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,示波器是最好的老师。别光盯着代码看,把探头夹在电机端子上,波形会告诉你一切。