3. 基本矢量作用时间:计算相邻非零矢量与零矢量的作用时间 Tx、Ty、T0
好,我们接着往下走。上一节我们把扇区判断搞定了,知道了目标电压矢量落在哪个 60° 扇区里。那接下来要干什么?说白了,就是算一算:在这个扇区里,两个相邻的非零矢量各作用多久,零矢量又该插进去多久。
这个计算,是整个 SVPWM 的核心。我当年刚入行的时候,照着公式抄都能抄错,后来发现是自己对「伏秒平衡」的理解还停留在表面。你想想看,我们最终要输出的 PWM 波,其实就是用这几个基本矢量的作用时间,拼出一个平均值等于目标矢量的效果。
3.1 伏秒平衡原则
先把这个原则说清楚。SVPWM 的基本思想,就是在一个 PWM 周期 Ts 内,用相邻的两个非零矢量 Ux、Uy 和零矢量 U0(或 U7)来合成目标矢量 Uref。
数学表达就是:
Uref * Ts = Ux * Tx + Uy * Ty + U0 * T0
其中:
Tx:第一个相邻非零矢量的作用时间Ty:第二个相邻非零矢量的作用时间T0:零矢量的作用时间Ts = Tx + Ty + T0
这个公式看着简单,但物理含义很深。它说的是:电压矢量对时间的积分相等。我在调试一个 7.5kW 伺服驱动器时,遇到过电流波形畸变,查到最后发现是 Tx + Ty 超过了 Ts,导致过调制,伏秒平衡被打破了。嗯,从那以后我每次算完都会检查一下这个和。
3.2 在 αβ 坐标系下推导 Tx、Ty
我们以扇区 I 为例(U4(100) 和 U6(110) 之间)。把目标矢量 Uref 投影到 αβ 轴上,然后根据两个基本矢量的方向,列出方程组。
设 U4 的方向为 α 轴,U6 的方向与 α 轴夹角 60°。那么:
Uα = |U4| * Tx/Ts + |U6| * cos(60°) * Ty/Ts
Uβ = 0 + |U6| * sin(60°) * Ty/Ts
其中 |U4| = |U6| = 2/3 * Udc(这是基本矢量幅值)。代入并化简,得到:
Tx = (sqrt(3) * Ts / Udc) * (sqrt(3)/2 * Uα - 1/2 * Uβ)
Ty = (sqrt(3) * Ts / Udc) * Uβ
我个人习惯把系数 sqrt(3) * Ts / Udc 提出来,后面括号里的东西其实就是扇区判断时用到的中间变量 X、Y、Z 的某种组合。这样写代码的时候,复用性很高。
3.3 通用计算公式:X、Y、Z 中间变量
为了避免每个扇区都重新推导,业界通用的做法是先算三个中间变量:
X = sqrt(3) * Ts / Udc * Uβ
Y = sqrt(3) * Ts / Udc * (sqrt(3)/2 * Uα + 1/2 * Uβ)
Z = sqrt(3) * Ts / Udc * (-sqrt(3)/2 * Uα + 1/2 * Uβ)
然后根据扇区号,直接查表得到 Tx 和 Ty:
| 扇区 | Tx | Ty |
|---|---|---|
| I (1) | -Z | X |
| II (2) | Z | Y |
| III (3) | X | -Y |
| IV (4) | -X | Z |
| V (5) | -Y | -Z |
| VI (6) | Y | -X |
3.4 零矢量作用时间 T0 与过调制处理
零矢量的作用时间很简单:
T0 = Ts - Tx - Ty
但是!这里有个坑。当 Tx + Ty > Ts 时,说明目标电压矢量已经超出了六边形的内切圆,进入了过调制区。这时候 T0 会变成负数,物理上不可能实现。
T0 算出来是负的,PWM 比较器直接饱和,电机电流瞬间飙到过流值。后来我加了一段饱和处理,把 Tx 和 Ty 按比例缩放到 Ts 以内,问题就解决了。
过调制时的处理方式:
if (Tx + Ty > Ts) {
scale = Ts / (Tx + Ty);
Tx = Tx * scale;
Ty = Ty * scale;
T0 = 0;
} else {
T0 = Ts - Tx - Ty;
}
这样处理后,虽然输出电压会略低于目标值,但至少系统不会崩溃。你想想看,在工程上,稳定比精确更重要。
3.5 知识体系流程图
下面这张图,把整个计算流程串起来了。从 αβ 轴电压开始,到最终输出 Tx、Ty、T0,每一步都很清楚。
3.6 代码实现示例
最后,给出一段 C 语言的实现。这段代码我用了很多年,结构清晰,适合移植到 DSP 或 MCU 上。
// 输入:Ualpha, Ubeta, Udc, Ts
// 输出:Tx, Ty, T0
// 扇区号已在之前计算好,存储在 sector 中
float X, Y, Z;
float Tx, Ty, T0;
float scale;
// 1. 计算中间变量
X = 1.732f * Ts / Udc * Ubeta;
Y = 1.732f * Ts / Udc * (0.866f * Ualpha + 0.5f * Ubeta);
Z = 1.732f * Ts / Udc * (-0.866f * Ualpha + 0.5f * Ubeta);
// 2. 查表得到 Tx, Ty
switch(sector) {
case 1: Tx = -Z; Ty = X; break;
case 2: Tx = Z; Ty = Y; break;
case 3: Tx = X; Ty = -Y; break;
case 4: Tx = -X; Ty = Z; break;
case 5: Tx = -Y; Ty = -Z; break;
case 6: Tx = Y; Ty = -X; break;
default: Tx = 0; Ty = 0; break;
}
// 3. 过调制处理
if (Tx + Ty > Ts) {
scale = Ts / (Tx + Ty);
Tx *= scale;
Ty *= scale;
T0 = 0.0f;
} else {
T0 = Ts - Tx - Ty;
}
- 伏秒平衡是 SVPWM 的根基,
Uref * Ts = Ux * Tx + Uy * Ty + U0 * T0 - 中间变量 X、Y、Z 可以复用扇区判断时的计算结果,减少运算量
- 过调制处理是工程必备,不做的话系统会出大问题
T0的分配方式(是全部用U0还是U7,或者各一半)会影响谐波,这个我们后面再聊