3. 电机控制基础:H桥原理,PWM调速与死区时间设置

好,咱们今天聊点硬核的。H桥、PWM、死区时间,这三个词你肯定不陌生。但说实话,我见过不少工程师,干了三五年,对死区的理解还停留在「加个延时就行」的层面。嗯,这其实挺危险的。

咱们一步步来。先搞懂H桥到底在干嘛,再说PWM怎么调速,最后聊聊那个让人又爱又恨的死区时间。

3.1 H桥原理:说白了就是个换向开关

H桥这个名字,来源于它的电路形状像个大写的字母「H」。四个开关管,两个在上,两个在下,中间挂着电机。你想想看,这不就是个换向开关吗?

我习惯把四个开关管分别叫做:Q1(左上)、Q2(右上)、Q3(左下)、Q4(右下)。

电机要正转,怎么办?导通Q1和Q4。电流从电源正极,经过Q1,流过电机,再经过Q4,回到电源负极。就这么简单。

要反转呢?导通Q2和Q3。电流方向反过来了。

这里有个关键点——绝对不能同时导通同一侧的上下两个管子。比如Q1和Q3同时导通,那就是电源正极直接对地短路。我管这叫「直通」,后果嘛...冒烟是轻的,严重的话能把MOSFET炸飞。

核心要点:

  • 正转:Q1 + Q4 导通
  • 反转:Q2 + Q3 导通
  • 刹车:Q1 + Q2 导通(或 Q3 + Q4)
  • 滑行:全部关断

我在项目中遇到过一件事。有个同事,调试时发现电机一启动就抖得厉害。查了半天,发现是H桥的驱动时序写错了,正转和反转之间没有加延时,导致瞬间短路。嗯,那次教训挺深刻的。

3.2 PWM调速:不是调电压,是调占空比

很多人以为PWM调速就是调电压。其实不是。你想想看,电机两端接的是12V或者24V,电压是固定的。那怎么调速?

答案是:通过快速开关,改变平均电压

PWM的全称是脉冲宽度调制。说白了,就是在一个固定的周期里,让管子导通一段时间,关断一段时间。导通时间占整个周期的比例,叫占空比。

占空比50%,电机得到一半的功率。占空比100%,全功率。占空比0%,停转。

我习惯用这样的公式来理解:

电机平均电压 = 电源电压 × 占空比

举个例子。电源12V,占空比75%,那电机感受到的平均电压就是9V。转速大概就是全速的75%。

这里有个坑——PWM频率不能太低,也不能太高

  • 频率太低(比如几十Hz):电机会发出嗡嗡声,甚至能听到开关的咔嗒声。人耳能听到20Hz到20kHz,你想想看,要是PWM频率落在人耳范围内,那噪音得多烦人。
  • 频率太高(比如几百kHz):开关损耗会急剧增加。MOSFET每开关一次,都有能量损耗。频率越高,损耗越大,发热越严重。

我个人建议,车载转向电机的PWM频率选在10kHz到20kHz之间。这个范围人耳听不到,开关损耗也还能接受。

我的经验:

我曾经在一个项目里把PWM频率设到了50kHz,结果MOSFET烫得能煎鸡蛋。后来降到16kHz,温度直接降了30度。频率这东西,不是越高越好。

3.3 死区时间:一个不得不加的「安全间隙」

好,现在咱们聊聊死区时间。这是H桥控制里最容易出问题的地方。

你想想看,H桥在换向的时候,比如从正转切换到反转。正转时Q1和Q4导通,反转时需要Q2和Q3导通。那中间这个切换过程,怎么保证不短路?

假设我先关掉Q1和Q4,再打开Q2和Q3。听起来没问题对吧?但实际中,开关管不是瞬间完成的。关断需要时间,导通也需要时间。

如果Q1还没完全关断,Q3就已经导通了——直通!

所以,我们需要在切换时,插入一段「所有人都关断」的时间。这段时间就是死区时间。

我画个图帮你理解:

H桥PWM与死区时间示意图 Q1 Q3 死区 死区 时间 → 红色:Q1导通(上管) 蓝色:Q3导通(下管) 橙色区域:死区时间(所有管子关断)

你看,Q1关断后,要等一段时间,Q3才能导通。这段时间里,两个管子都是关断的。这就是死区。

死区时间设多长?这取决于你用的MOSFET或者IGBT的开关速度。

开关器件类型 典型开关时间 建议死区时间
低速MOSFET 100-200ns 500ns - 1μs
高速MOSFET 20-50ns 100-300ns
IGBT 200-500ns 1-3μs
智能功率模块 内置死区 按手册配置

警告:

死区时间不是越大越好。死区太长,电机会出现明显的「台阶感」,低速时尤其明显。死区太短,又有直通风险。我曾经在一个项目里,因为死区设了2μs,电机在低速时抖得像筛子。后来调到500ns,问题解决了。

3.4 代码实现:一个简单的PWM+死区示例

说了这么多理论,咱们看看代码怎么写。我用的是STM32的HAL库,但思路是通用的。

// 配置定时器PWM输出
void Motor_PWM_Init(void)
{
    TIM_HandleTypeDef htim1;
    TIM_OC_InitTypeDef sConfigOC = {0};
    
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 0;                    // 不分频
    htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;  // 中央对齐模式
    htim1.Init.Period = 1000;                    // PWM频率 = 72MHz / 1000 = 72kHz
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim1.Init.RepetitionCounter = 0;
    htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    HAL_TIM_PWM_Init(&htim1);
    
    // 配置通道1(上管PWM)
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;                         // 初始占空比0%
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
    sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
    
    // 配置通道2(下管PWM)
    sConfigOC.Pulse = 0;
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2);
    
    // 启动PWM输出
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
}

// 设置电机转速和方向
void Motor_SetSpeed(int16_t speed)
{
    // speed范围:-1000 ~ 1000
    // 正数:正转,负数:反转
    
    if (speed > 0)
    {
        // 正转:上管PWM,下管常关
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, speed);
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 0);
    }
    else if (speed < 0)
    {
        // 反转:下管PWM,上管常关
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, -speed);
    }
    else
    {
        // 停止
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 0);
    }
}

注意看,我用了中央对齐模式。为什么?因为中央对齐模式下,PWM的上升沿和下降沿是错开的,天然就有一定的死区效果。当然,这不能完全替代硬件死区,但能减少死区设置的难度。

我的习惯:

我一般会在硬件上再加一级死区插入电路。比如用74HC14或者专门的MOSFET驱动芯片,它们内部有死区时间设置引脚。这样即使软件出了bug,硬件也能兜底。

3.5 避坑指南

最后,我总结几个我踩过的坑,你遇到了可以少走弯路。

  • 死区时间不是对称的:上管关断和下管导通的时间可能不一样。最好用示波器实测,别光看手册。
  • PWM频率和死区时间要匹配:频率越高,死区占的比例越大,有效占空比范围就越小。比如72kHz的PWM,死区1μs,那占空比损失就很大。
  • 启动时要小心:电机启动瞬间电流很大,可能达到额定电流的5-10倍。这时候如果死区设置不当,很容易炸管。
  • 别忘了续流二极管:H桥里的MOSFET本身有体二极管,但有时候体二极管不够用。我建议在电机两端并联一个快恢复二极管,能有效抑制反电动势。

我曾经在一个量产项目里,因为死区时间设得太紧,导致一批产品在高温下频繁炸管。后来查出来,是温度升高后MOSFET的开关速度变慢了,死区不够用。从那以后,我设计死区时间都会留30%的余量。

好了,H桥、PWM、死区时间,这三个东西你搞明白了,电机控制的基础就算打牢了。下一节咱们聊聊更高级的东西——电流环和速度环的控制。嗯,到时候你会发现,今天讲的这些东西,全都会用上。


公众号:蓝海资料掘金营,微信deep3321