3. 基本矢量作用时间:相邻矢量作用时间计算、零矢量分配策略
好,咱们接着聊SVPWM的核心——矢量作用时间。上一章我们讲了怎么判断扇区,知道了当前参考电压在哪个区域。那接下来呢?说白了,就是得算出每个扇区里那两个相邻基本矢量各干多久的活,以及零矢量怎么插进去。
我个人习惯把这一步叫做“时间分配”。你想想看,一个开关周期是固定的,比如100微秒。你得在这100微秒里,把Uα、Uβ这两个目标电压分量,用两个相邻矢量和零矢量拼出来。拼得好,波形就漂亮;拼得不好,谐波就大。
3.1 相邻矢量作用时间计算
先讲计算。每个扇区里,两个相邻矢量的作用时间T1和T2,其实有统一的公式。我记得刚入行时,看到那些三角函数推导头都大了。后来发现,只要记住一个核心原则就行:伏秒平衡。
什么意思?就是在一个周期内,两个相邻矢量产生的效果,要跟参考电压矢量完全一样。用数学表达就是:
T1 * V1 + T2 * V2 = Ts * Vref
其中Ts是开关周期,V1和V2是相邻基本矢量,Vref是参考电压矢量。把这个方程在αβ坐标系下展开,就能解出T1和T2。
我直接给结论吧。对于第I扇区(0°~60°),两个相邻矢量是V1(100)和V2(110),它们的作用时间是:
T1 = (sqrt(3) * Ts / Vdc) * (sqrt(3)/2 * Uα - 0.5 * Uβ)
T2 = (sqrt(3) * Ts / Vdc) * Uβ
看着有点复杂?别急,实际工程里我们一般用查表法或者归一化处理。我给大家整理了一个通用公式表,覆盖所有扇区:
| 扇区 | 相邻矢量 | T1(第一个矢量) | T2(第二个矢量) |
|---|---|---|---|
| I (0°~60°) | V1(100), V2(110) | K * (√3/2·Uα - 0.5·Uβ) | K * Uβ |
| II (60°~120°) | V3(010), V2(110) | K * (-√3/2·Uα - 0.5·Uβ) | K * (√3/2·Uα - 0.5·Uβ) |
| III (120°~180°) | V3(010), V4(011) | K * Uβ | K * (-√3/2·Uα - 0.5·Uβ) |
| IV (180°~240°) | V5(001), V4(011) | K * (-√3/2·Uα + 0.5·Uβ) | K * (-Uβ) |
| V (240°~300°) | V5(001), V6(101) | K * (√3/2·Uα + 0.5·Uβ) | K * (-√3/2·Uα + 0.5·Uβ) |
| VI (300°~360°) | V1(100), V6(101) | K * (-Uβ) | K * (√3/2·Uα + 0.5·Uβ) |
其中 K = √3 · Ts / Vdc。注意,Uα和Uβ是经过Clark变换后的电压分量,单位是伏特。
3.2 过调制处理
算完T1和T2之后,有个坑必须注意——过调制。什么是过调制?就是T1 + T2 > Ts的情况。这时候参考电压矢量超出了六边形的内切圆,你没法用两个相邻矢量拼出来了。
我曾经在一个电机驱动项目里遇到过这个问题。当时电机高速运行时,突然电流波形开始抖动,噪声也变大了。查了半天,发现就是过调制没处理好,T1+T2超过了Ts,导致计算出来的占空比超过了100%。
处理办法很简单:如果T1 + T2 > Ts,就按比例缩放:
T1_new = T1 * Ts / (T1 + T2)
T2_new = T2 * Ts / (T1 + T2)
这样T1_new + T2_new就等于Ts了。但代价是输出电压幅值会降低,波形会失真。嗯,这是没办法的事,物理极限摆在那里。
3.3 零矢量分配策略
好,T1和T2算完了,剩下的时间就是零矢量的。零矢量有两个:V0(000)和V7(111)。怎么分配它们的时间?这里就有讲究了。
零矢量分配直接影响两个东西:开关损耗和谐波含量。我给大家总结三种常见策略:
| 策略名称 | 分配方式 | 特点 | 适用场景 |
|---|---|---|---|
| 对称分配 | T0 = T7 = Ts/2 - (T1+T2)/2 | 谐波最小,开关次数均衡 | 通用场景,最常用 |
| 单零矢量 | 只用V0或只用V7 | 开关次数少,损耗低 | 对效率要求高的场合 |
| 非对称分配 | T0 ≠ T7,按比例分配 | 可调节共模电压 | EMI敏感场景 |
我个人最常用的是对称分配。为什么?因为它产生的PWM波形是对称的,谐波含量最低。你想想看,一个周期里,V0和V7各占一半时间,开关管在中间时刻切换,波形看起来就很舒服。
具体实现是这样的:
T0 = Ts - T1 - T2
T0_half = T0 / 2
T7_half = T0 / 2
// 然后计算三相占空比
// 以第I扇区为例:
Ta = T0_half
Tb = T0_half + T1
Tc = T0_half + T1 + T2
这里的Ta、Tb、Tc就是三相上桥臂的导通时间。注意,这个顺序跟扇区有关,不同扇区对应的相序不一样。
3.4 七段式与五段式SVPWM
说到零矢量分配,就不得不提七段式和五段式SVPWM。这两个概念其实就是在说:一个开关周期里,开关管切换了几次。
- 七段式: 每个周期内,三相开关管总共切换7次。V0 → V1 → V2 → V7 → V2 → V1 → V0。对称分配,谐波小。
- 五段式: 每个周期内,只切换5次。去掉了一组零矢量,比如只用V0和V1、V2。开关损耗降低约30%,但谐波会大一些。
我记得有一次做车载逆变器,客户对效率要求特别高。我试了五段式,效率确实提升了2个百分点,但电机噪声也变大了。后来跟客户商量,还是换回了七段式。嗯,这就是工程上的取舍。
下面这张图展示了七段式SVPWM在一个周期内的波形结构:
从图上可以清楚看到,七段式波形关于中心对称。A相在中间时刻切换,B相和C相依次错开。这种对称性让电流纹波最小,谐波性能最好。
3.5 实际代码实现
最后,我给大家贴一段实际工程中用的代码。这是基于STM32的SVPWM实现片段,重点看时间计算和零矢量分配的部分:
// 扇区判断结果:sector = 1~6
// Ualpha, Ubeta 为归一化后的电压分量 [-1, 1]
// Ts 为开关周期(us)
// Vdc 为母线电压(V)
float K = 1.732f * Ts / Vdc; // sqrt(3) ≈ 1.732
// 根据扇区计算T1, T2
switch(sector) {
case 1:
T1 = K * (0.866f * Ualpha - 0.5f * Ubeta);
T2 = K * Ubeta;
break;
case 2:
T1 = K * (-0.866f * Ualpha - 0.5f * Ubeta);
T2 = K * (0.866f * Ualpha - 0.5f * Ubeta);
break;
// ... 其他扇区类似
}
// 过调制处理
if (T1 + T2 > Ts) {
float scale = Ts / (T1 + T2);
T1 *= scale;
T2 *= scale;
}
// 零矢量分配(对称分配)
float T0 = Ts - T1 - T2;
float T0_half = T0 * 0.5f;
// 计算三相占空比(第I扇区为例)
float Ta = T0_half;
float Tb = T0_half + T1;
float Tc = T0_half + T1 + T2;
// 写入定时器比较寄存器
TIM1->CCR1 = (uint16_t)(Ta * TIM1_PERIOD / Ts);
TIM1->CCR2 = (uint16_t)(Tb * TIM1_PERIOD / Ts);
TIM1->CCR3 = (uint16_t)(Tc * TIM1_PERIOD / Ts);