单片机STM32采用定时器捕获的方式测量频率

STM32采用定时器捕获的方法测低频信号很准确,我测高频100K-120K就误差太大了,大概200Hz,这儿的误差是个范围,不是某个值。有的人说两个定时器一个定时,一个计数,这样太浪费资源了吧。STM32定时器分为高级定时器(TIM1、TIM8)、通用定时器(TIM2、 TIM3、 TIM4和TIM5)及基本定时器(TIM6和TIM7)。本文用定时器捕获的方法,用的是通用定时器3通道2来实现测量频率。如下是通用定时器框图:


单片机STM32采用定时器捕获的方式测量频率


下面示例是用捕获的方法计算频率,列举几个主要函数配置讲一下:

void Time3_Configuration()

{

TIM_ICInitTypeDef TIM_ICInitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

//RCC_ClocksTypeDef freq;

//RCC_GetClocksFreq(&freq);

/*TIM3时基*/

TIM_DeInit(TIM3);

TIM_TimeBaseStructure.TIM_Period = 0xffff;

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // Time base configuration

/*TIM3输入捕获*/

TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

TIM_ICInitStructure.TIM_ICPolarity = TIM_CounterMode_Up;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; /*输入预分频*/

TIM_ICInitStructure.TIM_ICFilter = 0;


TIM_ICInit(TIM3, &TIM_ICInitStructure);


TIM_PWMIConfig(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);


/* Enable the Master/Slave Mode */

TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);


/* TIM enable counter */

TIM_Cmd(TIM3, ENABLE);


/* Enable the CC2 Interrupt Request */

TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);

}

中断部分计算频率:

void TIM3_IRQHandler(void)

{

if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET)

{

/* Clear TIM5 Capture compare interrupt pending bit */

TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

if(capture_number == 0)

{

/* Get the Input Capture value */

ic3_readvalue3 = TIM_GetCapture(TIM3);

capture_number = 1;

}

else if(capture_number == 1)

{

/* Get the Input Capture value */

ic3_readvalue4 = TIM_GetCapture(TIM3);


/* Capture computation */

if (ic3_readvalue4 > ic3_readvalue3)

{

CAPTURE = ic3_readvalue4 ;

}


/* Frequency computation */

Frequency = (u32)72000000 / CAPTURE;

capture_number = 0;

}

else

{

Frequency=0;

}

}

}


还有一种方法就是用外部中断计算频率。更精确的计算方法得慢慢研究。


分享到:


相關文章: