第四节 过调制I区原理:保持矢量角度不变,仅调整幅值,最小相角误差原则
好,咱们今天聊点硬核的。过调制I区,说白了就是SVPWM从线性区往六边形边界走的第一步。很多教材喜欢一上来就扔公式,我换个方式讲——你想象一下,你手里有个矢量,它想往外跑,但六边形边界拦着它。怎么办?
我个人的习惯是,先理解物理意义,再去看数学推导。过调制I区的核心思想其实就一句话:保持矢量角度不变,只砍幅值。听起来简单吧?但这里面的门道可不少。
4.1 为什么非要保持角度不变?
你想想看,电机控制里我们最关心什么?转矩和磁链。转矩跟电流的幅值有关,磁链跟电流的相位有关。如果你把角度也改了,那磁链方向就偏了,电机可能就抖起来了。
我在项目里遇到过这种情况:一开始做弱磁控制,过调制没处理好,结果电机高速运行时噪声特别大。后来一查,就是过调制I区里角度没锁住,导致磁链波动。嗯,从那以后我对这个原则就特别敏感。
所以过调制I区的第一条铁律就是:角度不变,只调幅值。这样磁链方向是稳定的,转矩响应也不会乱跳。
4.2 最小相角误差原则是什么?
好,现在问题来了。参考电压矢量 Vref 落在六边形外面了,我们得把它拉回来。怎么拉?沿着原来的方向,直接缩到六边形边界上。这就是最小相角误差原则——说白了,就是让实际输出的矢量跟参考矢量的方向尽可能一致,误差只体现在幅值上。
我画个图帮你理解一下:
看到没?红色虚线是参考矢量,绿色实线是实际输出。角度θ完全一样,只是长度变短了。这就是最小相角误差原则的几何解释。
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区的实现分成三步:
- 判断是否进入过调制:比较Vref和六边形内切圆半径Vdc/√3。如果Vref大于这个值,就进入过调制区。
- 计算限幅后的幅值:根据当前角度,查表或者直接计算六边形边界上的幅值。
- 重新合成矢量:用限幅后的幅值和原来的角度,重新计算占空比。
我的小技巧:
如果你用查表法,建议把角度分辨率做到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