有一次我在调一台永磁同步电机的FOC程序,电流环PI已经稳定了,转速波形也干净利落。我拿着示波器去测电机三相端子的电压,结果看到的不是教科书上那种正弦波,而是一个“顶”被削平的马鞍形波形。群里一个刚入门的同学很认真地问:“FOC最终要求的,到底是相电压还是线电压?桥臂上出来的根本不是正弦,是不是哪里搞错了?”
这个问题表面上只是个概念区分,实际上把FOC从算法到功率级的完整链路全部串起来了。我当时为了把话说清楚,不得不把SVPWM的调制过程、逆变器的物理输出、电机的绕组连接方式全部重新捋了一遍,才发现“相电压还是线电压”这个提问本身就藏着好几个容易被混淆的层级。这篇文章就把我当时的完整思考记录下来:FOC算法内部到底在控制什么电压,电机绕组最终承受的又是什么电压,以及为什么示波器上看到的“马鞍波”其实是正常工作状态。
1. 问题原点:电机端电压为什么不是“标准正弦波”
1.1 一次调试中的波形困惑
先还原一下当时的情景。电机空载运行在1500rpm,电流环带宽调到了800Hz左右,示波器接在电机U相端子和直流母线负极之间。把PWM高频开关分量滤掉之后,能看到一个低频包络,但这个包络看起来像正弦波被“压扁”了顶部和底部,更像一个马鞍,而不是教科书里画的平滑正弦曲线。
我当时的第一个念头也是“SVPWM是不是写错了”。但随后我测了另外两相,发现三相包络形状一样、相位互差120度,而且相电流波形确实是干净的正弦。合着电压波形“不对”,电流波形反而对?这个矛盾逼着我回头重新审视FOC输出电压的本质。
后来在调试群里的讨论逐渐聚焦到那个经典问题上:FOC最终要求的,到底是相电压,还是线电压?这个问题的答案不能拍脑袋给,因为它决定了你如何理解SVPWM的占空比计算、如何设置电流环输出限幅、以及如何解释你在示波器上看到的每一种波形。
1.2 FOC指令的完整传递链路
要回答这个问题,得先把FOC从算法到电机的一整条指令链捋清楚。一个典型的转速-电流双闭环FOC系统,信号是这样流动的:
- 速度环比较目标转速和实际转速,输出q轴电流指令 Iq_ref,d轴电流指令 Id_ref 通常设0(表贴式电机),或者按MTPA/弱磁策略给定;
- 电流环PI控制器比较Id_ref/Iq_ref和采样回来的Id/Iq,输出d轴电压指令 Vd 和 q轴电压指令 Vq;
- Vd、Vq经过反Park变换,变成静止αβ坐标系下的电压指令 Vα、Vβ;
- Vα、Vβ送入SVPWM模块,经过扇区判断、相邻矢量作用时间计算,最终得到三相桥臂的占空比;
- 占空比送入逆变器,控制六个功率管导通和关断,产生三相PWM电压;
- PWM电压施加到电机三相绕组,产生定子电流,进而产生电磁转矩。
这个链路里最微妙的地方在于:第2步输出的Vd、Vq,第3步得到的Vα、Vβ,和第4步SVPWM里的参考电压矢量,本质上是同一个物理量在不同坐标系下的表示。而第5步之后,真正加载在电机端子之间的电压,又经过了逆变器和绕组连接方式的“二次翻译”。所以“最终要求的是相电压还是线电压”,要看你在哪个环节问这个问题。
2. 三个电压概念先对齐:相电压、线电压、电压空间矢量
2.1 三相电路里的电压定义与换算关系
先把最基础的概念摆清楚,后面才不会绕晕。
相电压:某一相绕组端点相对中性点(或星形连接的中点)的电压。如果中性点不可及,通常指相对“虚拟中点”的电压。三相平衡时,相电压各相大小相等、相位互差120度。
线电压:任意两根相线之间的电压,也就是两个端点之间的电位差。线电压等于两个相电压之差,比如 Uab = Ua - Ub。三相平衡正弦系统中,线电压的幅值是相电压幅值的√3倍,相位超前对应的相电压30度。
这里有个特别容易混淆的点:线电压和相电压的√3倍关系,是在“对称三相正弦系统”下才成立的。如果你拿示波器去测桥臂输出对直流负极的电压,它既不是纯正的相电压波形,也不是线电压波形,因为它含有一个公共的零序分量——这个我们后面在SVPWM部分细说。
直流母线电压 Vdc:逆变器输入的直流电压,它决定了所有电压矢量的幅值边界。三相逆变器本质上是一个“电压源”性质的电路,桥臂输出的每次开关动作,要么把电机端接到+Vdc,要么接到0V(对直流负极),所以Vdc是所有电压计算的绝对标尺。
为了直观,我列了个对比表,把这三个电压的物理含义和相互之间的数量关系写清楚:
| 电压类型 | 测量方式 | 三相对称正弦时的幅值关系 |
|---|---|---|
| 相电压 | 端点对中性点(或虚拟中点) | 基波幅值设为 Uph |
| 线电压 | 任意两端点之间 | √3 × Uph |
| 桥臂对直流负极电压 | 端点对直流负极 | 含零序分量的马鞍波,基波幅值条件性等于Uph的调制结果 |
2.2 电机绕组实际承受的到底是哪个电压
大多数永磁同步电机和直流无刷电机都是星形连接,而且中性点通常不引出来。这意味着每相绕组的一端接逆变器桥臂,另一端和另外两相绕组短接在中性点。绕组两端实际承受的电压,是“这一相端点电压”减去“中性点电压”。
从物理端口来看,电流流过绕组的驱动力来自两端点之间的电位差,而这个电位差就是线电压。比如U相绕组两端的电压是 Va - Vn,其中Vn是中性点电位;而Vn由三相共同决定。如果三相完全对称且没有零序电流回路,中性点电位约等于三相端点电压的平均值,即 Vn = (Va+Vb+Vc)/3。
于是你会看到一种奇特的现象:算法模型里的相电压是一个纯正弦量,但物理上真正推动电流的电压差,却是两个端点电压的差,也就是线电压的组合。这也是为什么有些工程师会坚持说“电机绕组承受的是线电压”——从功率级物理上看,这个说法没错。
但从FOC的数学模型看,电机电压方程又确实是用相电压写的。这两者并不矛盾,因为三相相电压之间通过线电压唯一确定(三相无零序时),坐标变换把三相量变成一个整体来处理,线电压的信息完全包含在相电压合成矢量中,只是多了一个√3的幅值系数。
2.3 电压空间矢量:FOC真正“画”出来的东西
接下来是理解FOC最关键的概念:电压空间矢量。
三相相电压 ua、ub、uc 可以合成一个复平面上的旋转矢量,定义为:
us = (2/3) × (ua + a×ub + a²×uc)
其中 a = e^(j2π/3),是120度旋转因子。如果 ua、ub、uc 是三相对称正弦波,那么合成矢量 us 的幅值就是相电压的峰值,方向以电角速度旋转。
这个矢量的妙处在于:它把“三个标量电压”压缩成了一个矢量。而FOC的电流环PI算出的Vd、Vq经过反Park变换后得到的Vα、Vβ,恰好就是这个矢量在静止αβ坐标系下的两个分量。换句话说,FOC算法层从始至终在操作的对象,就是相电压空间矢量,而不是某个具体的线电压。
SVPWM的任务,就是在一个PWM开关周期内,用逆变器可输出的8种离散电压状态(6个有效矢量+2个零矢量),让输出矢量的时间平均值等于参考矢量 Vα + jVβ。这个过程不关心“某两相之间的电压差是多少”,它关心的是合成矢量的幅值和方向。
3. 从算法到功率级逐层看:算的是相电压,用的也是相电压
3.1 电流环输出的Vd、Vq是相电压的dq分量
回到最根源的电机模型。PMSM在dq旋转坐标系下的定子电压方程为:
Vd = Rs×Id + Ld×(dId/dt) - ωe×Lq×Iq
Vq = Rs×Iq + Lq×(dIq/dt) + ωe×(Ld×Id + ψf)
方程里的Vd、Vq,是定子绕组相电压经过Park变换后在dq轴上的分量。什么叫“相电压经过Park变换”?就是把三相端点对中性点的电压(ua、ub、uc)先做Clark变换得到uα、uβ,再做Park变换得到ud、uq。也就是说,电压方程从建立那天起,用的就是相电压,不是线电压。
在等幅值变换约定下,Vd、Vq合成矢量的幅值等于相电压峰值。这个约定直接决定了电流环PI输出的物理含义:如果你给Iq一个PI输出,得到的Vq是“要让q轴电流达到目标所需施加的相电压分量”。所以你在代码里看到的Vd、Vq,天然就是相电压尺度。
一个特别有力的佐证是电流环PI输出限幅的设置。绝大多数FOC实现里,Vd、Vq的合成限幅值取的是:
Vmax = Vdc / √3 ≈ 0.577 × Vdc
这个数值不是拍脑袋定的,它正好是SVPWM在线性调制区内能输出的最大相电压峰值(下一章会详细推导)。如果Vd、Vq是线电压尺度,限幅值就应该是Vdc,而实际工程中没人这么设。这已经足够说明问题:FOC算法内部的电压指令,从来都是相电压。
3.2 SVPWM以相电压矢量为目标生成占空比
SVPWM的处理对象是电压矢量,不是三相电压的瞬时标量。它的工作流程大致是这样的:
- 判断参考矢量 Vα+jVβ 落在哪个扇区(六个60度扇区之一);
- 用所在扇区相邻的两个有效矢量和零矢量,按伏秒平衡原则计算各自的作用时间;
- 将作用时间映射成三相桥臂的占空比,并通过特定的开关序列(通常7段式或5段式)输出。
比如扇区1(0度到60度)的7段式序列是:
000 → 100 → 110 → 111 → 110 → 100 → 000
一个PWM周期内,功率管的开关状态先让有效矢量V1作用一段时间,再让V2作用一段时间,最后用零矢量补足剩余时间。这样做的效果是:这个周期内逆变器输出电压矢量的平均值,恰好等于参考矢量。
注意SVPWM从来不需要知道“线电压”是多少。它只是不断问自己:当前这个开关周期,参考矢量落在哪个扇区、两个相邻矢量各需要作用多少比例的时间。至于最终在电机端子上形成的线电压是什么形态,那是调制结果的自然推论,不是算法的输入或目标。
3.3 桥臂输出马鞍波、绕组承受正弦波的原因
现在可以解释最开始的困惑:为什么桥臂输出电压的包络是马鞍形,而电机相电流却是正弦?
关键在于SVPWM为了扩大线性调制范围,会在三相端电压中注入一个零序电压分量(也叫共模分量或三次谐波分量)。这个分量在三相中大小相等、方向相同,也就是说:
Ua0(对直流负极) = Ua*(相对中性点的正弦相电压) + U_zero
Ub0 = Ub* + U_zero
Uc0 = Uc* + U_zero
其中U_zero是SVPWM根据所在扇区实时计算出来的零序注入值。从数值上看,这个零序分量让每一相的端电压包络从正弦变成了“顶部和底部被压平”的马鞍形。
那为什么电机相电流还能保持正弦?因为中性点电压也在跟着跳。前面说了,中性点电位Vn约等于三相端点电压的平均值,也就是:
Vn = (Ua0+Ub0+Uc0)/3 = U_zero(当三相正弦部分之和为零时)
于是电机真正施加在绕组上的相电压等于端点电压减去中性点电压,正好把零序部分抵消掉了:
Ua(n) = Ua0 - Vn = Ua*
也就是说,马鞍波是存在于“桥臂对直流负极”这个参考点上的电压形态;而电机绕组上实际看到的相电压和线电压,依然是对称正弦。你拿着示波器测电机端子和直流负极之间的电压,看到的是马鞍波,这是正常的SVPWM工作方式;但你测端子之间的线电压,或者用虚拟中点测相电压,看到的就是标准正弦。
这个知识点特别容易让刚接触FOC的人犯迷糊。我见过不少初学者看着马鞍波就怀疑自己的SVPWM代码有问题,实际上代码完全正常。我对这个现象的理解是:马鞍波是SVPWM“内部工作电压”,它承载着零序指令;而电机“外部感受电压”是干净的正弦相电压/线电压,两者通过中性点电压的变化完成了分离。
4. 拿数学说话:Vdc/√3为什么是相电压的硬边界
4.1 从SVPWM线性调制区推导电压上限
前面提到Vmax = Vdc/√3,这个数字是从哪来的,值得认真推导一次。SVPWM里,逆变器可输出的8个基本矢量中,6个有效电压矢量的幅值是 2Vdc/3。以V1(对应桥臂状态100)为例,三相输出分别是Vdc、0、0,合成矢量幅值就是 (2/3)×Vdc。
但参考矢量不能“用满”这6个顶点的全部范围,因为在每个扇区内,你只能同时使用两个相邻有效矢量,而它们的最大作用时间之和受限于一个PWM周期。最终可连续输出的参考矢量轨迹,是一个正六边形,六个顶点就是6个有效矢量的端点(幅值2Vdc/3),边是相邻扇区的边界。
如果要求参考矢量的轨迹是圆形(即三相电压始终对称且无畸变),那么这个圆的最大半径就是六边形的内切圆半径。正六边形内切圆半径等于顶点矢量幅值乘以cos(π/6),也就是:
(2Vdc/3) × cos(30°) = (2Vdc/3) × (√3/2) = Vdc/√3
这个Vdc/√3就是SVPWM在线性调制区能够输出的最大相电压幅值(峰值),对应到线电压峰值正好是√3 × Vdc/√3 = Vdc。作为对比,传统SPWM正弦调制最大能输出的相电压峰值只有Vdc/2,SVPWM比它高约15.5%,这就是“母线电压利用率”的差距所在。
所以在FOC的电流环PI限幅里,你看到的Vmax = Vdc/√3,不是一个随意的手工标定值,而是SVPWM物理规律的硬边界。超过这个值就进入过调制区,输出电压波形会变畸变,电流环会开始出现明显的谐波和转矩脉动。
4.2 如果把Vd/Vq当成线电压,会错在哪
假设有人把FOC电压指令理解成“线电压尺度”——也就是说,他认为SVPWM输出的是线电压,因此PI输出的Vd、Vq对应的应该是线电压值。那会发生什么?
很简单,所有计算都会产生√3倍的偏差。线电压幅值等于相电压幅值的√3倍,如果反Park变换后的Vα、Vβ按线电压尺度输入SVPWM,而SVPWM内部的调制深度边界仍按相电压最大幅值Vdc/√3计算,那么系统会提前进入过调制。更直接的影响是:电流环PI输出的电压指令变成线电压之后,实际施加到绕组上的相电压比指令大了√3倍,相当于整个电压环的增益被错误放大,轻则电流波形畸变、转矩波动,重则触发过流保护。
我确实见过一个案例:有人改了Clark变换的系数忘记同步调整PI限幅,结果电机低速空载正常,一旦带载或者提高转速,电流波形就开始出现半波削顶。查来查去,最后发现是电压指令的尺度不对,电流环输出一直被限幅钳位,系统等效于工作在“电压不够”的状态。这类问题排查起来非常难受,因为启动和空载时表现不明显,只有运转到特定工况才会暴露。
所以从工程安全的角度,必须坚持一个结论:FOC内部所有电压量,从Vd/Vq到Vα/Vβ再到SVPWM的参考矢量,都统一采用相电压尺度。任何试图在其中插入线电压概念的行为,都会引入√3的倍数误差。
4.3 电压极限椭圆和弱磁计算中的证据
再给一个来自弱磁控制的证据。PMSM稳态运行时,忽略电阻压降和微分项,电压方程可以简化为:
Vd ≈ -ωe × Lq × Iq
Vq ≈ ωe × (Ld × Id + ψf)
电压幅值约束为 Vd² + Vq² ≤ Vmax²,代入后得到转子磁场定向坐标系下的“电压极限椭圆”方程:
(Lq×Iq)² + (Ld×Id + ψf)² ≤ (Vmax / ωe)²
等式右边Vmax/ωe会随着转速升高而收紧,这就是为什么高速需要弱磁——当ωe增大,必须让d轴电流Id往负方向走,才能压缩(Ld×Id + ψf)这一项,留出空间给q轴电流。
这个椭圆公式里用的Vmax,正是SVPWM线性调制区的相电压上限Vdc/√3。如果你在弱磁计算中把Vmax误当成线电压的上限Vdc,求出的椭圆边界会向外扩√3倍,算出来的弱磁电流起始点会严重偏离真实工况。结果是转速刚进入弱磁区,电流环就饱和,电流追踪不上指令,控制器表现得像“瞬间失去转矩能力”。
这是我个人建议所有做FOC的工程师都手推一遍的公式。推完之后你会发现,所谓的“电压极限”从来不是线电压极限,而是相电压空间矢量的极限。这个边界直接由SVPWM的调制能力决定,和电机绕组是星接还是角接无关(角接时的线电压变成了绕组相电压,但dq电压方程里依然是对每相绕组建立的相电压模型)。
5. 最终答案:分三层回答“相电压还是线电压”
5.1 三层视角下的明确结论
如果非要给一个直接回答,我会分三个层面说:
算法层:FOC电流环输出、反Park变换、SVPWM参考矢量,全部是相电压(相电压空间矢量)尺度。代码里根本没有“线电压”这个中间量,也不需要它。
调制层:SVPWM基于相电压矢量生成三相桥臂占空比,同时为了提升母线电压利用率注入零序分量。桥臂对直流负极的电压包络呈马鞍形,不是三相正弦,但这是正常的内部工作形态。
物理层:逆变器输出经过电机星形绕组的连接关系,绕组两端实际承受的是线电压,线电压幅值是内部相电压指令的√3倍。对电机本身来说,推动电流的确实是线电压组合,但它的全部信息已经包含在相电压矢量里了。
用一句话总结就是:FOC算法要求的是相电压,电机绕组物理承受的是线电压,两者通过坐标变换和绕组连接方式衔接,中间不需要你手动换算√3。如果你在工程代码中试图区分“我是应该输出相电压还是线电压”,那一定是在某个环节把尺度搞混了——真正该做的只是检查Clark/Park变换的系数约定是否统一。
5.2 示波器验证:怎么测量才看得见“相电压逻辑”
口头结论聊完了,来点实操验证方法。假设你手上有一台PMSM,中性点没有引出来,想直观确认FOC控制的是相电压而不是线电压,可以这样测:
第一种方法,搭一个虚拟中点。用三个阻值完全相同(误差尽量小于0.1%)的电阻,把一端分别接到电机U、V、W三个端子上,另一端并接在一起作为虚拟中点。用差分探头测某个端点到虚拟中点的电压,这就是该相电压的近似值。在SVPWM正常调制、电流正弦的工况下,这个电压的滤波后包络应该是平滑的正弦波。
第二种方法,直接测线电压。用差分探头接在U-V两个端子之间,看到的是线电压波形。把测到的线电压峰值除以√3,如果和虚拟中点测到的相电压峰值一致,说明系统的电压尺度完全符合相电压模型。这个实验做一次,胜过看十遍原理图。
第三种方法,观察零序注入。把探头接在U端子和直流母线负极之间,看到的马鞍波包络和相电压正弦包络对比,你会发现马鞍波的“波峰压平量”正好对应SVPWM注入的零序分量。这一步能直观地解释为什么马鞍波不代表“输出异常”。
我建议在电机带载、转速稳定、电流正弦度好的工况下做这三组测量。如果测出来的线电压峰值不是相电压峰值的√3倍,或者电机端对负极的包络不是马鞍形而变成了正弦,那就要回头检查SVPWM的扇区判断和占空比计算了。反过来,如果三组波形都符合预期,那么FOC的电压链路基本可以说是健康的。
5.3 调试中容易踩的坑与个人建议
最后分享几个我在实际调试中踩过的坑,也是群里讨论这个问题时高频出现的问题。
第一个坑:把桥臂对负极的马鞍波当成电机相电压,然后怀疑SVPWM注入零序是设计缺陷。事实上零序注入是SVPWM提升调制比的关键手段。想验证这一点很简单:把电机换成三个星形连接的电阻负载,用差分探头测端点到虚拟中点电压,波形会是正弦,而测端点到直流负极仍是马鞍波。只要两者关系对得上,就不用慌。
第二个坑:电流环PI输出限幅直接填Vdc/2。很多初学FOC的人沿用SPWM的思维,觉得相电压峰值最多到母线电压的一半。但对SVPWM来说,线性调制上限是Vdc/√3,你给PI限幅设成Vdc/2,等于白白牺牲了15.5%的电压利用率。高速满载时电机会提前进入“电压饱和”状态,轻则转矩下降,重则电流环失控。我现在的习惯是留3%到5%的裕量,限幅设在0.92到0.95倍的Vdc/√3左右,防止过调制带来的谐波。
第三个坑:Clark/Park变换的系数约定不一致。有的代码用等幅值变换(2/3系数),有的用等功率变换(√(2/3)系数),两种约定下Vd、Vq的数值差了√(2/3)≈0.816倍。如果你在移植代码时只改了变换函数、没同步调整SVPWM的标定系数或者PI参数,整个电压环的增益就变了。这类问题特别隐蔽,因为空载低速时电流环依然能稳住,但带宽、动态响应、限幅行为全都和预期对不上。
说点个人体会:做FOC调试,一定不要把电压指令和物理端口电压混在一起看。我会在代码里用注释明确标注每个变量的物理含义和尺度——比如“Vd/Vq:相电压峰值尺度(等幅值Park变换)”“Vmax:SVPWM线性调制上限Vdc/√3”。看似多写几行注释,实际上能帮你在三个月后重新打开代码时,少掉一大半的排查时间。
回到最开始那个问题。下次有人再问“FOC最终要求的是相电压还是线电压”,我的回答是:先别急着下结论,想清楚你站在算法层还是功率物理层。算法层永远在画相电压空间矢量,功率层永远在按开关状态输出。中间的桥梁是调制和变换,而√3这个系数只在线电压的物理测量中出现,绝不会出现在FOC的电压指令里。