4. PWM频率与分辨率权衡:频率计算公式、分辨率与占空比精度的关系、实际工程中的取舍策略
做PWM设计,你迟早会撞上一堵墙——想要高频,分辨率就不够;想要精细调节,频率又上不去。这不是芯片不行,而是硬件底层就存在一对天生的矛盾。
我早年做电机驱动时就被这个问题坑过。当时想用20kHz的PWM频率来避开人耳噪声,同时要求占空比调节精度达到0.1%。结果一算,定时器的时钟根本不够分。嗯,从那以后我每次选型都会先做这道算术题。
4.1 频率与分辨率的数学关系
先看公式。PWM的频率由定时器的计数周期决定:
PWM频率 = 定时器时钟频率 / (预分频值 + 1) / (自动重装载值 + 1)
而分辨率,说白了就是占空比能细分成多少级:
分辨率(位) = log₂(自动重装载值 + 1)
举个例子。定时器时钟是72MHz,预分频设为0,自动重装载值设为7199:
PWM频率 = 72MHz / 1 / 7200 = 10kHz
分辨率 = log₂(7200) ≈ 12.8位
这意味着占空比可以调节约7200个等级,精度大约是0.014%。听起来不错对吧?
但如果你把频率提到100kHz呢?
自动重装载值 = 72MHz / 1 / 100kHz - 1 = 719
分辨率 = log₂(720) ≈ 9.5位
只有720个等级了。精度掉到了0.14%。
核心矛盾:频率每提高一倍,分辨率就损失1位。这是由定时器计数器的有限位宽决定的,无法绕过。
4.2 分辨率与占空比精度的实际含义
很多人觉得“10位分辨率够用了,反正人眼看不出来”。但实际工程中,分辨率不足带来的问题很具体。
占空比精度 = 1 / (自动重装载值 + 1) × 100%
拿LED调光来说。8位分辨率(256级),从最暗到最亮只有256步。如果你要做呼吸灯效果,每一步的亮度跳变会很明显,尤其在低亮度区域。我做过一个项目,客户要求LED从0.1%亮度开始平滑上升,8位分辨率根本做不到——最低非零占空比就是0.39%,直接跳过去了。
| 分辨率(位) | 占空比等级数 | 最小占空比步进 | 典型应用场景 |
|---|---|---|---|
| 8 | 256 | 0.39% | 普通LED指示、风扇调速 |
| 10 | 1024 | 0.098% | 呼吸灯、电机粗调 |
| 12 | 4096 | 0.024% | 高显色指数照明、伺服电机 |
| 16 | 65536 | 0.0015% | 精密电源、音频D类功放 |
我的经验:电机控制至少需要10位分辨率,否则低速时转矩脉动会很明显。LED照明建议12位起步,不然调光曲线在低端会“断档”。
4.3 实际工程中的取舍策略
既然鱼和熊掌不能兼得,那怎么选?我总结了三条路。
策略一:按应用需求反推参数
先确定两个硬约束:
- 最低可接受频率——低于这个值,系统会出问题(比如电机噪声、LED闪烁)
- 最低可接受分辨率——低于这个值,控制精度不达标
然后反推定时器时钟和预分频值。举个例子:
需求:频率 ≥ 20kHz,分辨率 ≥ 12位
定时器时钟:72MHz
自动重装载值 ≥ 2¹² = 4096
最大频率 = 72MHz / 4096 ≈ 17.6kHz ❌ 不满足20kHz
怎么办?降低分辨率到11位:
自动重装载值 = 2048
频率 = 72MHz / 2048 ≈ 35.1kHz ✅
分辨率 = 11位 ✅
有时候就是得妥协。11位分辨率能不能接受?得看你的负载特性。
策略二:使用更高时钟频率的定时器
很多MCU有专门的“高级定时器”,挂载在更高的时钟总线上。比如STM32的TIM1和TIM8,时钟可以跑到144MHz甚至更高。
时钟144MHz,目标频率20kHz,目标分辨率12位:
自动重装载值 = 144MHz / 20kHz = 7200
分辨率 = log₂(7201) ≈ 12.8位 ✅ 同时满足
我建议你仔细看数据手册。有些MCU的定时器时钟可以独立配置,别被默认的APB时钟限制住。
注意:提高定时器时钟会增加功耗。电池供电的产品要权衡。我曾经为了追求16位分辨率把定时器时钟拉到最高,结果待机电流多了2mA,得不偿失。
策略三:硬件自动重装载 + 双缓冲
如果频率和分辨率都卡死了,还有一招——利用定时器的自动重装载和双缓冲特性,在运行时动态切换预分频值或重装载值。
但这招有风险。切换瞬间如果时序没处理好,会输出一个异常脉冲。我一般只在非关键场合用,比如系统初始化阶段。
4.4 知识体系总览
下面这张图把频率、分辨率、占空比精度三者的关系串起来了。你可以把它当作选型时的检查清单。
4.5 避坑指南
最后分享几个我踩过的坑。
- 别只看理论分辨率。实际占空比精度还受定时器计数器的抖动影响。有些低端MCU的定时器时钟本身就不准,算出来的分辨率再高也没用。
- 注意预分频器的限制。不是所有预分频值都能用。有些芯片的预分频器只能设成2的幂次方,比如1、2、4、8……你算出来要设成3,结果硬件不支持。
- 小心中断开销。频率越高,定时器中断越频繁。如果每个周期都要更新占空比,CPU可能被拖死。我做过一个项目,PWM频率设到100kHz,中断服务函数里就干了一件事——更新比较寄存器,结果CPU占用率直接飙到40%。
我的建议:选型阶段就列一个表格,把目标频率、目标分辨率、可用定时器时钟列出来,算一遍再动手。别等到画板子、写代码了才发现参数不匹配。那时候改,成本就高了。