單片機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;

}

}

}


還有一種方法就是用外部中斷計算頻率。更精確的計算方法得慢慢研究。


分享到:


相關文章: