1. 为什么电机驱动必须考虑死区控制?
我第一次用TI DSP 28335做电机驱动时,烧掉了三块MOSFET。当时怎么也想不明白,明明PWM波形看起来很正常,为什么上电就炸管?后来才发现是死区时间没设置好。这个惨痛教训让我深刻理解到:死区控制不是可选项,而是电机驱动的生命线。
在H桥或三相逆变器中,同一桥臂的两个开关管(比如上管和下管)绝对不能同时导通。但现实中MOSFET或IGBT都存在关断延迟(Turn-off delay),这个时间通常在几十到几百纳秒。如果上管的关断信号和下管的开通信号完全同步,就会出现短暂的"共通"现象,造成电源直通短路。轻则导致器件过热,重则直接炸管冒烟。
死区就是在互补PWM信号中插入的安全间隔。具体做法是:在原有PWM边沿处,让开通信号适当延迟(称为上升沿死区),同时让关断信号适当提前(称为下降沿死区)。这样就能确保:在任何一个开关管完全关断之前,另一个管绝不会开通。TI DSP 28335的ePWM模块内置了专业的死区生成单元(DB模块),可以精确控制这个安全间隔。
2. ePWM死区模块的硬件原理
28335的ePWM模块堪称电力电子工程师的瑞士军刀。它的死区控制单元(DB模块)位于动作限定模块(AQ)之后,通过可编程逻辑实现硬件级的安全防护。我拆解过它的工作流程:
输入信号选择(IN_MODE寄存器):决定对哪路信号进行死区处理。常见配置是:
- 00:直接使用AQ输出的EPWMxA
- 01:使用AQ输出的EPWMxB
- 10:使用AQ输出的EPWMxA和EPWMxB(这是我们最常用的H桥模式)
极性控制(POLSEL寄存器):这个设置很容易被忽视,但却至关重要。它决定了互补信号的极性关系:
- 00:两路输出同相(很少用)
- 01:EPWMxB反相
- 10:EPWMxA反相
- 11:两路都反相(相当于整体反向)
死区时间计算:这是最核心的部分。DBRED控制上升沿延迟,DBFED控制下降沿提前。它们的计算公式是:
死区时间 = (DBRED或DBFED值) × TBCLK周期比如系统时钟75MHz时,要实现1μs死区:
DBRED = DBFED = 1μs × 75MHz = 75
实际项目中我遇到过一个问题:设置的死区时间明明计算正确,但示波器测量总是不对。后来发现是忘了配置时基模块的时钟分频(HSPCLKDIV和CLKDIV),导致实际TBCLK频率与预期不符。这个坑提醒我:死区时间配置必须和时基模块设置联动检查。
3. 从理论到代码的完整实现
下面以1kHz PWM、50%占空比、1μs死区为例,展示完整的配置流程。这段代码已经在多个量产项目中验证过:
// 时基模块配置 EPwm1Regs.TBPRD = 37500; // 1kHz PWM周期 EPwm1Regs.TBCTL.bit.CTRMODE = 2; // 增减计数模式 EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // 高速时钟2分频 EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 基准时钟不分频 // 比较模块配置 EPwm1Regs.CMPA.half.CMPA = 18750; // 50%占空比 // 动作限定配置 EPwm1Regs.AQCTLA.bit.CAU = 2; // CTR=CMPA且增计数时拉高 EPwm1Regs.AQCTLA.bit.CAD = 1; // CTR=CMPA且减计数时拉低 // 死区模块核心配置 EPwm1Regs.DBCTL.bit.IN_MODE = 2; // 使用EPWMxA和EPWMxB作为输入 EPwm1Regs.DBCTL.bit.POLSEL = 2; // EPWMxB反相输出 EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // 使能双路输出 EPwm1Regs.DBRED = 75; // 上升沿延迟1μs EPwm1Regs.DBFED = 75; // 下降沿提前1μs有几个关键点需要注意:
- 计数模式选择:增减计数模式(先增后减)能产生对称的PWM波形,特别适合电机驱动。如果使用增计数模式,周期计算公式会不同。
- 占空比计算:在增减计数模式下,实际占空比是CMPA值与TBPRD的比值。比如CMPA=TBPRD/2就是50%占空比。
- 死区生效条件:必须同时配置OUT_MODE=3来使能双路输出,否则死区设置不会生效。
4. 死区时间对电机性能的影响
死区时间不是越大越好。我在做伺服驱动测试时,记录过不同死区时间对电机性能的影响:
| 死区时间 | 电流THD | 效率 | 温升 | 现象描述 |
|---|---|---|---|---|
| 0.5μs | 5.2% | 92.3% | +28℃ | 偶尔出现共通导致炸管 |
| 1.0μs | 5.5% | 91.8% | +25℃ | 稳定运行 |
| 2.0μs | 6.8% | 89.5% | +32℃ | 明显振动和噪音 |
| 3.0μs | 8.1% | 86.2% | +40℃ | 转矩脉动明显 |
从实测数据可以看出:
- 死区过小(0.5μs):虽然波形质量好,但存在共通风险
- 死区适中(1μs):安全性和性能达到平衡
- 死区过大:会导致输出电压失真,增加谐波和损耗
选择死区时间的经验法则是:取开关管规格书中关断延迟时间的1.5倍。比如某MOSFET的关断延迟是600ns,那么死区可设置为900ns到1μs。实际项目中,我通常会先用示波器观察开关管的实际关断波形,再微调死区参数。
5. 高级技巧与常见问题排查
在调试死区控制时,有几个实用技巧值得分享:
问题1:死区时间不生效
- 检查DBCTL[OUT_MODE]是否设置为3
- 确认GPIO复用功能已正确配置(使用EALLOW保护)
- 测量TBCLK实际频率是否与计算一致
问题2:互补波形不同步
- 检查POLSEL设置是否符合硬件电路设计
- 确认AQ模块配置是否正确(特别是CAU/CAD动作)
- 使用示波器的XY模式观察两路PWM的相位关系
问题3:电机出现异常噪音
- 适当增大死区时间(每次增加10ns测试)
- 检查CMPA值是否在0到TBPRD之间
- 尝试改用对称PWM生成模式
对于需要动态调整死区的应用(比如根据温度补偿),可以通过中断服务程序实时修改DBRED和DBFED:
interrupt void epwm1_isr(void) { EPwm1Regs.DBRED = adjust_red; // 动态调整上升沿死区 EPwm1Regs.DBFED = adjust_fed; // 动态调整下降沿死区 EPwm1Regs.ETCLR.bit.INT = 1; // 清除中断标志 }最后提醒一个容易忽略的细节:28335的ePWM模块支持寄存器影子缓冲(Shadow Register),但在配置死区参数时,DBRED和DBFED是立即生效的,没有影子缓冲机制。这意味着在运行时修改这些参数要特别小心,最好在PWM周期开始或结束时进行。