#include "stm32f2xx.h"
/**
* @brief Configure the TIM3 Pins.
* @param None
* @retval None
*/
void TIM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//NVIC_InitTypeDef NVIC_InitStructure;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOB clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* TIM3 channel2 configuration : PB.05 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect TIM pin to AF2 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_TIM3);
/* Enable the TIM3 global Interrupt */
//NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
//NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//NVIC_Init(&NVIC_InitStructure);
}
/*setup TIM3 to PWM input to prepare for measure the AC frequency*/
void FREQ_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_ICInitTypeDef TIM_ICInitStructure;
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f2xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f2xx.c file
*/
TIM_DeInit(TIM3);
/* TIM Configuration */
TIM_Config();
/* Set the prescaler is 32*/
//TIM3-> SC = 31;
TIM_TimeBaseStructure.TIM_Period = 0xffff;
TIM_TimeBaseStructure.TIM_Prescaler = 31;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // Time base configuration
/* TIM4 configuration: PWM Input mode ------------------------
The external signal is connected to TIM3 CH2 pin (PB.05),
The Rising edge is used as active edge,
The TIM3 CCR2 is used to compute the frequency value
The TIM3 CCR1 is used to compute the duty cycle value
------------------------------------------------------------ */
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
//TIM_ICInit(TIM3, &TIM_ICInitStructure);
/* Select the TIM3 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);
/* Stop Capture */
//TIM3->CCER &= (uint16_t)~(TIM_CCER_CC2E | TIM_CCER_CC1E);
/* Enable the CC2 Interrupt Request */
// TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
}
uint32_t IC2Value = 0;
uint32_t IC3Value = 0;
//uint16_t DutyCycle = 0;
float Frequency = 0,i;
uint32_t freq;
/*To get AC Frequency*/
uint32_t Get_FREQ(void)
{//TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
TIM_ARRPreloadConfig(TIM3, DISABLE);
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
//IC2Value = 0;
//uint16_t DutyCycle = 0;
//Frequency = 0;
//TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
TIM3->CCER |= TIM_CCER_CC2E | TIM_CCER_CC1E;
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
TIM3->SR = 0;
/* Wait until end of the capture*/
while(TIM_GetFlagStatus(TIM3, TIM_IT_CC2) == RESET)
{};
/* Wait until end of the capture*/
//while(TIM_GetFlagStatus(TIM3, 0x1) == RESET)
//{};
/* Wait until end of the capture*/
//while(TIM_GetFlagStatus(TIM3, TIM_FLAG_CC2OF) == RESET)
//{};
/* Clear TIM3 Overcapture compare interrupt pending bit */
//TIM3->SR &= (uint16_t)~(TIM_FLAG_CC2OF);
/* Clear TIM3 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
/* Delay*/
for(i = 0;i<50000;i++);
/* Get the Input Capture value */
IC2Value = TIM_GetCapture2(TIM3);
IC3Value= TIM_GetCapture1(TIM3);
//IC2Value = 37500;
if (IC2Value != 0)
{
/* Duty cycle computation */
//DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;
/* Frequency computation
TIM4 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */
Frequency = (float)(RCC_Clocks.HCLK_Frequency)/2/32 / (float)IC2Value;
}
else
{
//DutyCycle = 0;
Frequency = 0;
}
/* Calibration of the measured value*/
Frequency += 0.5;
freq = (uint32_t)Frequency;
/* TIM enable counter */
TIM_Cmd(TIM3, DISABLE);
/* TIM input Disable */
TIM3->CCER &= (uint16_t)~(TIM_CCER_CC2E | TIM_CCER_CC1E);
return freq;
}
我用STM32F207测50ZH交流的频率,上面的代码是可以用的,而且很稳定!
但我在
while(TIM_GetFlagStatus(TIM3, TIM_FLAG_CC2OF) == RESET)
{};
后面插入了一个延时
/* Delay*/
for(i = 0;i<50000;i++);
再读CCR2的,这样读出来的频率才稳定!
但我不知道为什么必须要这个延时,如果去掉不行!
有朋友遇到过这样的问题吗?不知道有没有更好的解决办法!
不知道是不是芯片的BUG,大家多交流啊!
大侠帮帮忙,分析一下!
谢谢
|