4、PWM驱动开发:PWM定时器配置、输出极性设置、死区时间插入、互补输出配置
PWM 驱动,说白了就是让芯片输出一串宽度可调的脉冲。电机调速、LED 调光、开关电源,都离不开它。但真正要把 PWM 用好,尤其是驱动半桥、全桥这类功率电路,光会配个频率占空比可不够。
我个人习惯把 PWM 开发分成四步:定时器骨架搭好 → 极性定对 → 死区插准 → 互补输出收尾。下面咱们一个一个来拆。
4.1 PWM 定时器配置——先把架子搭起来
大部分 MCU 的 PWM 都是由通用定时器或高级定时器产生的。我最早用 STM32 的时候,以为配个 TIM 就是设几个寄存器,结果输出死活没波形。后来才发现,时基单元没配对,后面全白搭。
配置的核心就三个参数:
- 预分频器(PSC)——决定计数时钟频率
- 自动重装载值(ARR)——决定 PWM 周期
- 比较值(CCR)——决定占空比
公式很简单:
PWM 频率 = 定时器时钟 / ((PSC + 1) × (ARR + 1))
占空比 = CCR / (ARR + 1) × 100%
举个例子,我常用 72 MHz 主频,想要 20 kHz 的 PWM:
PSC = 71 → 计数时钟 = 72 MHz / 72 = 1 MHz
ARR = 49 → PWM 频率 = 1 MHz / 50 = 20 kHz
CCR = 25 → 占空比 = 25 / 50 = 50%
4.2 输出极性设置——正反逻辑别搞反
输出极性,就是决定高电平有效还是低电平有效。寄存器里通常叫 POLARITY 或 OCxP。
| 极性设置 | 有效电平 | 典型应用场景 |
|---|---|---|
| 高电平有效 | CCR 匹配时输出高 | 通用 PWM、LED 调光 |
| 低电平有效 | CCR 匹配时输出低 | 互补输出、负逻辑驱动 |
为什么会搞反?我记得有一次调试一个电机驱动板,PWM 波形看着没问题,电机就是反转。查了半天,原来是极性设反了,占空比越大转速反而越低。
4.3 死区时间插入——防止上下管直通
死区时间,是 PWM 驱动半桥/全桥电路时,上下两个开关管同时关断的那段间隔。没有死区,一个管还没关死,另一个就开了,瞬间短路。
我在项目中遇到过最惨的一次:死区设了 50 ns,觉得够了。结果 MOSFET 的关断延迟有 80 ns,上电瞬间直接冒烟。嗯,从那以后我学乖了。
死区时间怎么算?
死区时间 ≥ 关断延迟 + 开通延迟 + 安全裕量
一般建议:
- 低速 MOSFET(几百 kHz 以下):200 ns ~ 500 ns
- 高速 GaN/SiC(MHz 级):50 ns ~ 100 ns
- 安全裕量至少留 20%
配置时,高级定时器通常有专门的死区寄存器。以 STM32 为例:
TIM1->BDTR |= TIM_BDTR_DTG_0; // 死区时间 = 1 个计数时钟周期
// 如果计数时钟 = 1 MHz,死区 = 1 µs
4.4 互补输出配置——一对信号同时搞定
互补输出,就是同一个 PWM 信号,同时输出两路:一路原相,一路反相。专门用来驱动半桥的上下管。
配置要点:
- 使能互补通道——比如 TIM1_CH1 和 TIM1_CH1N
- 设置输出极性——主输出和互补输出可以独立设
- 插入死区——死区插入后,两路信号之间会自动产生间隔
- 使能主输出——高级定时器通常有个 MOE 位,忘了开就没波形
我见过不少新手,配完寄存器发现没输出,查了半天——MOE 位没置 1。说白了,高级定时器多了一层安全锁,你得主动解锁。
下面这张图,是我自己总结的 PWM 互补输出配置流程:
4.5 实战配置示例——以 STM32 TIM1 为例
下面给一个完整的配置片段,20 kHz PWM,死区 1 µs,互补输出:
// 1. 时基配置
TIM1->PSC = 71; // 72 MHz / 72 = 1 MHz
TIM1->ARR = 49; // 1 MHz / 50 = 20 kHz
// 2. 通道模式:PWM 模式 1
TIM1->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM 模式 1
TIM1->CCMR1 |= TIM_CCMR1_OC1PE; // 预装载使能
// 3. 输出极性:高电平有效
TIM1->CCER |= TIM_CCER_CC1E; // 主输出使能
TIM1->CCER |= TIM_CCER_CC1NE; // 互补输出使能
// 默认极性为高电平有效,不修改 CC1P/CC1NP
// 4. 死区时间:1 µs(计数时钟 1 MHz)
TIM1->BDTR |= 1; // DTG[7:0] = 1
// 5. 使能主输出
TIM1->BDTR |= TIM_BDTR_MOE;
// 6. 设置占空比 50%
TIM1->CCR1 = 25;
// 7. 启动定时器
TIM1->CR1 |= TIM_CR1_CEN;
4.6 常见问题与排查思路
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 无波形输出 | MOE 未使能 / 通道未使能 | 检查 BDTR 寄存器和 CCER 寄存器 |
| 频率不对 | PSC 或 ARR 算错 | 用公式反算,核对寄存器值 |
| 上下管同时导通 | 死区时间太小或极性配反 | 示波器看两路波形是否有重叠 |
| 电机抖动 | 死区时间过大 | 逐步减小死区,观察抖动消失点 |
嗯,PWM 驱动开发说难不难,说简单也不简单。核心就一句话:时基算准、极性设对、死区插够、互补使能。把这四步走稳了,大部分 PWM 应用都能搞定。