3. SVPWM基本原理:电压矢量的合成与分解、扇区判断、作用时间计算、基本电压矢量与零矢量的分配
好,咱们进入正题。SVPWM,全称是Space Vector Pulse Width Modulation,空间矢量脉宽调制。说白了,它跟传统的SPWM(正弦脉宽调制)思路不太一样。SPWM是让三相分别跟正弦波比较,生成PWM波。而SVPWM呢,是从电机整体的角度出发,把三相电压看成一个合成的空间旋转矢量。
我刚开始接触FOC时,也困惑过:为什么要搞这么复杂?后来在调试一个低速大扭矩的伺服项目时,发现SPWM的电压利用率就是上不去,电机嗡嗡响,力矩还抖。换成SVPWM后,母线电压利用率直接提升了15%,噪音也小了很多。从那以后,我就再也没用过SPWM做FOC了。
3.1 从三相到两相:Clark变换与电压矢量
咱们先回顾一下。FOC的核心是把三相电流Ia, Ib, Ic通过Clark变换,变成两相静止坐标系下的Iα, Iβ。电压也一样。逆变器输出的三相电压Va, Vb, Vc,经过Clark变换,就得到了Vα, Vβ。
这个Vα, Vβ合在一起,就是一个空间电压矢量Vref。它的幅值和角度,就代表了当前时刻我们想让电机定子绕组感受到的电压状态。
核心思想: SVPWM的本质,就是通过控制六个功率管(IGBT或MOSFET)的开关组合,在每一个PWM周期内,用相邻的两个基本电压矢量和零矢量,去“拼凑”出我们想要的任意方向、任意大小的Vref。
3.2 六个基本电压矢量与两个零矢量
一个典型的三相两电平逆变器,有6个开关管。为了防止直通,同一桥臂的上下管不能同时导通。所以,一共有2³ = 8种开关状态。
这8种状态里,有6种是“非零”状态,它们会在电机绕组上产生一个固定的空间电压矢量。另外2种是“零”状态,要么上三管全通,要么下三管全通,电机绕组被短路,电压矢量为0。
这6个非零矢量,把整个360°平面均匀分成了6个扇区,每个扇区60°。我习惯把扇区编号为I、II、III、IV、V、VI。
| 开关状态 (A B C) | 基本电压矢量 | 矢量幅值 | 矢量角度 |
|---|---|---|---|
| 100 | V1 | 2/3 Vdc | 0° |
| 110 | V2 | 2/3 Vdc | 60° |
| 010 | V3 | 2/3 Vdc | 120° |
| 011 | V4 | 2/3 Vdc | 180° |
| 001 | V5 | 2/3 Vdc | 240° |
| 101 | V6 | 2/3 Vdc | 300° |
| 000 / 111 | V0 / V7 | 0 | 无 |
我的小习惯: 记这6个矢量不用死记硬背。你只要记住“100”是V1,角度0°,然后按二进制顺序逆时针转就行。100 -> 110 -> 010 -> 011 -> 001 -> 101。这样在写代码时,查表也方便。
3.3 扇区判断:Vref落在哪?
现在,我们有了目标矢量Vref(Vα, Vβ)。第一步,就是判断它落在哪个扇区里。这就像打靶,先得知道目标在哪个方向。
判断方法有很多,我推荐一种最常用的、基于Vα, Vβ符号和大小关系的算法。它不需要查表,计算量小,非常适合在嵌入式MCU里跑。
我们定义三个中间变量:
B1 = Vβ
B2 = (√3/2) * Vα - (1/2) * Vβ
B3 = -(√3/2) * Vα - (1/2) * Vβ
然后,根据这三个变量的符号,就能算出扇区号:
N = 4 * sign(B3) + 2 * sign(B2) + 1 * sign(B1)
其中,sign(x) 如果 x > 0 返回1,否则返回0。
最后,通过一个简单的映射表,就能得到扇区号:
| N 值 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| 扇区 | II | VI | I | IV | III | V |
我曾经踩过的坑: 在定点DSP上实现时,忘了处理Vβ为0的边界情况。结果电机在过零时,扇区判断会来回跳,导致电流波形出现毛刺。后来我加了一个很小的死区(比如0.001),问题就解决了。边界条件一定要小心!
3.4 作用时间计算:T1, T2, T0
知道扇区后,就好办了。假设Vref落在扇区I,它由相邻的基本矢量V1(100)和V2(110)合成。根据“伏秒平衡”原理:
Vref * Ts = V1 * T1 + V2 * T2 + V0 * T0
其中,Ts是PWM周期,T1和T2是两个基本矢量的作用时间,T0是零矢量的作用时间。
把V1, V2, Vref都投影到α-β坐标系下,解这个方程组,就能得到T1和T2。不同扇区的计算公式略有不同,但可以统一成一套公式。
我一般先计算三个通用变量 X, Y, Z:
X = (√3 * Vβ * Ts) / Vdc
Y = ( (3/2)*Vα + (√3/2)*Vβ ) * Ts / Vdc
Z = ( -(3/2)*Vα + (√3/2)*Vβ ) * Ts / Vdc
然后,根据扇区号查表得到 T1 和 T2:
| 扇区 | T1 | T2 |
|---|---|---|
| I | Z | Y |
| II | Y | -X |
| III | -Z | X |
| IV | -X | Z |
| V | X | -Y |
| VI | -Y | -Z |
最后,别忘了做饱和处理。如果 T1 + T2 > Ts,说明Vref已经超出了逆变器能输出的最大电压(进入了过调制区)。这时候需要等比例缩小:
T1_sat = T1 * Ts / (T1 + T2)
T2_sat = T2 * Ts / (T1 + T2)
T0 = 0
否则,T0 = Ts - T1 - T2。
3.5 矢量分配:七段式与五段式
时间算出来了,怎么分配给各个开关管呢?这就涉及到矢量分配策略。最常用的是七段式SVPWM和五段式SVPWM。
七段式:在一个PWM周期内,开关序列以零矢量开始和结束,中间插入两个非零矢量。比如在扇区I,序列是:000 -> 100 -> 110 -> 111 -> 110 -> 100 -> 000。这样每次切换只改变一个桥臂的状态,开关损耗较小,谐波也小。我大部分项目都用这个。
五段式:只使用一个零矢量,序列是:000 -> 100 -> 110 -> 100 -> 000。开关次数少了1/3,开关损耗更低,但谐波会大一些。适合对效率要求极高、对噪音不敏感的场合。
我个人习惯,在通用伺服驱动器里,默认用七段式。只有在做超高速电机(比如10万转以上的主轴)时,才会考虑五段式来降低开关损耗。
3.6 知识体系总览
说了这么多,你可能有点晕。没关系,我画了一张图,把整个SVPWM的流程串起来。你一看就明白了。
嗯,这张图把整个流程串起来了。从Vα, Vβ输入,到最终输出PWM占空比,每一步都清清楚楚。你写代码时,就按这个流程来,保证不会乱。