08三相逆变器

桥臂、PWM、死区和线电压

本模块主旨
6 个开关 + 3 桥臂 + 死区 + 中心对齐 PWM + BKIN 硬件保护 = 把 Vd/Vq 安全落到电机绕组上。

学完应能回答

查看完整 Walkthrough(9 步 + 4 误区)

总览
逆变器是算法 → 真实电机的功率桥梁。理想模型简洁,但死区 / 过流 / 直通保护是工程必须做对的事。

零基础速入

类比
逆变器就像 6 个开关组成的"接力开关阵"——上下两个开关互相 toggle,把直流母线斩成想要的交流相电压。要保护这些开关不烧("死区"=不让上下管同时开),又要把死区造成的失真补偿回来。
核心概念
6 个 MOSFET/IGBT 三对,每对上下管互补导通;占空比决定平均相电压;死区时间是必要的保护代价但会造成低速电压畸变。

为什么要学

第一手操作
右侧把"死区时间"从 1μs 拉到 4μs,看相电压波形顶部出现明显凹槽(死区损失增大)。再把"PWM 频率"从 16kHz 降到 4kHz,看死区在每个周期占比变大、损失放大。

学习目标

核心概念

公式

平均相电压(理想)
Va = (Da - 0.5) × Udc

Da 是上桥臂占空比 [0,1],以母线中点为参考。Da=0.5 → Va=0;Da=1 → Va=+Udc/2。

死区损失
ΔV_dt = td × fpwm × Udc × sign(Iphase)

电流流入电机时上管"少导通"td,电流流出时下管"少导通"td。损失正比于死区时间和频率。

过调制阈值
|Vphase| > 0.5 × Udc → 部分 PWM 周期 duty 撞 0 或 1

SVPWM 线性区单相幅值 ≈ Udc/√3 ≈ 0.577·Udc。继续增大就有 duty 被钳位。

死区补偿
Va_cmd = Va_ref + ΔV_dt × sign(Ia)

提前在 PWM 命令上加补偿值;电流过零附近补偿不准(极性翻转),靠抑制电流过零段抖动。

工程意义

STM32 移植指南

常见误区

  • 忘记 enable 互补输出极性(CCxNE)。
  • 死区过大(>5μs)低速波形严重畸变啸叫。
  • 没有硬件过流保护,软件来不及救。
  • 上电瞬间 PWM 占空比未初始化为 0.5,触发母线冲击。

调试方法

建议实验

STM32 C 代码骨架

/* ============================================
 * inverter_init.c — STM32G4 TIM1 三相互补 + 死区 + 刹车
 * ============================================ */

#define PWM_FREQ_HZ      16000
#define DEAD_TIME_NS     1000      // 1 μs,按驱动器手册调
#define APB2_CLOCK_HZ    170000000 // G4 主频

void inverter_pwm_init(void) {
    /* 1. TIM1 时钟 */
    RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;

    /* 2. 中心对齐 PWM,ARR = clock / freq / 2 (因为中心对齐计数翻倍) */
    TIM1->PSC = 0;
    TIM1->ARR = APB2_CLOCK_HZ / PWM_FREQ_HZ / 2 - 1;
    TIM1->CR1 |= TIM_CR1_CMS_0;     // 中心对齐 mode 1(向上时更新比较)

    /* 3. PWM mode 1 三通道 + 互补输出 */
    TIM1->CCMR1 |= (6 << TIM_CCMR1_OC1M_Pos) | TIM_CCMR1_OC1PE;
    TIM1->CCMR1 |= (6 << TIM_CCMR1_OC2M_Pos) | TIM_CCMR1_OC2PE;
    TIM1->CCMR2 |= (6 << TIM_CCMR2_OC3M_Pos) | TIM_CCMR2_OC3PE;
    TIM1->CCER  |= TIM_CCER_CC1E | TIM_CCER_CC1NE
                 | TIM_CCER_CC2E | TIM_CCER_CC2NE
                 | TIM_CCER_CC3E | TIM_CCER_CC3NE;

    /* 4. 死区 + 主输出使能(BDTR)
     *    DTG[7:5]=0xx → DT = DTG × tCK_INT
     *    1μs @ 170MHz → DTG ≈ 170 (0xAA) */
    uint32_t dtg = (uint32_t)((uint64_t)DEAD_TIME_NS * APB2_CLOCK_HZ / 1000000000ULL);
    if (dtg > 127) dtg = 127;       // 简单上限,更高需切高位编码
    TIM1->BDTR = TIM_BDTR_MOE | (dtg & 0xFF);

    /* 5. 刹车输入 BKIN(接过流比较器输出,下降沿触发关断) */
    TIM1->BDTR |= TIM_BDTR_BKE | TIM_BDTR_BKP;

    /* 6. 初始占空比 50%,避免上电冲击 */
    TIM1->CCR1 = TIM1->ARR / 2;
    TIM1->CCR2 = TIM1->ARR / 2;
    TIM1->CCR3 = TIM1->ARR / 2;

    /* 7. 中断(更新事件触发 ADC 注入) */
    TIM1->DIER |= TIM_DIER_UIE;
    NVIC_SetPriority(TIM1_UP_TIM16_IRQn, 0);
    NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);

    /* 8. 启动 */
    TIM1->CR1 |= TIM_CR1_CEN;
}

/* 中断里写 CCR:
 *   TIM1->CCR1 = (uint16_t)(duty_a * (TIM1->ARR + 1));
 * BKIN 触发后 MOE=0,所有 PWM 强制低,无需 CPU。
 */

下一步

随堂题

同一桥臂上下管同时导通会发生什么?
  1. 正常工作
  2. 直通短路,瞬间炸管 (正确)
  3. 只是输出错误
  4. 保护自动启动
提示:上下管同时开 = 母线 + 经过两个管子直接接地,瞬态短路电流毫秒级烧毁。死区时间就是为了避免这个。
死区时间 td = 2μs,PWM 频率 16kHz,占空比 50% 时一个周期"丢失"的导通时间占比?
  1. 约 0.4%
  2. 约 3.2% (正确)
  3. 约 32%
  4. 约 50%
提示:一个周期 62.5μs,死区 2μs 占 3.2%。低速小电流时这部分电压损失明显。
STM32 高级定时器 TIM1 的"刹车输入 BKIN"作用是?
  1. 启动 PWM
  2. 硬件触发后立刻关断所有 PWM 输出,无需 CPU 介入 (正确)
  3. 改变频率
  4. 复位定时器
提示:过流时硬件比较器输出接到 BKIN,触发后 MOE 寄存器自动清零,所有 PWM 强制低。CPU 中断只是事后处理。
低速小电流时电机啸叫,最可能的根因是?
  1. Kp 太大
  2. 死区时间过大造成低速电压畸变 (正确)
  3. PWM 频率太低
  4. 编码器分辨率不够
提示:死区损失 ΔV 与 td × fpwm 成正比,电流过零附近电压扭曲。可缩短死区或加死区补偿算法。
上电瞬间发现母线大冲击电流。检查代码,PWM CCR 初始化值是多少最安全?
  1. 0
  2. ARR (= 100%)
  3. ARR/2 (= 50%) (正确)
  4. 随便
提示:CCR=0 → 上桥常闭、下桥常开,下桥电流通过电机绕组到地,无电压差。最安全的是 ARR/2 (50%) → 三相中点电压都等于 Udc/2,相间无电压。