☰
FOC磁场定向控制实战:从三相电流到转矩控制的完整链路解析
2026/10/7 7:49:59 网站建设 项目流程

1. 从三相到两轴:FOC 到底在解决什么问题

如果你拆过航模电调或者伺服驱动器,大概率见过这样的场景:一块小小的板子上,六个 MOS 管驱动一个三相无刷电机,电机转起来又稳又安静,低速下扭矩还特别大。这背后十有八九跑的就是磁场定向控制,也就是我们常说的 FOC。

FOC 的核心目标其实一句话就能说清:把三相交流电机当成直流电机来控制。直流电机为什么好控制?因为它的励磁磁场和电枢磁场在空间上是正交的,你给电枢电流,产生的转矩就和电流成正比,控制起来非常线性。而三相交流电机通的是正弦波,定子电流产生的磁场是个旋转的矢量,转子和它之间的夹角一直在变,直接控制三相电流根本没法直观地控制转矩。

FOC 的做法就是通过坐标变换,把三相静止坐标系下的电流,映射到一个跟着转子一起旋转的坐标系上。在这个旋转坐标系里,原本旋转的磁场被“拉直”了,一个轴管励磁,一个轴管转矩,两个量都是直流量,用 PI 调节器就能稳稳地控制住。这就是为什么 FOC 能让电机在低速下依然输出平稳扭矩、噪音小、效率高。

这套东西听起来数学味很重,但落到工程上,无非就是几个环节:采样三相电流、做 Clarke 变换、做 Park 变换、跑两个电流环 PI、再反变换回三相、最后用 SVPWM 输出。整条链路里,三相电流是原料,dq 坐标系是加工车间,转矩控制是最终产品。我见过不少刚上手的朋友,卡就卡在坐标系变换的物理意义上,代码照着抄能跑,但一出问题就完全不知道从哪查。所以这篇我打算把这条链路从头到尾捋一遍,重点讲清楚每个环节为什么这么设计,以及实际调试时那些文档里不会写的坑。

适合看这篇的人:做过电机控制但 FOC 没跑通的、想从方波驱动升级到 FOC 的、以及被 dq 变换绕晕过的嵌入式工程师。我会尽量用生活化的类比把数学讲明白,同时给出可以直接参考的代码结构和参数整定思路。

2. 三相电流与坐标变换:FOC 的数学地基

2.1 为什么三相电流不能直接拿来控制

先说说三相电流本身。一个理想的三相无刷电机,三相绕组在空间上互差 120 度电角度,通入的电流也是互差 120 度的正弦波。这三相电流合成起来,就是一个幅值恒定、以电频率旋转的电流矢量。

问题来了:这个旋转矢量的幅值和角度,和转矩之间是什么关系?答案是——取决于它和转子磁场的夹角。如果电流矢量和转子磁场方向一致,那它只产生励磁,不产生转矩;如果超前 90 度,转矩最大。也就是说,要控制转矩,本质上是要控制电流矢量相对于转子磁场的位置和大小。

但三相电流是三个随时间正弦变化的量,你没法直接对它们做 PI 控制——PI 调节器对正弦量的跟踪是有稳态误差的,而且三个量互相耦合,调一个动全身。这就是为什么必须做坐标变换:把问题从“跟踪三个正弦量”变成“控制两个直流量”。

这里有个很关键的物理直觉:坐标变换不是数学游戏,它是在换一个观察视角。就像你坐在旋转木马上看地面的人,觉得他们在绕圈;但如果你也坐在旋转木马上看另一个同样转速的人,他就静止了。Park 变换干的就是这件事——把观察者放到转子上,于是定子电流在观察者眼里就变成了两个不动的分量。

2.2 Clarke 变换:三相到两相的降维

Clarke 变换是把三相静止坐标系(a、b、c)变成两相静止坐标系(α、β)。因为三相电流满足 ia + ib + ic = 0(星形连接无中线时),所以三个量里只有两个是独立的,降成两维不丢信息。

变换公式有两种常见形式,区别在系数:

  • 等幅值变换:α 轴分量等于 a 相电流,系数是 2/3。这种变换下,变换前后矢量的幅值不变,做电流环时给定值和实际值可以直接比较,工程上最常用。
  • 等功率变换:系数是 sqrt(2/3),变换前后功率不变,但幅值会变,做控制时要注意标幺化。

我个人的习惯是用等幅值变换,因为调试时示波器上看 iα 和 ia 的幅值一致,心里有底。具体公式:

iα = (2/3) * (ia - 0.5*ib - 0.5*ic) iβ = (2/3) * (sqrt(3)/2) * (ib - ic)

实际代码里,因为 ia + ib + ic = 0,可以简化成:

i_alpha = ia; i_beta = (ia + 2.0f * ib) * ONE_BY_SQRT3;

这个简化版省掉了一次乘法和几次加减,在中断里跑能省几个周期。但要注意,这个简化只在三相电流严格满足和为零时成立。如果采样有偏差或者电机有中线引出,就得老老实实按完整公式算。

注意:Clarke 变换的输入必须是同一时刻采样的三相电流。如果三相采样有先后顺序,在高速下会引入相位误差,导致转矩脉动。我见过一个案例,电机在 3000 转以上出现明显抖动,最后查出来是 ADC 采样顺序导致的,改成同步触发就好了。

2.3 Park 变换:跟着转子一起转

Park 变换是把 α、β 坐标系再旋转一个角度 θ(转子电角度),得到 d、q 坐标系。d 轴对准转子磁场方向,q 轴超前 90 度。

id = iα * cosθ + iβ * sinθ iq = -iα * sinθ + iβ * cosθ

变换之后,id 是励磁分量,iq 是转矩分量。对于表贴式永磁同步电机(SPMSM),d 轴和 q 轴电感相等,磁阻转矩为零,所以通常把 id 控制为 0,只给 iq 就能控制转矩,转矩和 iq 成正比:

Te = 1.5 * p * ψf * iq

其中 p 是极对数,ψf 是永磁体磁链。这个公式是 FOC 转矩控制的理论基础——只要把 iq 控住,转矩就控住了。

对于内置式永磁同步电机(IPMSM),d 轴和 q 轴电感不等,存在磁阻转矩,这时候可以给一点负的 id 来利用磁阻转矩,提高效率,这就是所谓的 MTPA(最大转矩电流比)控制。不过这是进阶话题,先把 id=0 跑通再说。

θ 这个角度从哪来?有传感器的话,从编码器或霍尔读;无感的话,从观测器估。这是 FOC 里最要命的一环,角度错了,整个坐标系就歪了,电流全乱套。后面会专门讲。

2.4 反 Park 变换与 SVPWM:把控制量送回三相

电流环算出来的 vd、vq 是旋转坐标系下的电压指令,要送回三相去执行,得先反 Park 变回 α、β:

vα = vd * cosθ - vq * sinθ vβ = vd * sinθ + vq * cosθ

然后通过 SVPWM(空间矢量脉宽调制)生成六路 PWM。SVPWM 比正弦波调制(SPWM)的直流电压利用率高约 15%,而且谐波特性更好,是 FOC 的标配。

SVPWM 的核心思想是:用八个基本电压矢量(六个有效矢量加两个零矢量)去合成任意方向的电压矢量。具体实现有七段式和五段式,七段式谐波好但开关次数多,五段式开关损耗低但谐波稍差。工程上常用七段式,因为死区效应和电流纹波更小。

这里有个实操细节:SVPWM 计算出来的三个占空比,要经过死区补偿再写入定时器比较寄存器。死区是为了防止上下桥臂直通,但死区会导致输出电压畸变,低速时尤其明显,表现为电流波形出现平顶。补偿方法一般是根据电流方向给占空比加一个偏置,具体补偿量要结合死区时间和开关频率算。

3. 电流环与转矩控制:把 iq 拿捏住

3.1 电流环为什么是 FOC 的内核

整个 FOC 的控制结构是双环:外环是速度环或位置环,内环是电流环。电流环的带宽通常比速度环高 5 到 10 倍,因为电流响应必须足够快,才能让转矩指令被及时执行。

电流环的输入是 id_ref 和 iq_ref,输出是 vd 和 vq。对于 id=0 控制,id_ref 直接给 0,iq_ref 来自速度环的输出。两个 PI 调节器分别控制 d 轴和 q 轴电流。

为什么用 PI 而不是别的?因为电机绕组是 RL 电路,传递函数是一阶的,PI 调节器能提供足够的低频增益实现零稳态误差,同时通过零点对消把系统整成典型一阶或二阶。理论上,PI 参数可以按内模控制(IMC)或零极点对消法算出来:

Kp = L * ωc Ki = R * ωc

其中 L 是电感,R 是电阻,ωc 是期望的电流环带宽。比如 L=1mH,R=0.5Ω,想要 2000rad/s 的带宽,那 Kp=2,Ki=1000。实际调试时在这个基础上微调,因为还有采样延迟、PWM 延迟、死区等非理想因素。

提示:电流环带宽不是越高越好。带宽太高,对采样噪声和 PWM 延迟敏感,容易振荡;带宽太低,转矩响应慢,动态性能差。一般取开关频率的 1/10 到 1/20。比如 20kHz 开关频率,带宽取 1k 到 2k rad/s 比较稳妥。

3.2 dq 轴耦合与解耦补偿

dq 坐标系下,电压方程是这样的:

vd = R*id + Ld*d(id)/dt - ωe*Lq*iq vq = R*iq + Lq*d(iq)/dt + ωe*Ld*id + ωe*ψf

注意最后那几项带 ωe 的,是交叉耦合项和反电动势项。它们的存在意味着:你调 d 轴电压,q 轴电流会受影响;转速越高,耦合越强。如果不做解耦,电流环在高速下会明显变差,甚至失稳。

解耦补偿的做法很简单:在 PI 输出上叠加前馈项:

vd_ff = -ωe * Lq * iq vq_ff = ωe * Ld * id + ωe * ψf

这样就把耦合项抵消掉了,d 轴和 q 轴可以独立调。低速时耦合小,加不加差别不大;但转速上到额定的一半以上,不加解耦基本没法看。

我踩过的一个坑:一开始没加解耦,电机在低速跑得好好的,一上高速电流就震荡,iq 波形像锯齿一样。查了半天以为是 PI 参数问题,后来加上前馈补偿,波形立刻干净了。所以如果你发现高速下电流环不稳,先检查解耦有没有做对。

3.3 转矩控制的实现路径

转矩控制的最终目标是让电机输出想要的转矩。对于 id=0 控制,转矩和 iq 成正比,所以速度环的输出直接就是 iq_ref。速度环通常也用 PI,输入是速度误差,输出是转矩指令。

但这里有个限幅问题:iq_ref 不能无限大,受限于电机额定电流和逆变器容量。所以速度环输出要经过一个限幅器,限幅值取电机允许的最大 q 轴电流。同时,如果做了弱磁控制,id_ref 也会随转速变化,这时候转矩和 iq 的关系就不是简单正比了,需要查表或在线计算。

实际工程里,转矩控制还要考虑几个因素:

  • 电流采样精度:采样电阻的温漂、运放的失调都会影响 iq 的准确性,进而影响转矩精度。高精度场合要用霍尔电流传感器或隔离运放。
  • 角度精度:θ 的误差直接导致 id、iq 解算错误,表现为转矩脉动。有传感器时要注意编码器安装偏心,无感时要注意观测器收敛。
  • 死区与管压降:低速小电流时,死区和 MOS 管压降导致的电压误差占比大,会让实际电流偏离指令,转矩控制不准。

3.4 无感 FOC 的角度估计:滑模观测器实战

无感 FOC 最核心的问题就是:没有编码器,怎么知道转子在哪?常见方法有反电动势观测、滑模观测器(SMO)、龙伯格观测器、高频注入等。滑模观测器因为鲁棒性好、实现简单,在工业上用得最多。

滑模观测器的基本思路是:根据电机电压方程构造一个电流观测器,用实际电流和观测电流的误差来构造滑模面,通过开关函数迫使误差收敛到零,从而从等效控制量里提取反电动势,再算出角度。

具体步骤:

  1. 在 α、β 坐标系下建立电流观测器:
    d(iα_hat)/dt = (1/L) * (vα - R*iα_hat - eα_hat) d(iβ_hat)/dt = (1/L) * (vβ - R*iβ_hat - eβ_hat)
  2. 定义滑模面 s = iα_hat - iα,用符号函数或饱和函数构造控制量:
    eα_hat = k * sign(iα_hat - iα)
  3. 对 eα_hat、eβ_hat 做低通滤波,得到反电动势估计值。
  4. 角度 θ = atan2(-eα_hat, eβ_hat)。

滑模观测器的难点在抖振和低速性能。符号函数抖振大,实际用饱和函数或 sigmoid 函数替代。低速时反电动势幅值小,信噪比低,角度估计不准,所以纯滑模观测器一般只能跑到额定转速的 5% 到 10% 以上。要低速甚至零速运行,得用高频注入或者把滑模和别的观测器结合起来。

注意:滑模观测器的参数 k 需要根据反电动势幅值来整定。k 太小,收敛慢;k 太大,抖振严重。一般取反电动势峰值的 1.5 到 2 倍。另外,低通滤波会引入相位延迟,高速时要补偿,补偿角 = atan(ωe / ωc),ωc 是滤波器截止频率。

4. 从代码到波形:FOC 实操全流程

4.1 硬件与软件框架搭建

一套典型的 FOC 系统,硬件上需要:三相逆变桥(六个 MOS 或 IPM)、电流采样电路(至少两相,常用三电阻或单电阻)、母线电压采样、转子位置传感器(有感的编码器/霍尔,无感的省掉)、以及一颗能跑浮点或定点 FOC 的 MCU。

软件框架我一般这么分:

  • PWM 中断(最高优先级):触发 ADC 采样、执行电流环、更新 PWM 占空比。频率等于开关频率,比如 20kHz。
  • 速度环中断:频率低一些,比如 1kHz,执行速度 PI 和角度更新。
  • 主循环:处理通信、状态机、故障保护。

PWM 和 ADC 的同步很关键。通常用定时器的更新事件触发 ADC,ADC 转换完成后产生中断,在中断里做 FOC 计算。这样采样时刻固定在 PWM 周期的中点或起点,避开开关噪声。

void PWM_IRQHandler(void) { // 1. 读取三相电流 ia = ADC_GetPhaseA(); ib = ADC_GetPhaseB(); ic = -ia - ib; // 2. Clarke 变换 i_alpha = ia; i_beta = (ia + 2.0f * ib) * ONE_BY_SQRT3; // 3. Park 变换 id = i_alpha * cos_theta + i_beta * sin_theta; iq = -i_alpha * sin_theta + i_beta * cos_theta; // 4. 电流 PI vd = PI_Update(&pi_d, id_ref - id); vq = PI_Update(&pi_q, iq_ref - iq); // 5. 解耦补偿 vd -= omega_e * Lq * iq; vq += omega_e * (Ld * id + psi_f); // 6. 反 Park v_alpha = vd * cos_theta - vq * sin_theta; v_beta = vd * sin_theta + vq * cos_theta; // 7. SVPWM SVPWM_Calc(v_alpha, v_beta, &duty_a, &duty_b, &duty_c); PWM_SetDuty(duty_a, duty_b, duty_c); // 8. 清中断标志 PWM_ClearIRQ(); }

这段代码是骨架,实际还要加母线电压补偿、死区补偿、过流保护等。母线电压补偿是因为 SVPWM 输出的占空比对应的是实际母线电压,如果母线波动,同样的占空比输出电压会变,所以要用实际母线电压归一化。

4.2 电流采样时机与噪声抑制

电流采样是 FOC 里最容易出问题的地方。三电阻采样时,采样时刻必须避开开关动作,否则采到的是开关噪声。通常的做法是在 PWM 周期的中点采样,因为这时候下桥臂导通,采样电阻上有电流流过。

但中点采样有个限制:当占空比接近 0% 或 100% 时,下桥臂导通时间太短,采样窗口不够。这时候要么用最小采样时间限制,要么切换到单电阻采样方案。单电阻采样只需要一个采样电阻,成本低,但重构三相电流的算法复杂,且在扇区边界处有盲区。

噪声抑制方面,硬件上在采样电阻两端加 RC 滤波,软件上做多次采样取平均或中值滤波。但滤波会引入延迟,影响电流环带宽,所以要权衡。我一般用两次采样取平均,延迟小,效果也够。

提示:采样电阻的选型要考虑功耗和信噪比。阻值大,信号强但功耗大;阻值小,功耗低但信号弱。一般取 1mΩ 到 10mΩ,配合运放放大到 ADC 量程的 1/2 到 2/3。运放要选高共模抑制比、低失调的,比如差分运放。

4.3 参数整定与调试步骤

FOC 调试我一般按这个顺序来:

  1. 确认硬件:先不接电机,用示波器看六路 PWM 波形,确认死区、极性、互补性都对。然后接一个假负载(比如三个电感),看电流采样是否正常。
  2. 开环旋转:给一个固定的电压矢量和逐渐增加的角度,让电机开环转起来。这一步验证 SVPWM 和角度生成是否正确。如果电机不转或抖动,检查相序和角度方向。
  3. 电流环整定:电机堵转或带小负载,给 id_ref=0,iq_ref 给一个小阶跃,看 iq 的响应。先调 Kp 到临界振荡,再降到 0.5 倍,然后加 Ki 消除稳态误差。用示波器看 iq 波形,上升时间、超调、稳态误差都要关注。
  4. 速度环整定:电流环 OK 后,闭合速度环,给速度阶跃,调速度 PI。速度环带宽取电流环的 1/5 到 1/10。
  5. 无感观测器调试:如果做无感,先开环拖到一定转速,切换到闭环,看观测器角度和实际角度的误差。误差大就调观测器参数,或者检查反电动势常数是否准确。

每一步都要用示波器或上位机看波形,不要凭感觉。我习惯用 DAC 把 id、iq、速度这些量输出到示波器上,实时观察。没有 DAC 的话,用串口上传到上位机画波形也行,但采样率受限。

4.4 常见问题与排查速查表

现象可能原因排查方法
电机不转,有嗡嗡声相序错、角度方向错交换任意两相,或角度加负号
低速抖动,高速正常死区补偿不足、电流采样噪声加大死区补偿,检查采样时刻
高速电流震荡解耦未做、PI 带宽过高加前馈解耦,降低 Kp
转矩脉动大角度误差、电流采样偏差校准编码器,检查采样电阻
无感启动失败观测器低速不收敛用高频注入或开环启动
过流保护频繁触发电流环参数太激进、限幅值太小降低 Kp,检查限幅
电机发热严重id 不为零、谐波大检查 id_ref,优化 SVPWM

这张表是我这些年踩坑总结出来的,基本覆盖了 80% 的常见问题。遇到问题先查表,能省不少时间。

5. 进阶话题与工程经验

5.1 弱磁控制与 MTPA

电机转速升高时,反电动势增大,当反电动势接近母线电压时,电流环就饱和了,转速上不去。这时候需要弱磁:给一个负的 id,削弱转子磁场,降低反电动势。弱磁控制的核心是电压极限椭圆和电流极限圆的约束下,找到最优的 id、iq 组合。

MTPA 则是另一个方向:对于 IPMSM,通过合理分配 id 和 iq,用最小的电流产生最大的转矩。MTPA 的解析解可以通过对转矩公式求导得到,但实际因为参数非线性,常用查表法。

这两个话题展开能写一整篇,这里只提一点:弱磁和 MTPA 都需要准确的电机参数(Ld、Lq、ψf),参数不准,效果大打折扣。所以做这些高级控制之前,先把参数辨识做扎实。

5.2 带宽的理解与整定

热词里有个“foc控制中带宽的理解”,我单独说说。带宽本质上是系统对指令的跟踪能力,定义为幅频特性下降到 -3dB 对应的频率。电流环带宽决定了转矩响应的快慢,速度环带宽决定了速度跟踪的快慢。

带宽不是越高越好,受限于:

  • 采样频率:根据香农定理,带宽不能超过采样频率的一半,实际取 1/10 以下。
  • PWM 延迟:PWM 更新有半个周期的延迟,加上采样和计算延迟,总延迟约 1.5 个 PWM 周期。延迟越大,可达到的带宽越低。
  • 噪声:带宽高,高频噪声放大,容易振荡。

整定时,先用理论公式算一个初值,然后在实际系统上测阶跃响应,看上升时间和超调。如果超调大,降 Kp;如果有稳态误差,加 Ki。反复几次就能找到合适的值。

5.3 无感 FOC 的启动策略

无感 FOC 最大的难点是启动。零速和低速时反电动势为零或很小,观测器无法估计角度。常见的启动策略有三种:

  1. 三段式启动:先强制对齐(给一个固定角度通电流,把转子拉到已知位置),然后开环加速(按预设的加速度增加角度和电压),最后切换到闭环。简单可靠,但启动时间和位置不确定。
  2. 高频注入:在 d 轴注入高频电压信号,利用凸极效应提取转子位置。能实现零速启动,但对电机凸极率有要求,且注入会带来噪音和损耗。
  3. I/F 启动:电流闭环、频率开环,给一个旋转的电流矢量,让电机跟着转,达到一定转速后切换到 FOC。比三段式平滑,但参数整定麻烦。

我一般先用三段式把系统跑通,再根据应用需求决定要不要上高频注入。航模和风扇这类对启动时间不敏感的,三段式足够了;伺服和压缩机这类要求零速大转矩的,得上高频注入。

5.4 代码优化与实时性

FOC 中断里跑的东西不少,20kHz 开关频率意味着 50us 就要跑完一次。三角函数、除法这些运算很耗时,得优化。

  • 三角函数:用查表法或 CORDIC 算法,比库函数快很多。查表要注意分辨率,太粗会导致角度误差,太细占 Flash。
  • 除法:尽量用乘法代替,比如除以 3 变成乘以 1/3。
  • 定点化:如果 MCU 没有 FPU,用 Q 格式定点运算,速度比浮点快几倍。但要注意溢出和精度。
  • 中断优先级:FOC 中断优先级最高,其他中断不能打断它,否则时序会乱。

我实测过,在 100MHz 的 M4 上,浮点 FOC 跑 20kHz 大概占 30% 到 40% 的 CPU,定点能降到 15% 左右。如果还要跑观测器和弱磁,得留够余量。

5.5 实测经验与避坑清单

最后分享几条我踩过的坑:

  • 电流采样运放的失调:运放失调会导致零电流时采样不为零,积分后 id、iq 漂移。上电时要校准失调,或者用软件做零漂补偿。
  • 编码器安装偏心:会导致角度误差随位置周期性变化,表现为转矩脉动。安装时要保证同心度,或者做偏心补偿。
  • 死区时间过大:死区大了,输出电压损失大,低速时电流畸变严重。死区时间一般取 0.5us 到 2us,根据 MOS 开关速度定。
  • 母线电容太小:母线电容小,电压波动大,影响 SVPWM 输出。一般按每安培 100uF 到 200uF 选。
  • 参数辨识不准:R、L、ψf 不准,电流环和观测器都调不好。上电时做一次参数辨识,或者用 LCR 表测。

FOC 这东西,理论看一遍觉得懂了,实际调起来全是细节。我的建议是,先搭一个能跑的最小系统,把电流环调好,再逐步加功能。每加一个功能,都要用波形验证,不要凭感觉。波形不会骗人,眼睛会。

后续如果想深入,可以研究一下模型预测控制(MPC)在 FOC 上的应用,或者把 FOC 和参数辨识、无位置传感器技术结合起来。但基础的三相电流、dq 变换、转矩控制这条链路,是所有进阶的根基,值得反复琢磨。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询