第四节 过调制I区原理:保持矢量角度不变,仅调整幅值,最小相角误差原则

好,咱们今天聊点硬核的。过调制I区,说白了就是SVPWM从线性区往六边形边界走的第一步。很多教材喜欢一上来就扔公式,我换个方式讲——你想象一下,你手里有个矢量,它想往外跑,但六边形边界拦着它。怎么办?

我个人的习惯是,先理解物理意义,再去看数学推导。过调制I区的核心思想其实就一句话:保持矢量角度不变,只砍幅值。听起来简单吧?但这里面的门道可不少。

4.1 为什么非要保持角度不变?

你想想看,电机控制里我们最关心什么?转矩和磁链。转矩跟电流的幅值有关,磁链跟电流的相位有关。如果你把角度也改了,那磁链方向就偏了,电机可能就抖起来了。

我在项目里遇到过这种情况:一开始做弱磁控制,过调制没处理好,结果电机高速运行时噪声特别大。后来一查,就是过调制I区里角度没锁住,导致磁链波动。嗯,从那以后我对这个原则就特别敏感。

所以过调制I区的第一条铁律就是:角度不变,只调幅值。这样磁链方向是稳定的,转矩响应也不会乱跳。

4.2 最小相角误差原则是什么?

好,现在问题来了。参考电压矢量 Vref 落在六边形外面了,我们得把它拉回来。怎么拉?沿着原来的方向,直接缩到六边形边界上。这就是最小相角误差原则——说白了,就是让实际输出的矢量跟参考矢量的方向尽可能一致,误差只体现在幅值上。

我画个图帮你理解一下:

Vref Vout θ U1(100) U2(110) U3(010) U4(011) U5(001) U6(101) 参考矢量 实际输出 图4-1 过调制I区矢量合成示意图

看到没?红色虚线是参考矢量,绿色实线是实际输出。角度θ完全一样,只是长度变短了。这就是最小相角误差原则的几何解释。

4.3 数学上怎么算?

好,咱们来点实际的。假设参考矢量在αβ坐标系下是 (Vα, Vβ),幅值是 Vref,角度是 θ。那过调制I区的输出就是:

// 伪代码:过调制I区实现
if (Vref > Vmax) {
    // 计算当前扇区
    sector = getSector(Vα, Vβ);
    
    // 找到六边形边界上的交点
    // 这个交点就是沿着角度θ方向与六边形的交点
    Vout_α = Vmax * cos(θ);
    Vout_β = Vmax * sin(θ);
    
    // 但注意!Vmax不是固定的,它跟角度有关
    // 在六边形边界上,Vmax = Vdc / sqrt(3) / cos(π/6 - θ_mod)
    // 其中θ_mod是角度在扇区内的偏移量
}

这里有个坑,我当年踩过。Vmax不是常数!在六边形边界上,不同角度的最大幅值是不一样的。你想想看,六边形六个顶点离原点最远,而边的中点离原点最近。所以Vmax其实是角度的函数。

关键公式:

在过调制I区,实际输出电压幅值为:

Vout = Vdc / √3 / cos(π/6 - θ_mod)

其中θ_mod是参考矢量在扇区内的相对角度,范围是[-π/6, π/6]

4.4 实际实现时的注意事项

我个人做项目时,一般把过调制I区的实现分成三步:

  1. 判断是否进入过调制:比较Vref和六边形内切圆半径Vdc/√3。如果Vref大于这个值,就进入过调制区。
  2. 计算限幅后的幅值:根据当前角度,查表或者直接计算六边形边界上的幅值。
  3. 重新合成矢量:用限幅后的幅值和原来的角度,重新计算占空比。

我的小技巧:

如果你用查表法,建议把角度分辨率做到0.5度以内。我之前用1度分辨率,结果电机在高速区有轻微的转矩脉动。后来改成0.25度,问题就解决了。当然,这跟你的PWM频率和电机参数也有关系,具体可以自己调调看。

4.5 过调制I区的局限性

说实话,过调制I区能提升的电压利用率有限。从线性区的0.577Vdc,到I区最高能到0.637Vdc,也就提升了10%左右。如果你需要更高的电压利用率,那就得进过调制II区了——那个咱们下一节再聊。

但I区有个好处:谐波小。因为只调幅值不调角度,输出电压的谐波含量相对较低。我在做伺服驱动器时,如果客户对噪声要求高,我一般就只用到I区,不去碰II区。

注意:

过调制I区虽然谐波小,但也不是完全没有谐波。当参考矢量在六边形边界上移动时,输出电压的波形会从正弦波变成马鞍波。这个变化本身就会引入低次谐波。如果你的应用对谐波特别敏感(比如音频设备),建议还是留点裕量,别进过调制。

4.6 一个简单的实现示例

最后,给你一个C语言风格的实现片段。这个代码我在STM32F4上跑过,效果还不错:

// 过调制I区处理函数
// 输入:Vα, Vβ (参考电压)
// 输出:Vα_lim, Vβ_lim (限幅后的电压)
void Overmodulation_ZoneI(float Vα, float Vβ, float *Vα_lim, float *Vβ_lim) {
    float Vref = sqrtf(Vα*Vα + Vβ*Vβ);
    float Vdc = 310.0f;  // 母线电压,单位V
    float Vlin = Vdc / 1.732f;  // 线性区最大幅值
    
    if (Vref <= Vlin) {
        // 线性区,直接输出
        *Vα_lim = Vα;
        *Vβ_lim = Vβ;
        return;
    }
    
    // 计算角度
    float theta = atan2f(Vβ, Vα);
    
    // 计算扇区内的相对角度
    float theta_mod = fmodf(theta + PI/6, PI/3) - PI/6;
    
    // 计算六边形边界上的最大幅值
    float Vmax = Vdc / 1.732f / cosf(PI/6 - fabsf(theta_mod));
    
    // 限幅
    float scale = Vmax / Vref;
    *Vα_lim = Vα * scale;
    *Vβ_lim = Vβ * scale;
}

这段代码看起来简单,但有几个细节要注意:

  • fmodf处理角度时要小心负值,我建议先加π/6再取模
  • cosf的参数范围是[0, π/3],在这个区间内cos是单调递减的,没问题
  • 如果Vref比Vmax还大(理论上不会,但浮点运算可能有误差),建议再加一层保护

好了,过调制I区的内容就这些。记住核心:角度不变,幅值压缩,最小相角误差。这个原则贯穿整个过调制I区,你理解透了,后面的II区就好办了。


公众号:蓝海资料掘金营,微信deep3321