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变换后的电压分量,单位是伏特。

我的小技巧: 实际代码里,我一般先把Uα和Uβ归一化到[-1, 1]区间,然后预计算K值。这样T1和T2的计算就变成了几个乘加运算,DSP或者MCU跑起来飞快。

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了。但代价是输出电压幅值会降低,波形会失真。嗯,这是没办法的事,物理极限摆在那里。

注意: 过调制时,零矢量时间T0 = Ts - T1 - T2会变成负数。所以一定要先做缩放,再算T0。顺序搞反了,代码就会出bug。

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在一个周期内的波形结构:

七段式SVPWM波形结构(第I扇区) 一个开关周期 Ts 0 T0/2 T0/2+T1 T0/2+T1+T2 T0/2+T1+T2+T7/2 Ts A相 B相 C相 V0 V1 V2 V7 V2 V1 对称分配:V0和V7各占一半零矢量时间,波形关于中心对称

从图上可以清楚看到,七段式波形关于中心对称。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);
避坑指南: 我曾经在代码里忘了做过调制判断,结果电机在高速区直接炸了MOS管。从那以后,我每次写SVPWM代码,第一件事就是加过调制保护。另外,注意浮点数精度问题,建议用Q格式定点数或者查表法来加速。