1. 为什么选择STM32做频率计?
做电子测量的人都知道,频率计是最基础也最常用的仪器之一。去年我在调试一个射频模块时,发现手头的商用频率计体积大、价格贵,而且很多高级功能其实根本用不上。当时就萌生了自己做便携式频率计的想法,而STM32系列单片机自然成为首选。
STM32F103C8T6这颗芯片特别适合做频率测量,原因有三:首先它自带多达11个定时器,其中TIM1/TIM8是高级定时器,特别适合做精确计时;其次72MHz的主频配合硬件捕获功能,测量精度轻松达到0.1Hz级别;最重要的是它的DMA控制器可以直接把捕获数据搬运到内存,不占用CPU资源。我实测下来,用输入捕获模式测量1MHz信号时,CPU占用率不到5%。
2. 硬件设计关键点
2.1 信号调理电路设计
被测信号可能来自各种场景:可能是MCU的PWM输出(3.3V电平),也可能是函数发生器的10Vpp正弦波,甚至可能是带直流偏置的信号。这就需要前端调理电路来处理:
- 过压保护:用1N4148二极管做钳位,防止高压损坏IO口
- 电平转换:LM393比较器将任意信号转为3.3V方波
- 滤波处理:100pF电容并联10k电阻组成低通滤波,抑制高频噪声
特别注意:STM32的IO口最高耐受5V电压,但长期工作在极限参数下会影响寿命。我的经验是,超过3.6V的信号一定要先分压再输入。
2.2 PCB布局要点
高频测量最怕干扰,布线时要注意:
- 信号输入走线尽量短,必要时做50Ω阻抗匹配
- 模拟地和数字地用0Ω电阻单点连接
- 晶振电路远离信号输入通道
- 电源引脚务必加0.1μF去耦电容
有个坑我踩过:一开始没注意电源滤波,测量100kHz以上信号时读数跳变严重。后来在每路电源入口加了LC滤波(10μH+100nF),问题立刻解决。
3. 软件实现核心逻辑
3.1 定时器配置技巧
使用TIM2做输入捕获时,关键配置如下:
c复制TIM_ICInitTypeDef ic;
ic.TIM_Channel = TIM_Channel_1;
ic.TIM_ICPolarity = TIM_ICPolarity_Rising; // 捕获上升沿
ic.TIM_ICSelection = TIM_ICSelection_DirectTI;
ic.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 不分频
ic.TIM_ICFilter = 0x0; // 不滤波
TIM_ICInit(TIM2, &ic);
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1); // 触发源选择
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);// 从模式配置
这里有个细节:TIM_ICFilter参数如果设置过大,虽然能滤除毛刺,但会导致脉冲丢失。我的经验值是:对于1MHz以下信号设为0,1-10MHz设6,更高频率需要硬件滤波。
3.2 频率计算算法
测量原理很简单:在固定闸门时间内统计脉冲个数。但实际编码时有几个优化点:
- 使用DMA+定时器溢出中断组合,避免丢失高频信号
- 采用滑动窗口算法,每10ms更新一次显示
- 对低频信号(<1kHz)改用周期测量法提高精度
核心计算公式:
c复制// 高频模式(N为捕获到的脉冲数)
freq = N / (gate_time * TIM_CLK);
// 低频模式(T为测得周期)
freq = 1.0 / (T * TIM_CLK / TIM_Prescaler);
实测发现,当信号占空比异常时(比如10%),普通测量方式误差会变大。后来我改进为双边沿触发测量,精度提升了5倍。
4. 性能优化实战经验
4.1 提高测量上限的技巧
STM32的理论测量上限是主频的一半(36MHz),但实际做到20MHz以上就需要技巧:
- 启用定时器的预分频器,降低计数频率
- 使用两个定时器级联,一个测高频一个测低频
- 对信号进行64分频后再测量(需硬件支持)
有个取巧的方法:用外部高速比较器(如MAX9017)先把信号分频,再用STM32测量。这样成本增加不到10元,但测量范围可以扩展到100MHz。
4.2 抗干扰处理方案
工业现场电磁环境复杂,这些措施很有效:
- 在软件中实现数字滤波(去掉突变值)
- 设置合理的信号幅值阈值
- 增加测量次数取平均值
- 对异常值进行中值滤波
最让我意外的是:显示刷新率也会影响测量稳定性。当我把LCD刷新从60Hz降到30Hz后,高频测量波动明显减小。后来发现是SPI总线干扰导致的。
5. 成品实测数据对比
用自制的STM32频率计与普源DS1052Z示波器对比测试:
| 信号频率 | 示波器读数 | STM32读数 | 误差 |
|---|---|---|---|
| 1kHz | 1000.0Hz | 999.8Hz | 0.02% |
| 1MHz | 1.00000MHz | 0.99992MHz | 0.008% |
| 10MHz | 10.0000MHz | 9.9967MHz | 0.033% |
| 50MHz* | 50.000MHz | 49.87MHz | 0.26% |
(*使用分频器测量)
这个精度对于大多数业余应用已经完全够用。整套BOM成本不到50元,体积只有烟盒大小,而且功耗极低(待机电流<10mA)。
