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 知识体系总览

下面这张图把频率、分辨率、占空比精度三者的关系串起来了。你可以把它当作选型时的检查清单。

PWM频率与分辨率权衡知识体系 定时器时钟频率(如72MHz) 预分频值 + 自动重装载值 预分频值 + 自动重装载值 PWM频率 = f_clk / (PSC+1) / (ARR+1) 分辨率 = log₂(ARR+1) 位 占空比精度 = 1 / (ARR+1) × 100% 可调等级数 = ARR + 1 相互制约 取舍策略:按需求反推 → 提高时钟 → 动态切换 频率越高 → 分辨率越低 → 占空比精度越粗 分辨率越高 → 频率越低 → 可能引入人耳噪声或闪烁

4.5 避坑指南

最后分享几个我踩过的坑。

  • 别只看理论分辨率。实际占空比精度还受定时器计数器的抖动影响。有些低端MCU的定时器时钟本身就不准,算出来的分辨率再高也没用。
  • 注意预分频器的限制。不是所有预分频值都能用。有些芯片的预分频器只能设成2的幂次方,比如1、2、4、8……你算出来要设成3,结果硬件不支持。
  • 小心中断开销。频率越高,定时器中断越频繁。如果每个周期都要更新占空比,CPU可能被拖死。我做过一个项目,PWM频率设到100kHz,中断服务函数里就干了一件事——更新比较寄存器,结果CPU占用率直接飙到40%。

我的建议:选型阶段就列一个表格,把目标频率、目标分辨率、可用定时器时钟列出来,算一遍再动手。别等到画板子、写代码了才发现参数不匹配。那时候改,成本就高了。