当前位置: 首页 > news >正文

基于 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、初始化代码

#include"stm32f1xx_hal.h"TIM_HandleTypeDef htim2;volatileuint32_tcapture1=0,capture2=0;volatileuint8_tcapture_flag=0;volatileuint16_toverflow_count=0;voidTIM2_Init(void){TIM_ClockConfigTypeDef sClockSourceConfig={0};TIM_MasterConfigTypeDef sMasterConfig={0};TIM_IC_InitTypeDef sConfigIC={0};htim2.Instance=TIM2;htim2.Init.Prescaler=72-1;// 72MHz/72 = 1MHzhtim2.Init.CounterMode=TIM_COUNTERMODE_UP;htim2.Init.Period=0xFFFFFFFF;htim2.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;HAL_TIM_IC_Init(&htim2);sClockSourceConfig.ClockSource=TIM_CLOCKSOURCE_INTERNAL;HAL_TIM_ConfigClockSource(&htim2,&sClockSourceConfig);sConfigIC.ICPolarity=TIM_INPUTCHANNELPOLARITY_RISING;sConfigIC.ICSelection=TIM_ICSELECTION_DIRECTTI;sConfigIC.ICPrescaler=TIM_ICPSC_DIV1;sConfigIC.ICFilter=0;HAL_TIM_IC_ConfigChannel(&htim2,&sConfigIC,TIM_CHANNEL_1);sMasterConfig.MasterOutputTrigger=TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode=TIM_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->Channel==HAL_TIM_ACTIVE_CHANNEL_1){if(capture_flag==0){capture1=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);capture_flag=1;}else{capture2=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);// 计算周期(考虑溢出)uint32_tperiod_ticks=0;if(capture2>=capture1){period_ticks=capture2-capture1;}else{period_ticks=0xFFFFFFFF-capture1+capture2;}// 计算频率meter.frequency=1000000/period_ticks;// 1MHz 时钟capture_flag=0;overflow_count=0;}}}voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim){if(htim->Instance==TIM2){overflow_count++;}}

六、测频法实现(TIM3 外部计数)

1、初始化代码

TIM_HandleTypeDef htim3;volatileuint32_tcount_value=0;voidTIM3_Init(void){TIM_SlaveConfigTypeDef sSlaveConfig={0};TIM_MasterConfigTypeDef sMasterConfig={0};htim3.Instance=TIM3;htim3.Init.Prescaler=0;htim3.Init.CounterMode=TIM_COUNTERMODE_UP;htim3.Init.Period=0xFFFF;htim3.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;HAL_TIM_Base_Init(&htim3);sSlaveConfig.SlaveMode=TIM_SLAVEMODE_EXTERNAL1;sSlaveConfig.InputTrigger=TIM_TS_ETRF;sSlaveConfig.TriggerPolarity=TIM_INPUTCHANNELPOLARITY_RISING;sSlaveConfig.TriggerFilter=0;HAL_TIM_SlaveConfigSynchro(&htim3,&sSlaveConfig);sMasterConfig.MasterOutputTrigger=TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(&htim3,&sMasterConfig);}

2、定时测量(1秒闸门)

voidMeasure_Frequency(void){staticuint32_tlast_count=0;uint32_tcurrent_count=__HAL_TIM_GET_COUNTER(&htim3);// 1秒定时中断触发meter.frequency=current_count-last_count;last_count=current_count;}

七、自动量程切换逻辑

voidAuto_Range_Switch(void){staticuint32_tlast_freq=0;staticuint8_tstable_count=0;if(meter.frequency>100000){// >100KHzmeter.mode=1;// 测频法}else{meter.mode=0;// 测周法}// 防抖动if(abs(meter.frequency-last_freq)<10){stable_count++;if(stable_count>5){stable_count=0;last_freq=meter.frequency;}}else{stable_count=0;}}

八、占空比测量(双沿捕获)

floatMeasure_Duty_Cycle(void){uint32_thigh_time,low_time,period;// 配置上升沿和下降沿捕获// ... 初始化代码// 计算占空比period=high_time+low_time;if(period>0){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_tavg=0;for(inti=0;i<100;i++){avg+=Read_ADC();}zero_offset=avg/100;}

十一、测量范围与精度

频段方法分辨率
1Hz - 100Hz测周法0.1Hz
100Hz - 10KHz测周法1Hz
10KHz - 100KHz测周法10Hz
100KHz - 1MHz测频法100Hz
1MHz - 10MHz测频法1KHz

最高精度:0.1Hz @ 1Hz
最大误差:< 0.1%

http://www.rkmt.cn/news/1295872.html

相关文章:

  • UltimateStack终极堆叠模组:打破Minecraft物品限制的完整指南
  • Node.js 服务端项目接入 Taotoken 多模型 API 的完整步骤
  • 2026龙湾口腔排行榜:这几家实力口碑双优 - 速递信息
  • 土地供应格局锁定板块稀缺性,从源头决定广州楼市长期供求与全预算置业方向 - 速递信息
  • Linux压缩解压实战指南:从tar/gzip到xz/zip的全面解析
  • Steam创意工坊模组下载解决方案:WorkshopDL跨平台模组管理工具
  • SSH远程连接服务器
  • p5.js Web Editor 渐进式TypeScript迁移:从11万行JavaScript到类型安全架构的工程实践
  • c++ 端口扫描程序实现案例
  • 国内卫浴十大品牌华艺卫浴 绿色科技引领健康卫浴新生态 - 速递信息
  • 基于RT-Thread Studio搭建瑞萨RA6M4开发环境全攻略
  • 计算机提示词长度控制:指定AI回答字数与详略
  • 2026年5月钢格栅厂家领军榜!五大标杆实力解码助力一站式选型采购 - 速递信息
  • 149.PyTorch+YOLOv8 实战|口罩检测全流程,含模型评估与 ONNX 导出
  • 基于发布订阅模式的Web实时通信框架hermes-for-web实践指南
  • mysql如何配置MySQL的连接保持_调整tcp_keepalive设置
  • 【NotebookLM+Stata+LaTeX三端协同】:经济学论文写作效率提升300%的私密工作流(附MIT经济系内部配置清单)
  • 华南师范大学校园网自动登录脚本逆向分析:从F12抓包到Python requests模拟POST请求全解析
  • 质量工具怎么快速学会? - 众智商学院职业教育
  • Mysql:索引与B+树
  • Noto Emoji字体终极指南:5步解决跨平台表情符号乱码问题
  • OpenAI关闭微调API,AI副业者的机会来了!
  • 闻达AI助手:本地化大语言模型平台的架构设计与应用实践
  • 终极免费音频编辑解决方案:告别昂贵软件,用Audacity实现专业级音频处理
  • Cadence 17.4出Gerber给嘉立创,解析失败?试试手动清理这个钻孔文件
  • 上海/北京/深圳 | Build with AI: 直击 Next 26,构建智能未来
  • 高效地下水模拟完全指南:使用Python和FloPy进行专业水文建模
  • 从Windows效率困境到指尖革命:Flow Launcher的智能工作流重塑指南
  • 湖北综合格斗俱乐部推荐:从“野蛮生长”到“专业进化”,你选对了吗? - 速递信息
  • 如何在PC上运行Switch游戏:Ryujinx开源模拟器的完整配置指南