第三章:PWM波形反推——从占空比和频率,反推定时器的配置参数
各位好,欢迎来到第三章。
上一章我们聊了怎么从波形里读出频率和占空比。但说实话,那只是第一步。真正有意思的是——你拿到这两个数字之后,怎么反推出芯片里定时器是怎么配的?
这就像你看到一辆车的尾灯亮起频率,反推出司机踩刹车的力度。嗯,有点那个意思。
3.1 核心公式:定时器与PWM的关系
先别急着看代码,咱们把数学关系理清楚。
一个标准的PWM输出,背后站着三个关键参数:
- 预分频器(PSC):决定定时器时钟跑多快
- 自动重装值(ARR):决定PWM周期
- 比较值(CCR):决定占空比
它们之间的关系,说白了就两个公式:
PWM频率 = 定时器时钟频率 / ((PSC + 1) * (ARR + 1))
占空比 = CCR / (ARR + 1) (向上计数模式)
注意,这里有个 +1 的细节。我见过不少新手在这里翻车。定时器的寄存器是从0开始计数的,所以实际计数值要加1。你想想看,ARR设为99,实际计数是0到99,一共100个时钟周期。
关键点:ARR + 1 才是真正的周期计数值。CCR 是计数值,不是百分比。
3.2 反推第一步:从频率反推(PSC+1)*(ARR+1)
好,假设你从示波器上读到了一个PWM波形:
- 频率:1kHz
- 占空比:25%
你的MCU定时器时钟是72MHz。那么第一步,我们算一下总的分频系数:
总系数 = 72MHz / 1kHz = 72000
这个72000就是 (PSC+1) * (ARR+1) 的乘积。
到这里,你可能会问:那PSC和ARR到底怎么分?
嗯,这就是反推的难点所在。同一个乘积,可以有无数种拆分方式。比如:
- PSC=71, ARR=999 → (72)*(1000)=72000
- PSC=719, ARR=99 → (720)*(100)=72000
- PSC=7199, ARR=9 → (7200)*(10)=72000
哪个才是对的?
我的经验:我个人习惯先看占空比的分辨率。占空比25%,如果ARR=9,那CCR只能是2.25?不可能,寄存器不能存小数。所以ARR不能太小。
3.3 反推第二步:从占空比反推CCR和ARR
占空比25%,意味着 CCR / (ARR+1) = 0.25。
也就是 CCR = (ARR+1) * 0.25。
CCR必须是整数。所以 (ARR+1) 必须是4的倍数。
我们回头看刚才那三种拆分:
- ARR=999 → ARR+1=1000,是4的倍数 → CCR=250 ✅
- ARR=99 → ARR+1=100,是4的倍数 → CCR=25 ✅
- ARR=9 → ARR+1=10,不是4的倍数 → CCR=2.5 ❌
所以第三种直接排除。
那前两种怎么选?
实际项目中:我曾经遇到过一个问题——电机控制要求PWM频率1kHz,占空比分辨率要0.1%。ARR=99时,分辨率只有1%,不够用。最后选了ARR=999的方案。
一般来说,ARR越大,占空比调节越精细。但ARR太大,定时器中断频率会降低,实时性受影响。这是个权衡。
3.4 常见定时器模式对反推的影响
刚才我们假设的是向上计数模式。但实际中还有:
- 向下计数模式:公式一样,但CCR含义略有不同
- 中央对齐模式:频率公式要除以2,因为一个周期内计数走了两趟
举个例子,中央对齐模式下:
PWM频率 = 定时器时钟频率 / (2 * (PSC+1) * (ARR+1))
如果你用向上计数的公式去套中央对齐的波形,算出来的PSC和ARR会差一倍。我刚开始做STM32的时候就在这栽过跟头。
注意:反推之前,先确认定时器的工作模式。看波形是对称的还是不对称的?对称的波形大概率是中央对齐模式。
3.5 实战案例:一个完整的反推过程
好,咱们来走一遍完整的流程。
已知条件:
- 定时器时钟:72MHz
- 波形频率:50Hz
- 占空比:7.5%
- 波形不对称(上升沿快,下降沿慢)→ 向上计数模式
第一步:算总系数
总系数 = 72,000,000 / 50 = 1,440,000
第二步:拆分PSC和ARR
占空比7.5% = 3/40。所以ARR+1最好是40的倍数。
我试了几个组合:
| PSC | ARR | ARR+1 | CCR | 是否合理 |
|---|---|---|---|---|
| 1439 | 999 | 1000 | 75 | ✅ 常用 |
| 7199 | 199 | 200 | 15 | ✅ 分辨率低 |
| 2879 | 499 | 500 | 37.5 | ❌ 非整数 |
我个人会选择PSC=1439, ARR=999, CCR=75。为什么?因为ARR=999是很多MCU的默认值,而且分辨率够用。
第三步:验证
频率 = 72M / (1440 * 1000) = 50Hz ✅
占空比 = 75 / 1000 = 7.5% ✅
一个小技巧:如果你不确定PSC和ARR的分配,可以看看波形有没有抖动。PSC太大(比如超过65535),定时器时钟太慢,波形容易受噪声影响。我遇到过几次这种情况,后来都尽量让PSC小一些。
3.6 避坑指南
最后,分享几个我踩过的坑:
- 坑一:忘了 +1。ARR=999时,实际周期是1000。算CCR时用999做分母,结果全错。
- 坑二:没考虑死区时间。有些PWM波形(比如H桥驱动)会在上升沿和下降沿之间插入死区。这时候占空比看起来会偏小。
- 坑三:误把脉冲宽度当成占空比。有人看到高电平时间1ms,周期10ms,直接说占空比10%。但如果波形是负逻辑呢?高电平反而是关断信号。
我曾经在一个电机驱动项目里,因为没注意死区时间,反推出来的CCR总是差那么几个数。折腾了两天才发现,原来是硬件自动插入了死区。从那以后,我拿到波形第一件事就是看上升沿和下降沿之间有没有间隙。
好了,这一章的内容就到这里。下一章我们会聊怎么把这些反推出来的参数,写成实际的寄存器配置代码。到时候我会拿STM32和GD32的库函数做例子,手把手教你怎么配。
记住:波形会说话,关键是你得听得懂。