4、SVPWM算法实现:七段式与五段式,占空比计算与死区补偿

好,咱们进入实战环节。前面几章我们把SVPWM的理论基础、扇区判断、作用时间都捋了一遍。现在要做的,就是把这些数学公式变成单片机里跑的代码,最终生成能驱动逆变器的PWM波。

这部分内容,说白了就是“怎么把算好的时间塞进定时器”。我见过不少新手,理论推导头头是道,一到写代码就卡壳。嗯,今天咱们就把这层窗户纸捅破。

4.1 七段式SVPWM:经典中的经典

七段式,也叫对称式SVPWM。它的核心思想是:每次开关状态切换,只改变一个桥臂的开关状态。这样做的好处很明显——谐波小,电流纹波也小。

我记得第一次调七段式的时候,用示波器看相电压波形,那个对称性确实漂亮。但代价是开关次数多,损耗大一点。

七段式的开关序列长这样(以第一扇区为例):

000 → 100 → 110 → 111 → 110 → 100 → 000

你看,从零矢量000开始,经过两个非零矢量,到达111,再原路返回。整个过程7段,所以叫七段式。

每个矢量的作用时间分配是这样的:

段序号 矢量 时间
1 V0 (000) T0/4
2 V4 (100) T1/2
3 V6 (110) T2/2
4 V7 (111) T0/2
5 V6 (110) T2/2
6 V4 (100) T1/2
7 V0 (000) T0/4

这里T0是零矢量总时间,T1和T2是两个非零矢量的作用时间。你可能会问:为什么零矢量要拆成四份?

其实就是为了让波形对称。对称波形能减少偶次谐波,这对电机运行很有好处。

关键点:七段式的占空比计算,本质上是把T1、T2、T0分配到三个桥臂的比较值上。每个桥臂的导通时间,就是该桥臂在7段序列中处于高电平的时间总和。

4.2 五段式SVPWM:效率优先

五段式,也叫不连续调制。它跟七段式的区别在于:每个PWM周期内,有一个桥臂不动作,始终接在正母线或负母线上。

说白了,就是牺牲一点波形质量,换来开关损耗降低1/3。我在做低电压大电流的电机驱动器时,特别喜欢用五段式。发热量明显小一截。

五段式的开关序列(第一扇区,钳位在正母线):

100 → 110 → 111 → 110 → 100

你看,只有5段。C相桥臂全程保持高电平(111状态),不参与开关。

两种方式的对比:

对比项 七段式 五段式
开关次数/周期 6次 4次
开关损耗 高 低(降低约33%)
电流谐波 小 稍大
适用场景 对噪声敏感、要求高 大电流、散热受限

我的建议:如果刚开始调SVPWM,先用七段式。波形好,容易debug。等系统跑稳了,再根据温升情况考虑要不要切到五段式。

4.3 占空比计算与PWM生成

好,到了真正写代码的环节。占空比计算,其实就是把T1、T2、T0映射到定时器的比较寄存器。

假设我们用的是中心对齐PWM模式,定时器周期为TPR。那么三个桥臂的比较值可以这样算:

// 假设已经算出了T1、T2、T0
// 扇区为第一扇区

// 先计算三个桥臂的导通时间
float Ta = (TPR - T1 - T2) / 2.0f;  // A相导通时间
float Tb = Ta + T1;                  // B相导通时间
float Tc = Tb + T2;                  // C相导通时间

// 根据扇区,将Ta、Tb、Tc分配给实际的U、V、W相
switch(sector)
{
    case 1:
        cmp1 = Ta;  // U相
        cmp2 = Tb;  // V相
        cmp3 = Tc;  // W相
        break;
    case 2:
        cmp1 = Tb;
        cmp2 = Ta;
        cmp3 = Tc;
        break;
    // ... 其他扇区类似
}

这里有个细节:Ta、Tb、Tc是导通时间,不是比较值。在中心对齐模式下,比较值 = 周期/2 - 导通时间/2。但很多MCU的定时器可以直接设置导通时间,具体看芯片手册。

我曾经在一个项目里,因为搞混了“比较值”和“导通时间”,波形乱得一塌糊涂。后来用示波器一抓,才发现是这里的问题。

注意:计算占空比时,一定要做限幅处理。如果T1+T2 > TPR,说明进入了过调制区。这时候需要等比例缩小T1和T2,保证总时间不超过PWM周期。

4.4 死区时间补偿

死区,是逆变器永远绕不开的话题。上下桥臂不能同时导通,否则就是短路。所以需要在切换时插入一段“都关断”的时间,这就是死区。

但死区会带来问题:输出电压失真。尤其是在低速轻载时,死区效应会导致电流波形畸变,甚至引起转矩脉动。

怎么补偿?我的做法是:根据电流方向,调整比较值。

原理很简单:

  • 当电流从桥臂流出(正电流),死区会导致输出电压偏低
  • 当电流流入桥臂(负电流),死区会导致输出电压偏高

所以补偿策略就是:

// 死区补偿
if (current_A > 0)
    cmp1 += dead_time_comp;  // 正电流,增加导通时间
else
    cmp1 -= dead_time_comp;  // 负电流,减少导通时间

// 同样处理B相和C相

这个dead_time_comp的值,一般取死区时间的一半。但实际效果跟母线电压、开关频率都有关系。我习惯在调试时,用示波器看相电压波形,手动微调这个值,直到波形过零点没有明显畸变。

避坑指南:我曾经在一个项目里,死区补偿的方向搞反了。结果电流波形比不补偿还差。后来在代码里加了个标志位,可以一键切换补偿方向,调试起来方便多了。

4.5 整体流程:一张图说清楚

下面这张图,把整个SVPWM实现的流程串起来了。从扇区判断到最终输出PWM,每一步都离不开。

SVPWM算法实现流程 输入:Vα, Vβ 扇区判断 计算T1、T2、T0 选择七段式/五段式 占空比计算与限幅 死区时间补偿 更新PWM寄存器 关键参数 • PWM频率:10k~20kHz • 死区时间:0.5~3μs • 调制比:0~0.9069 调试建议 1. 先开环输出固定占空比 2. 用示波器抓相电压波形 3. 确认扇区切换点正确

你看,整个流程其实不复杂。关键是把每一步的输入输出搞清楚,代码自然就写出来了。

最后说一句:调试SVPWM,示波器是最好的老师。别光盯着代码看,把探头夹在电机端子上,波形会告诉你一切。