4. SVPWM扇区判断:扇区划分原理、扇区判断算法、基于电压分量的扇区判定
各位工程师朋友,欢迎来到SVPWM的第四讲。前面我们聊了电压矢量的合成原理,也讲了如何用六个基本矢量去逼近一个旋转的参考矢量。但有个问题一直悬着:我怎么知道当前要合成的参考电压矢量落在哪个扇区?
这个问题不解决,后面的矢量作用时间计算就无从谈起。今天我们就来彻底搞定它。
4.1 扇区划分的底层逻辑
先看一张图,这是我个人习惯用的扇区划分方式——按空间角度每60°一个扇区,逆时针编号I~VI。
核心要点:扇区划分的本质,就是把360°的电压矢量空间切成6块,每块对应一对基本矢量的合成区域。
你看,六个基本矢量把平面分成六个60°的扇形区域。每个扇区内的任意参考矢量,都可以用该扇区边界的两个基本矢量来合成。比如扇区I,就是用V₁(100)和V₂(110)来合成。
这里有个细节我提醒一下:扇区边界本身也是基本矢量的方向。如果参考矢量正好落在边界上,那就只用两个矢量中的一个,另一个作用时间为零。这种情况在实际控制中很少见,但做算法时要考虑到。
4.2 扇区判断的数学原理
好了,扇区画出来了。现在的问题是:给定一个参考电压矢量Vref,我怎么知道它在哪个扇区?
最直观的方法是用角度。算出Vref与α轴的夹角θ,然后看θ落在哪个区间:
| 扇区 | 角度范围 | 对应基本矢量 |
|---|---|---|
| I | 0° ≤ θ < 60° | V₁(100), V₂(110) |
| II | 60° ≤ θ < 120° | V₂(110), V₃(010) |
| III | 120° ≤ θ < 180° | V₃(010), V₄(011) |
| IV | 180° ≤ θ < 240° | V₄(011), V₅(001) |
| V | 240° ≤ θ < 300° | V₅(001), V₆(101) |
| VI | 300° ≤ θ < 360° | V₆(101), V₁(100) |
这个方法理论上没问题,但实际工程中我基本不用。为什么?因为要算反正切函数,计算量大,而且角度判断还有边界模糊的问题。
我的经验:在DSP或MCU里,反正切函数通常要几十个指令周期。如果PWM频率是10kHz,每个周期都要算一次,CPU开销不小。更关键的是,角度法对电压采样噪声敏感——采样抖动一下,角度跳变,扇区判断就可能出错。
4.3 基于电压分量的扇区判定算法
那实际工程中用什么方法?用电压分量直接判断。这个方法不需要算角度,只需要比较Vα和Vβ的大小关系。
具体怎么做?我们先定义三个中间变量:
// 定义三个判定变量
V_a = V_beta
V_b = (sqrt(3)/2) * V_alpha - (1/2) * V_beta
V_c = -(sqrt(3)/2) * V_alpha - (1/2) * V_beta
然后根据这三个变量的符号,就能唯一确定扇区。判断规则如下:
| V_a 符号 | V_b 符号 | V_c 符号 | 扇区编号 |
|---|---|---|---|
| + | + | - | I |
| + | - | - | II |
| + | - | + | III |
| - | - | + | IV |
| - | + | + | V |
| - | + | - | VI |
你想想看,这个判断过程只需要比较和加减运算,没有三角函数,没有除法,计算量极小。在C代码里实现就是几条if语句的事。
算法优势:基于电压分量的扇区判定,计算量只有角度法的1/10左右,且对采样噪声的鲁棒性更好。
4.4 工程实现:C代码示例
下面是我在一个电机驱动项目里实际用过的代码片段。这个项目用的是STM32F4,PWM频率8kHz,电流环周期125μs。
// 扇区判断函数
// 输入: V_alpha, V_beta (标幺值)
// 输出: 扇区编号 1~6
int SVPWM_CalcSector(float V_alpha, float V_beta)
{
float V_a, V_b, V_c;
int sector = 0;
// 计算三个判定变量
V_a = V_beta;
V_b = 0.8660254f * V_alpha - 0.5f * V_beta; // sqrt(3)/2 ≈ 0.866
V_c = -0.8660254f * V_alpha - 0.5f * V_beta;
// 根据符号组合判断扇区
if (V_a > 0) sector = 1; // V_a为正,扇区在I/II/III
if (V_b > 0) sector |= 2; // V_b为正,扇区在I/V/VI
if (V_c > 0) sector |= 4; // V_c为正,扇区在III/IV/V
// 查表得到最终扇区编号
const int sector_map[8] = {0, 2, 6, 1, 4, 3, 5, 0};
return sector_map[sector];
}
我曾经踩过的坑:一开始我用的是角度法判断扇区,结果在电机低速运行时,电流采样噪声导致角度抖动,扇区频繁误判,电机噪音很大。后来换成电压分量法,问题立刻解决。所以我的建议是——能用电压分量法就别用角度法。
4.5 扇区判断的边界处理
实际运行中,参考矢量可能正好落在扇区边界上。比如Vβ = 0且Vα > 0时,矢量在0°方向,属于扇区I和扇区VI的边界。
这种情况下怎么处理?我的做法是:统一归到编号较小的扇区。比如0°边界归到扇区I,60°边界归到扇区II,以此类推。这样处理的好处是避免扇区在边界处来回跳变。
另外,当Vα和Vβ都很小(接近零矢量)时,扇区判断会变得不稳定。这时候我通常会加一个死区判断:如果Vref的幅值小于某个阈值,直接输出零矢量,不做扇区判断。
实用技巧:阈值一般取母线电压的1%~2%。比如母线电压300V,阈值设3~6V。这样既不影响正常调制,又能避免零矢量附近的误判。
4.6 本章小结
扇区判断是SVPWM的"入口"环节,判断错了后面全错。记住三个要点:
- 扇区划分:六个60°扇区,每个扇区用两个相邻基本矢量合成
- 判断方法:用Vα、Vβ计算三个判定变量,查符号表得到扇区
- 工程注意:边界统一归小扇区,零矢量附近加死区判断