3、防短路核心逻辑:直通现象、死区时间与PWM控制
各位工程师朋友,今天我们来聊聊直流电机H桥驱动中最要命的问题——短路。
我刚开始做电机驱动那会儿,就吃过这个亏。板子一上电,MOS管直接冒烟,吓得我赶紧拔电源。后来一查,就是典型的“直通”问题。说白了,就是上下两个管子同时导通了。
3.1 直通(Shoot-through)现象分析
什么叫直通?我画个简图你就明白了。
你看这个H桥,正常工作时,Q1和Q4导通,电流从VCC→Q1→电机→Q4→GND,电机正转。反过来Q2和Q3导通,电机反转。
但问题来了——如果Q1还没完全关断,Q2就已经导通了,会发生什么?
- VCC直接对GND短路,电流瞬间飙升
- MOS管在几微秒内过热烧毁
- 严重时可能炸管、烧PCB铜箔
- 电源电压会被瞬间拉低,影响其他电路
我在一个项目中就遇到过这种情况。当时用的是IR2104驱动芯片,死区时间设得太短,结果上电测试时,MOS管直接炸了,碎片崩到脸上,还好戴了护目镜。从那以后,我对死区时间就特别敏感。
3.2 死区时间(Dead Time)概念
死区时间,说白了就是故意插入的一段“空白期”。
在这段时间里,上下两个管子都关断。谁都不导通,自然就不会直通了。
| 参数 | 说明 | 典型值 |
|---|---|---|
| 死区时间 | 上下管都关断的时间间隔 | 100ns ~ 2μs |
| MOS管关断延迟 | 从栅极信号到完全关断的时间 | 20ns ~ 100ns |
| MOS管导通延迟 | 从栅极信号到完全导通的时间 | 15ns ~ 80ns |
| 安全裕量 | 死区时间减去开关延迟 | 建议 ≥ 50ns |
嗯,这里要注意:死区时间不是越长越好。太长了,电机电流会断续,产生噪音和振动。太短了,又可能直通。我一般取开关延迟的2~3倍作为起步值。
3.3 互补PWM与独立PWM控制
讲完死区,我们来看看两种常见的PWM控制方式。
3.4.1 互补PWM(Complementary PWM)
互补PWM,就是上下两个管的控制信号正好相反。上管高电平时,下管低电平;上管低电平时,下管高电平。
但直接这样用肯定不行——你想想看,信号翻转需要时间,翻转过程中就可能直通。所以要在翻转之间插入死区。
// 互补PWM + 死区插入(伪代码)
// 假设PWM频率20kHz,周期50μs
// 死区时间500ns
void generateComplementaryPWM(uint16_t dutyCycle) {
// 上管导通时间
uint16_t onTime = dutyCycle;
// 下管导通时间
uint16_t offTime = PWM_PERIOD - dutyCycle;
// 插入死区:上管关断后等500ns,下管才导通
// 下管关断后等500ns,上管才导通
// 实际波形:
// 上管: ████████______████████______
// 下管: ________████████______██████
// 死区: ↑←500ns→↑ ↑←500ns→↑
}
我习惯用STM32的定时器来做互补PWM。它的高级定时器自带死区插入功能,配置一下就行。
// STM32 互补PWM配置示例
void setupComplementaryPWM(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
// 定时器配置
TIM_TimeBaseStructure.TIM_Period = 999; // 20kHz @ 20MHz
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// PWM1模式配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; // 互补输出
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
// 死区时间配置:500ns
TIM_BDTRInitStructure.TIM_DeadTime = 10; // 500ns @ 20MHz
TIM_BDTRInit(TIM1, &TIM_BDTRInitStructure);
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
3.4.2 独立PWM(Independent PWM)
独立PWM就灵活多了。上下两个管子的PWM信号完全独立,你可以分别控制它们的占空比和相位。
这样做的好处是:
- 可以精细控制死区时间
- 支持更多控制模式(比如同步整流)
- 调试方便,可以单独测试每个管子
但缺点也很明显——软件复杂度高。你得自己保证上下管不会同时导通。
| 特性 | 互补PWM | 独立PWM |
|---|---|---|
| 硬件复杂度 | 低(硬件自动插入死区) | 高(软件控制) |
| 灵活性 | 低(固定互补关系) | 高(任意波形) |
| 死区控制 | 硬件自动 | 软件手动 |
| 适用场景 | 普通电机驱动 | 高性能/特殊控制 |
| 风险 | 配置错误仍可能直通 | 软件bug导致直通 |
我个人习惯是:能用互补PWM就用互补PWM。硬件自动插入死区,省心又可靠。只有在需要特殊控制波形时,才用独立PWM。
3.4 避坑指南
最后,分享几个我踩过的坑:
- 死区时间设得太极限——以为100ns就够了,结果温度一高,MOS管开关速度变慢,直接直通。后来我留了3倍裕量。
- 忘记考虑MOS管寄生参数——栅极电阻、米勒电容都会影响开关速度。实际死区时间要比计算值大一些。
- 软件死区实现有bug——用定时器中断做独立PWM时,中断优先级没处理好,导致死区偶尔丢失。后来改用硬件定时器才解决。
- 新板子第一次上电,先把死区设大一点(比如2μs),确认没问题再慢慢缩小
- 用示波器同时看上下管的栅极波形,确认死区存在
- 温度测试时,在高温和低温下都验证死区是否足够
- 量产前做短路测试:故意让电机堵转,看驱动电路能否扛住
好了,关于防短路的核心逻辑就讲到这里。死区时间这个东西,说难不难,说简单也不简单。关键是要理解它的本质——用一点点时间损失,换取系统的安全可靠。这个取舍,值得。
公众号:蓝海资料掘金营,微信deep3321