4、PWM生成与配置:ePWM模块详解、PWM频率与死区设置、互补PWM输出
各位,咱们直接切入正题。做数字电源,PWM 就是你的“手”,去控制功率管的开关。ePWM 模块玩不转,后面所有闭环控制都是空中楼阁。这一章,我把 C2000 系列里 ePWM 的核心配置掰开揉碎了讲,重点就是频率怎么算、死区怎么设、互补输出怎么搭。
核心要点:ePWM 模块的本质是一个带时基、比较器、动作限定器和死区插入器的数字波形发生器。你给它一个周期值和一个比较值,它就能吐出精确的 PWM 波。
4.1 ePWM 模块架构速览
先看整体结构,心里有个地图。一个 ePWM 模块通常包含以下几个子模块:
- 时基模块 (TB):决定 PWM 的周期和计数模式。说白了就是时钟源和计数器。
- 比较模块 (CC):设定占空比。计数器值和比较值相等时,触发事件。
- 动作限定模块 (AQ):根据事件(比如计数等于零、等于周期、等于比较值)来决定输出是高电平还是低电平。
- 死区模块 (DB):插入死区时间,防止上下管直通。这是同步整流的关键。
- 事件触发模块 (ET):产生中断或启动 ADC 转换的时机。
我个人习惯,拿到一个新项目,第一步就是先把时基和动作限定配好,让 PWM 能正常输出波形,然后再去调死区和触发。
4.2 PWM 频率计算:时基配置
频率怎么算?公式很简单:
PWM频率 = 系统时钟频率 / (分频系数 × 周期寄存器值)
举个例子,系统时钟 100 MHz,你想跑 100 kHz 的开关频率。分频系数设为 1,那么周期寄存器值就是 1000。计数器从 0 数到 999,然后归零,一个周期结束。
这里有个坑,我踩过。周期寄存器是 16 位的,最大值 65535。如果你想要很低的频率,比如 1 kHz,分频系数就得设大一点。否则周期值会溢出。
| 系统时钟 (MHz) | 目标频率 (kHz) | 分频系数 | 周期寄存器值 |
|---|---|---|---|
| 100 | 100 | 1 | 1000 |
| 100 | 50 | 1 | 2000 |
| 100 | 10 | 10 | 1000 |
| 100 | 1 | 100 | 1000 |
小技巧:我一般先确定分频系数,让周期寄存器值落在 500 到 5000 之间。这样占空比调节的精度和动态响应都能兼顾。太小的周期值,占空比步进太大;太大的周期值,计数器翻转慢,响应迟钝。
4.3 占空比与比较值
占空比由比较寄存器 CMPA 或 CMPB 决定。在递增计数模式下:
占空比 = CMPA / 周期寄存器值
比如周期是 1000,CMPA 设为 300,占空比就是 30%。
嗯,这里要注意。CMPA 的值不能大于周期值,否则输出会一直为高或一直为低,那就失控了。我在调试一个 LLC 电源时,就因为软件里一个边界条件没处理好,CMPA 偶尔超过了周期值,结果管子直接烧了。从那以后,我每次更新占空比都会加一个饱和限幅。
4.4 死区设置:同步整流的安全带
死区是同步整流里绝对不能省的东西。上下管切换时,如果同时导通,电源和地直接短路,电流瞬间飙升。
死区模块的工作原理很简单:对上升沿和下降沿分别插入延迟。
- 上升沿延迟 (RED):输出从低变高时,延迟一段时间再变高。
- 下降沿延迟 (FED):输出从高变低时,延迟一段时间再变低。
配置死区时,通常用“上升沿延迟 + 下降沿延迟”模式,让两路 PWM 之间产生一个“都关断”的空档。
// 死区配置示例
EPwm1Regs.DBCTL.bit.OUT_MODE = 0x3; // 使能上升沿和下降沿延迟
EPwm1Regs.DBCTL.bit.POLSEL = 0x2; // 上升沿延迟作用于 PWMxA,下降沿延迟作用于 PWMxB
EPwm1Regs.DBRED.bit.DBRED = 50; // 上升沿延迟 50 个时钟周期
EPwm1Regs.DBFED.bit.DBFED = 50; // 下降沿延迟 50 个时钟周期
死区时间怎么算?
死区时间 = 延迟值 × 时钟周期
如果系统时钟 100 MHz,分频系数 1,时钟周期就是 10 ns。延迟值 50,死区时间就是 500 ns。
警告:死区时间不是越大越好。太大会导致占空比丢失,影响效率。太小又可能无法覆盖开关管的关断延迟。我一般先看 MOSFET 数据手册里的关断延迟时间,然后在此基础上加 20%~30% 的余量。比如关断延迟 200 ns,我就设 250~300 ns 的死区。
4.5 互补 PWM 输出
互补输出,就是两路 PWM 波形相位相反,中间插入死区。这是半桥、全桥、同步 Buck 等拓扑的标准配置。
配置步骤其实就三步:
- 配置动作限定:让 ePWMxA 和 ePWMxB 各自独立输出。
- 使能死区模块:选择“上升沿延迟 + 下降沿延迟”模式。
- 设置极性:通常 ePWMxA 是高有效,ePWMxB 是低有效,这样死区模块会自动生成互补波形。
// 互补 PWM 输出配置示例
// 1. 动作限定:PWMxA 在计数等于零时置高,等于 CMPA 时置低
EPwm1Regs.AQCTLA.bit.ZRO = 0x2; // 置高
EPwm1Regs.AQCTLA.bit.CAU = 0x1; // 置低
// 2. 动作限定:PWMxB 在计数等于零时置低,等于 CMPA 时置高
EPwm1Regs.AQCTLB.bit.ZRO = 0x1; // 置低
EPwm1Regs.AQCTLB.bit.CAU = 0x2; // 置高
// 3. 死区配置
EPwm1Regs.DBCTL.bit.OUT_MODE = 0x3;
EPwm1Regs.DBCTL.bit.POLSEL = 0x2;
EPwm1Regs.DBRED.bit.DBRED = 50;
EPwm1Regs.DBFED.bit.DBFED = 50;
我曾经在一个项目中,因为极性设置反了,导致上下管同时导通,炸了一个驱动芯片。排查了半天才发现是 POLSEL 位写错了。所以,配置完一定要用示波器看波形,确认死区存在且方向正确。
4.6 实战配置流程
最后,给一个我常用的配置流程,按这个顺序来,基本不会漏东西:
- 系统时钟配置:确认 ePWM 模块的时钟源和频率。
- 时基配置:设置分频系数和周期寄存器,确定开关频率。
- 比较值初始化:设置一个安全的初始占空比,比如 50%。
- 动作限定配置:定义计数事件对应的输出动作。
- 死区配置:根据 MOSFET 参数设置死区时间。
- 输出极性配置:确认互补输出极性正确。
- 使能输出:最后才打开 PWM 输出。
总结:ePWM 配置的核心就三件事——频率、占空比、死区。频率由时基决定,占空比由比较值决定,死区由延迟值决定。互补输出是死区模块的典型应用。把这三点吃透,数字电源的 PWM 部分就稳了。