【电赛/毕设天花板】别再调包 SimpleFOC 了!STM32 纯手写 FOC 矢量控制:空间变换、SVPWM 与相电流采样硬核指南
前言
无论是能后空翻的机械狗(如宇树科技)、极度丝滑的大疆云台,还是特斯拉的驱动电机,它们底层的核心技术全都是同一个词——FOC(Field Oriented Control,磁场定向控制)。
在电赛和毕设中,如果你还在用传统的六步换向法(电调)驱动无刷电机,低速时的抖动和巨大的噪音会让你显得非常“业余”。
很多同学试图去学 FOC,但翻开教材,满屏的复平面、克拉克变换、帕克变换直接把人看懵;用网上的开源库,一旦电机抽搐,面对几万行代码根本无从 Debug。
今天,我们将打破数学玄学!剥开 FOC 的外衣,你会发现所谓的空间矢量变换,在 C 语言中只不过是几行极其简单的加减乘除。
本文手把手教你理解 FOC 闭环本质,并排掉**相电流采样(ADC)**这个让无数硬件狗炸管的史诗级大坑!
@TOC
一、 FOC 的底层哲学:把交流电变成直流电!
无刷电机有三根线(A、B、C),里面跑的是三个相位相差 120° 的正弦交流电。
要控制三个随时间不断变化的交流电,对单片机里的 PID 控制器来说,简直是地狱难度(PID 最怕目标值疯狂变化)。
FOC 的核心哲学只有一个:降维打击!
既然三相交流电太难控,我们就通过数学变换,把它们强行转换成两个静止的直流电!
Id(直轴电流):产生无用的磁场(让电机发热的力),我们的目标是用 PID 把它死死控制在 0。
Iq(交轴电流):产生推动电机旋转的力矩(有用的力)!你给的 Iq 越大,电机的扭矩就越大。我们要用 PID 精准控制这个 Iq!
结论:FOC 就是一个把复杂的三相交流电,变成 Id 和 Iq 两个简单的直流变量,然后用两个普通的 PID 去控制它们的过程。
二、 撕开数学伪装:Clarke 与 Park 变换的 C 语言真面目
教科书上的矩阵公式看起来吓人,但写成 C 语言代码,简单得让人心疼。
1. Clarke 变换:三相变两相
物理定律告诉我们,电机三根线流进流出的电流总和永远为 0(基尔霍夫定律):
Ia+Ib+Ic=0Ia+Ib+Ic=0。
所以我们其实只需要用 ADC 测两根线(比如 A 和 B)的电流,就能算出第三根。
Clarke 变换,就是把互成 120° 的 3 个电流(
Ia,Ib,IcIa,Ib,Ic),变成互成 90° 直角的 2 个电流(
Iα,IβIα,Iβ)。
C 语言极简代码(直接抄):
codeC
// 假设已经通过 ADC 测到了 A相 和 B相 的真实电流 Ia, Ib float I_alpha, I_beta; void Clarke_Transform(float Ia, float Ib) { I_alpha = Ia; // sqrt(3)/3 ≈ 0.577350269f // 公式推导极其复杂,但代码只有这一句! I_beta = 0.577350269f * (Ia + 2.0f * Ib); }2. Park 变换:旋转变静止(核心魔法)
上面算出来的
IαIα和
IβIβ依然是交流电!因为电机的转子在疯狂旋转。
Park 变换就是:让我们的观察视角,跟着电机的转子一起转!这样在我们的眼里,相对速度为 0,交流电就变成了完美的直流电(
IdId和
IqIq)。
这需要知道当前电机转子的绝对角度
θθ(通过磁编码器如 AS5600 瞬间读出)。
C 语言结合 CMSIS-DSP 加速代码:
codeC
#include "arm_math.h" float Id, Iq; void Park_Transform(float I_alpha, float I_beta, float theta) { float sin_theta, cos_theta; // 利用 STM32 底层 DSP 硬件加速,极速求出 sin 和 cos arm_sin_cos_f32(theta * 57.29578f, &sin_theta, &cos_theta); // 旋转坐标系矩阵乘法 Id = I_alpha * cos_theta + I_beta * sin_theta; Iq = -I_alpha * sin_theta + I_beta * cos_theta; }看到这里你明白了吗?困扰无数人的两大数据变换,在单片机里总共只需要3 行数学运算代码!利用算出来的 Id 和 Iq,你就可以开心地送进你最熟悉的 PID 控制器里了!
三、 FOC 的输出引擎:为什么不用 SPWM 而用 SVPWM?
PID 计算完了,我们得到了期望的电压输出。怎么把电压作用到电机的三根线上?
很多人以为是输出三个正弦波(SPWM)。
错!工业界绝不用 SPWM,而是用 SVPWM(空间矢量脉宽调制)!
为什么要用 SVPWM(马鞍波)?
如果用纯正弦波(SPWM),你最多只能利用电源电压的 86.6%。
SVPWM 巧妙地在正弦波中注入了三次谐波。你用示波器去测电机的相电压,会看到一个奇丑无比的**“马鞍形”波形**(像麦当劳的 M 标志)。
但是!两个马鞍波相减(线电压),正好是一个极其完美、幅度更大的纯正弦波!
收益:电源电压利用率直接飙升到100%!在同样的电池下,你的电机能输出更大的极限扭矩!
(SVPWM 的代码涉及扇区判断和 T1, T2 作用时间计算,大约 50 行代码,篇幅原因此处不展,大家可以套用开源的标准实现。)
四、 史诗级硬件灾难:相电流采样(ADC)的生死时速
FOC 所有的数学计算,都建立在你准确测到了电机的相电流(
Ia,IbIa,Ib)的前提下。
这是整个 FOC 乃至电赛中,最容易让单片机死机、让 MOS 管炸裂的天坑!
🚨 避坑 1:采样方式的选择
In-line(串联采样):在电机的线上串联极小的采样电阻。非常准,但需要极其昂贵的双向高共模运算放大器(如 INA240)。
Low-side(下桥臂采样):在三个下桥臂的 MOS 管下面串联采样电阻。成本极低(几毛钱的普通运放即可),但对单片机的 ADC 触发时序要求严苛到变态!
🚨 避坑 2:下桥臂采样的“幽灵时序”
因为采样电阻串联在下方,只有当电机的 下桥臂 MOS 管导通时,才有电流流过电阻!
如果你用 while(1) 随意触发 ADC,你大概率采到的是 0,或者是 MOS 管开关瞬间高达上百安培的巨大尖峰噪声。这时候你的 Clarke 变换全乱了,PID 输出核弹级指令,电机瞬间冒烟!
🏆 终极解决架构:定时器中央对齐 + CCR4 触发 ADC
(与上一篇《定时器外挂指南》梦幻联动!)
必须利用硬件级自动化对齐:
配置 TIM1 产生 SVPWM 时,必须设置为中心对齐模式(Center-aligned Mode)。在这种模式下,下桥臂的导通时间总是分布在计数器达到最大值(或者 0)的中间!
激活 TIM1 的第 4 通道(CCR4),将其比较值设置在计数器即将达到最高点的前 1 微秒!
用 TIM1 的 CCR4 比较事件(TRGO)去直接硬件触发 STM32 的 ADC!
威力:CPU 根本不需要操心!硬件会在每一个 PWM 周期的绝对正中心(此时 MOS 管稳定导通,且完美避开了开关瞬间的电流毛刺),精准截取真实的相电流。采出来的电流波形平滑得像丝绸,你的 FOC 闭环系统将坚如磐石!
五、 FOC 极简工作流全景图
别被代码文件绕晕了,FOC 的主循环其实是在定时器溢出中断(通常为 10kHz~20kHz)中执行的,流程极其清晰:
codeC
void FOC_High_Frequency_Loop(void) { // 1. 读角度 float theta = AS5600_Get_Angle(); // 2. 读真实电流 (ADC 硬件触发已经采好了) float Ia = Get_ADC_Current_A(); float Ib = Get_ADC_Current_B(); // 3. 变换为直流 Clarke_Transform(Ia, Ib); Park_Transform(I_alpha, I_beta, theta); // 得到当前真实的 Id, Iq // 4. PID 闭环计算 (我们的目标是 Id=0, Iq=目标扭矩) float Vd = PID_Calc(&PID_Id, 0.0f, Id); float Vq = PID_Calc(&PID_Iq, Target_Torque, Iq); // 5. 逆向变换回去!(怎么来的怎么回去) Inv_Park_Transform(Vd, Vq, theta); // 得到 V_alpha, V_beta // 6. 送给空间矢量调制器,硬件生成 6 路 PWM 去驱动 MOS 管! SVPWM_Generate(V_alpha, V_beta); }这就是 FOC 的全部!没有任何黑魔法,只有优美的数学与严密的硬件时序控制!
结语
在嵌入式开发的鄙视链中,纯手写底层 FOC 无疑处于最高端的塔尖。
它要求你同时具备模拟电路知识(运放采样)、数字电路知识(ADC与定时器联动)、自动控制原理(PID)、以及空间数学变换能力。
不要再去死记硬背那些枯燥的数学矩阵,理解 FOC 降维打击的哲学;不要去畏惧下桥臂采样的复杂,拥抱 STM32 底层硬件联动的美感。
当你亲手写出的第一行 FOC 代码,让那个满是磁铁和线圈的无刷电机,以 0.1 转/分的极慢速度丝滑旋转,并在你用手捏住它时,反馈给你如同拥有生命一般的肌肉弹力时……
你就会明白,硬核科技的浪漫,莫过于此。
预祝各位挑战极限的开发者:ADC 采点精准无误,PID 闭环稳如泰山,斩断玄学,手搓 FOC 震撼全场!🏆
