4. SVPWM 基本原理:空间电压矢量合成、扇区判断、作用时间计算与调制波生成
好,咱们今天来啃 SVPWM 这块硬骨头。说实话,我刚接触 FOC 那会儿,觉得 SVPWM 就是一堆公式和扇区判断,特别绕。后来在项目里调了好几个月的电机,才真正摸透它的脾气。你想想看,FOC 的核心是控制电流矢量,但逆变器只能输出 6 个离散的开关状态,怎么用这些离散状态去模拟一个连续旋转的电压矢量?这就是 SVPWM 要干的事。
4.1 从三相逆变器到空间电压矢量
先看硬件基础。一个典型的三相两电平逆变器,有 6 个开关管。同一桥臂上下不能直通,所以每一相只有两种状态:上管导通(定义为 1)或下管导通(定义为 0)。
三相组合起来,一共 2³ = 8 种状态。其中 6 种是非零矢量,2 种是零矢量(000 和 111)。
核心概念:这 8 种开关状态对应 8 个空间电压矢量。6 个非零矢量在空间上相隔 60°,把整个平面分成 6 个扇区。零矢量位于原点。
每个非零矢量的幅值都是 2/3 Vdc(直流母线电压)。为什么是 2/3?这个推导我建议你去看 Clarke 变换的等幅值变换形式,这里不展开。你只要记住,这 6 个矢量是固定的,但我们要合成的目标矢量是任意方向和幅值的。
4.2 矢量合成与扇区判断
怎么用这 6 个固定的矢量去合成任意矢量?说白了,就是「伏秒平衡」原理。在一个 PWM 周期内,用相邻的两个非零矢量分别作用一段时间,再插入零矢量填满整个周期,让平均效果等于目标矢量。
举个例子,目标矢量 Uref 落在扇区 I(0°~60°)。那就用 U4(100)和 U6(110)来合成。U4 作用 T4 时间,U6 作用 T6 时间,剩下的时间用零矢量填充。
第一步,得先判断目标矢量在哪个扇区。我见过不少新手在这里用角度查表法,其实没必要。直接用 Uα 和 Uβ 的符号关系就能判断。
我的判断方法:定义三个中间变量:
- B1 = Uβ
- B2 = √3/2 * Uα - 1/2 * Uβ
- B3 = -√3/2 * Uα - 1/2 * Uβ
然后算 N = 4*sign(B3) + 2*sign(B2) + sign(B1)。N 值 1~6 直接对应扇区 I~VI。这个办法我在 STM32 上跑过,一个 if-else 都不用,纯数学运算,快得很。
4.3 作用时间计算
扇区判断完了,就该算两个非零矢量的作用时间了。还是以扇区 I 为例,根据伏秒平衡:
Uref * Ts = U4 * T4 + U6 * T6 + U0 * T0
其中 Ts 是 PWM 周期。把 U4 和 U6 的矢量表达式代进去,解方程,得到:
T4 = (√3 * Ts / Vdc) * (√3/2 * Uα - 1/2 * Uβ)
T6 = (√3 * Ts / Vdc) * Uβ
看着眼熟吗?B2 和 B1 又出现了。所以实际工程里,我们一般先算三个通用变量 X、Y、Z:
| 变量 | 表达式 |
|---|---|
| X | √3 * Uβ * Ts / Vdc |
| Y | (√3/2 * Uβ + 3/2 * Uα) * Ts / Vdc |
| Z | (√3/2 * Uβ - 3/2 * Uα) * 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,说明目标矢量超出了六边形内切圆,进入了过调制区。这时候需要等比例缩小:
T1 = T1 * Ts / (T1 + T2)
T2 = T2 * Ts / (T1 + T2)
我曾经在一个项目里忘了做这个处理,结果电机在高速时电流波形畸变得厉害,找了三天才找到原因。
4.4 调制波生成与七段式 SVPWM
时间算好了,怎么生成 PWM 波形?常用的有两种方式:五段式和七段式。七段式谐波含量更低,我一般都用它。
七段式的思路是:每个 PWM 周期内,从零矢量(000)开始,切换到第一个非零矢量,再切换到第二个非零矢量,然后到零矢量(111),再对称地切回来。这样每个周期有 7 段,开关次数均匀,谐波小。
具体实现时,先算三个比较值:
Ta = (Ts - T1 - T2) / 4
Tb = Ta + T1 / 2
Tc = Tb + T2 / 2
然后根据扇区,把 Ta、Tb、Tc 分配给三相的比较寄存器:
| 扇区 | A 相比校值 | B 相比校值 | C 相比校值 |
|---|---|---|---|
| I | Ta | Tb | Tc |
| II | Tb | Ta | Tc |
| III | Tc | Ta | Tb |
| IV | Tc | Tb | Ta |
| V | Tb | Tc | Ta |
| VI | Ta | Tc | Tb |
把这些比较值写入定时器的 CCR 寄存器,硬件自动生成 PWM 波。嗯,到这里,SVPWM 的软件流程就走完了。
4.5 SVPWM 知识体系总览
下面这张图是我自己整理的 SVPWM 知识框架,从硬件到软件,从理论到实现,一目了然。
4.6 工程实现要点
最后聊几个我在实际项目中踩过的坑:
- PWM 频率选择:我一般选 10kHz~20kHz。太低了电流纹波大,太高了开关损耗大。对于大部分电机,16kHz 是个不错的折中。
- 死区时间:同一桥臂上下管切换时,必须插入死区。我习惯设 1~2μs,具体看 IGBT 或 MOSFET 的关断延迟。
- ADC 采样同步:电流采样要在 PWM 周期的中间点触发,这时候开关噪声最小。我都是用定时器的 TRGO 事件来触发 ADC,硬件同步,不用软件干预。
- 浮点运算优化:如果 MCU 没有 FPU,建议把 SVPWM 里的 √3 和 1/2 这些系数提前算好,用定点数做。我在一个 Cortex-M0 项目里就这么干过,把整个计算时间从 15μs 压到了 3μs。
我的调试习惯:先用开环方式给电机发一个固定的电压矢量,看电机能不能转到指定位置。能转,说明 SVPWM 的扇区判断和时间计算基本对了。然后再切到闭环。这样一步步来,出问题了也好定位。