当前位置: 首页 > 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.jsqmd.com/news/829951/

相关文章:

  • Agent Harness 的 Session Tree View:让每一个 Agent 做自己擅长的事情!
  • 别只盯着SIGGRAPH了:聊聊图形学那些被低估的宝藏期刊(CGF/CAGD实战经验)
  • 产业能级划定板块价值上限,供求结构直接决定片区流通性与长期保值能力 - 速递信息
  • UltimateStack终极堆叠模组:打破Minecraft物品限制的完整指南
  • 400M apk 20G能刷多少下载
  • Qt程序打包后双击报错0xc000007b?手把手教你用windeployqt正确部署依赖(32/64位环境详解)
  • Harmony与SCTransform协同优化:Seurat单细胞整合分析实战指南
  • 甄选靠谱多模型聚合平台优质厂家,助力企业AI高效落地
  • NotebookLM地质知识图谱构建实战:从10万页纸质区调报告中自动提取断层参数、岩体侵入期次与蚀变分带信息
  • 浏览器本地文档阅读革命:markdownReader如何重新定义技术文档体验
  • 土地供应格局锁定板块稀缺性,从源头决定广州楼市长期供求与全预算置业方向 - 速递信息
  • 2026龙湾口腔排行榜:这几家实力口碑双优 - 速递信息
  • p5.js Web Editor 渐进式TypeScript迁移:从11万行JavaScript到类型安全架构的工程实践
  • 树莓派首次启动配置全攻略:raspi-config工具详解与核心设置
  • 为什么你的快捷键突然失灵了?用Hotkey Detective找出Windows系统中的热键冲突元凶
  • 暗黑破坏神2存档修改器终极指南:免费打造完美角色
  • 终极指南:如何用Onekey在3分钟内搞定Steam游戏清单下载
  • 国内卫浴十大品牌华艺卫浴 绿色科技引领健康卫浴新生态 - 速递信息
  • 基于RT-Thread Studio搭建瑞萨RA6M4开发环境全攻略
  • GuardClaw OpenClaw插件:自动化子域名资产与Nuclei漏洞扫描的智能调度策略
  • Zeroconf零配置网络实战:mDNS与Avahi跨平台配置指南
  • 桌面Python复用CircuitPython蓝牙生态:Adafruit Blinka bleio实战指南
  • 2026年5月钢格栅厂家领军榜!五大标杆实力解码助力一站式选型采购 - 速递信息
  • ZEMAX热分析实战:从“空气边缘厚度”到“镜片带台”的避坑指南
  • 基于RT-Thread的智能指纹锁:从架构设计到低功耗与安全实现
  • Uber数据库迁移深度解析:从PostgreSQL到MySQL的架构演进实战
  • 质量工具怎么快速学会? - 众智商学院职业教育
  • AI专著生成大揭秘!实用AI工具推荐,高效完成20万字专著撰写
  • OpenClaw实战:用Python构建SEO/AEO自动化工具链
  • 从Cortex-M4的寄存器设计,聊聊nRF52832程序为啥跑得稳(附Keil5查看技巧)