基于 STM32 定时器输入捕获功能的数字频率计方案
一、测量原理与方案选择两种经典方法方法优点缺点适用频段测周法低频精度高高频误差大1Hz - 100KHz测频法高频精度高需要定时闸门100KHz - 10MHz推荐方案测周法 测频法自动切换二、硬件连接信号STM32 引脚注意被测信号PA0 (TIM2_CH1)可接 3.3V 输入分压电阻1kΩ 9kΩ保护输入整形电路施密特触发器可选输入保护必须加1kΩ 串联电阻 3.3V 钳位二极管三、STM32 定时器配置1、TIM2测周法 - 捕获模式通道CH1模式Input Capture触发上升沿分频72-1 → 计数频率 1MHz中断捕获中断 溢出中断2、TIM3测频法 - 外部计数模式通道ETR模式External Clock Mode 1触发上升沿分频1-1中断更新中断四、核心数据结构typedefstruct{uint32_tfrequency;// 最终频率uint8_tmode;// 0测周 1测频floatduty;// 占空比}FreqMeter_t;FreqMeter_t meter{0};五、测周法实现TIM2 捕获1、初始化代码#includestm32f1xx_hal.hTIM_HandleTypeDef htim2;volatileuint32_tcapture10,capture20;volatileuint8_tcapture_flag0;volatileuint16_toverflow_count0;voidTIM2_Init(void){TIM_ClockConfigTypeDef sClockSourceConfig{0};TIM_MasterConfigTypeDef sMasterConfig{0};TIM_IC_InitTypeDef sConfigIC{0};htim2.InstanceTIM2;htim2.Init.Prescaler72-1;// 72MHz/72 1MHzhtim2.Init.CounterModeTIM_COUNTERMODE_UP;htim2.Init.Period0xFFFFFFFF;htim2.Init.ClockDivisionTIM_CLOCKDIVISION_DIV1;HAL_TIM_IC_Init(htim2);sClockSourceConfig.ClockSourceTIM_CLOCKSOURCE_INTERNAL;HAL_TIM_ConfigClockSource(htim2,sClockSourceConfig);sConfigIC.ICPolarityTIM_INPUTCHANNELPOLARITY_RISING;sConfigIC.ICSelectionTIM_ICSELECTION_DIRECTTI;sConfigIC.ICPrescalerTIM_ICPSC_DIV1;sConfigIC.ICFilter0;HAL_TIM_IC_ConfigChannel(htim2,sConfigIC,TIM_CHANNEL_1);sMasterConfig.MasterOutputTriggerTIM_TRGO_RESET;sMasterConfig.MasterSlaveModeTIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(htim2,sMasterConfig);HAL_TIM_IC_Start_IT(htim2,TIM_CHANNEL_1);HAL_TIM_Base_Start_IT(htim2);}2、中断处理核心voidHAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef*htim){if(htim-ChannelHAL_TIM_ACTIVE_CHANNEL_1){if(capture_flag0){capture1HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);capture_flag1;}else{capture2HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);// 计算周期考虑溢出uint32_tperiod_ticks0;if(capture2capture1){period_tickscapture2-capture1;}else{period_ticks0xFFFFFFFF-capture1capture2;}// 计算频率meter.frequency1000000/period_ticks;// 1MHz 时钟capture_flag0;overflow_count0;}}}voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim){if(htim-InstanceTIM2){overflow_count;}}六、测频法实现TIM3 外部计数1、初始化代码TIM_HandleTypeDef htim3;volatileuint32_tcount_value0;voidTIM3_Init(void){TIM_SlaveConfigTypeDef sSlaveConfig{0};TIM_MasterConfigTypeDef sMasterConfig{0};htim3.InstanceTIM3;htim3.Init.Prescaler0;htim3.Init.CounterModeTIM_COUNTERMODE_UP;htim3.Init.Period0xFFFF;htim3.Init.ClockDivisionTIM_CLOCKDIVISION_DIV1;HAL_TIM_Base_Init(htim3);sSlaveConfig.SlaveModeTIM_SLAVEMODE_EXTERNAL1;sSlaveConfig.InputTriggerTIM_TS_ETRF;sSlaveConfig.TriggerPolarityTIM_INPUTCHANNELPOLARITY_RISING;sSlaveConfig.TriggerFilter0;HAL_TIM_SlaveConfigSynchro(htim3,sSlaveConfig);sMasterConfig.MasterOutputTriggerTIM_TRGO_RESET;sMasterConfig.MasterSlaveModeTIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(htim3,sMasterConfig);}2、定时测量1秒闸门voidMeasure_Frequency(void){staticuint32_tlast_count0;uint32_tcurrent_count__HAL_TIM_GET_COUNTER(htim3);// 1秒定时中断触发meter.frequencycurrent_count-last_count;last_countcurrent_count;}七、自动量程切换逻辑voidAuto_Range_Switch(void){staticuint32_tlast_freq0;staticuint8_tstable_count0;if(meter.frequency100000){// 100KHzmeter.mode1;// 测频法}else{meter.mode0;// 测周法}// 防抖动if(abs(meter.frequency-last_freq)10){stable_count;if(stable_count5){stable_count0;last_freqmeter.frequency;}}else{stable_count0;}}八、占空比测量双沿捕获floatMeasure_Duty_Cycle(void){uint32_thigh_time,low_time,period;// 配置上升沿和下降沿捕获// ... 初始化代码// 计算占空比periodhigh_timelow_time;if(period0){meter.duty(float)high_time/period*100.0f;}returnmeter.duty;}九、主函数示例intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_TIM2_Init();MX_TIM3_Init();HAL_TIM_IC_Start_IT(htim2,TIM_CHANNEL_1);HAL_TIM_Base_Start_IT(htim2);HAL_TIM_Base_Start_IT(htim3);while(1){Auto_Range_Switch();printf(频率: %lu Hz, 模式: %s, 占空比: %.1f%%\r\n,meter.frequency,meter.mode?测频:测周,meter.duty);HAL_Delay(500);}}参考代码 数字频率计基于stm32的中断捕获模式对输入信号进行计数www.youwenfan.com/contentcsu/69881.html十、性能优化1、多周期同步平均#defineAVG_COUNT10uint32_tfreq_buffer[AVG_COUNT];2、输入信号调理施密特触发器自动增益控制带通滤波器3、自动校零voidAuto_Zero_Calibration(void){uint32_tavg0;for(inti0;i100;i){avgRead_ADC();}zero_offsetavg/100;}十一、测量范围与精度频段方法分辨率1Hz - 100Hz测周法0.1Hz100Hz - 10KHz测周法1Hz10KHz - 100KHz测周法10Hz100KHz - 1MHz测频法100Hz1MHz - 10MHz测频法1KHz最高精度0.1Hz 1Hz最大误差 0.1%