3、扇区判断的快速算法:无需查表,用纯逻辑运算判断参考电压矢量所在扇区
好,咱们接着聊SVPWM的核心环节——扇区判断。
很多教材里会给你一张大表,列出Uα、Uβ的各种组合,然后让你查表。我个人不太喜欢这种做法。查表虽然直观,但在DSP里跑起来,总感觉不够干脆。你想想看,每次都要去内存里翻一遍,多浪费那几个时钟周期?
我在做第一个电机驱动项目时,就吃过这个亏。当时用的DSP主频不高,查表法加上中断处理,整个PWM刷新周期差点没跑过来。后来我痛定思痛,换成了纯逻辑运算。嗯,效果立竿见影。
3.1 扇区划分的物理意义
先回顾一下。SVPWM把空间分成了6个扇区,每个扇区60度。参考电压矢量Vref落在哪个扇区,我们就用哪两个相邻的非零矢量去合成它。
说白了,扇区判断就是回答一个问题:Vref现在到底在哪个60度区间里?
传统的做法是计算Vref的角度θ,然后看θ落在0~60°、60°~120°……还是300°~360°。这需要调用反正切函数,计算量很大。我建议你忘掉这条路。
3.2 快速判断的核心思想
我们不需要知道精确的角度。只需要知道Vref在αβ坐标系下的三个变量:Uα、Uβ,以及它们的线性组合。
这里引入三个中间变量,我习惯叫它们A、B、C:
// 定义三个参考量
U1 = Uβ
U2 = (√3/2)*Uα - (1/2)*Uβ
U3 = -(√3/2)*Uα - (1/2)*Uβ
然后,根据这三个量的符号(正或负),就能唯一确定扇区。具体规则如下:
- 如果U1 > 0,则A = 1,否则A = 0
- 如果U2 > 0,则B = 1,否则B = 0
- 如果U3 > 0,则C = 1,否则C = 0
最后,扇区号N = A + 2*B + 4*C。
你看,全是加减法和比较,没有查表,没有三角函数。DSP执行起来飞快。
核心公式:扇区号 N = sign(Uβ) + 2*sign(√3/2*Uα - 1/2*Uβ) + 4*sign(-√3/2*Uα - 1/2*Uβ)
其中sign(x)在x>0时返回1,否则返回0。
3.3 为什么这样能行?
你可能会问:这三个式子是怎么来的?
其实很简单。我们把αβ坐标系旋转一下,得到三个相差120°的轴线。U1、U2、U3就是Vref在这三条轴线上的投影。每个投影的正负,就对应着Vref是否落在这个轴线所划分的半平面内。
三个半平面一交集,正好把整个平面切成6个三角形区域。每个区域对应一个扇区。
我曾经在调试时遇到过一个问题:当Uβ刚好等于0时,符号判断会变得很敏感。这时候,我建议你加一个很小的死区阈值,比如1e-6,避免在零附近来回跳变。
小技巧:在DSP里实现时,可以用移位代替乘法。比如√3/2 ≈ 0.866,可以近似为 887/1024。这样乘法就变成了移位加加法,速度更快。
3.4 代码实现示例
下面是一段典型的DSP C代码,展示了如何用纯逻辑运算完成扇区判断:
// 输入:Ualpha, Ubeta (Q15格式)
// 输出:扇区号 (1~6)
int calcSector(int Ualpha, int Ubeta)
{
int sector = 0;
int U1, U2, U3;
int A, B, C;
// 计算三个参考量
U1 = Ubeta;
U2 = (int)( (long)Ualpha * 0.8660254f - (long)Ubeta * 0.5f ); // 实际用Q15定点
U3 = (int)( (long)(-Ualpha) * 0.8660254f - (long)Ubeta * 0.5f );
// 符号判断
A = (U1 > 0) ? 1 : 0;
B = (U2 > 0) ? 1 : 0;
C = (U3 > 0) ? 1 : 0;
// 合成扇区号
sector = A + (B << 1) + (C << 2); // 等价于 A + 2*B + 4*C
return sector;
}
这段代码里,我用了移位操作来替代乘法,这是DSP优化的常用手法。你如果仔细看,会发现连除法都没有,全是加减和移位。
注意:上面的代码用了浮点常数0.8660254f。在实际嵌入式项目中,一定要转成定点数。否则DSP的浮点运算会拖慢速度。我一般用Q15格式,把0.866表示为 0x6ED9。
3.5 扇区与N值的对应关系
计算出的N值(1~6)与扇区号的对应关系如下表。这个表你最好背下来,或者固化在代码里:
| N值 | 扇区号 | 角度范围 |
|---|---|---|
| 1 | 扇区II | 60° ~ 120° |
| 2 | 扇区VI | 300° ~ 360° |
| 3 | 扇区I | 0° ~ 60° |
| 4 | 扇区IV | 180° ~ 240° |
| 5 | 扇区III | 120° ~ 180° |
| 6 | 扇区V | 240° ~ 300° |
这个映射关系不是唯一的,不同文献可能略有差异。但只要你保持内部一致,就没问题。我个人习惯用上面这个表,因为它在后续计算作用时间时,索引起来比较顺手。
3.6 流程图:扇区判断的完整逻辑
下面我用一张SVG图,把整个判断流程串起来。你看一眼就能明白:
这张图把整个流程浓缩成了5个步骤。你写代码时,就按这个顺序来,保证不会乱。
3.7 避坑指南
最后,分享几个我踩过的坑:
- 符号判断的边界处理:我曾经在Uβ刚好为0时,因为符号判断不一致,导致扇区在边界处来回跳变。解决方案是加一个滞环比较,或者直接忽略零值附近的微小波动。
- 定点数精度:用Q15格式时,√3/2的近似值0x6ED9其实有千分之一的误差。在高速电机控制中,这个误差会导致电流谐波。我后来改用Q24格式,精度才够用。
- 不要用除法:有些教材里会教你用Uβ/Uα的比值来判断。千万别这么干!除法在DSP里太慢了,而且当Uα接近0时会溢出。
好了,扇区判断这块就讲到这里。记住:能用逻辑运算解决的,就别用查表。这是嵌入式优化的第一原则。
公众号:蓝海资料掘金营,微信deep3321