跳到主要内容直流无刷电机 FOC 控制算法原理与 STM32 实战 | 极客日志C算法
直流无刷电机 FOC 控制算法原理与 STM32 实战
直流无刷电机(BLDC)及永磁同步电机(PMSM)的磁场定向控制(FOC)算法。涵盖电机基础结构、FOC 核心原理(Clarke/Park 变换、SVPWM)、STM32F103 硬件配置与软件实现流程。通过数学推导与代码示例,解析坐标变换、扇区判断、矢量作用时间计算及 PWM 占空比生成逻辑。提供性能测试数据与进阶优化方向,适合嵌入式开发者掌握高性能电机控制技术。
清心24 浏览 直流无刷电机 FOC 控制算法原理与 STM32 实战
引言
在直流无刷电机(BLDC)和永磁同步电机(PMSM)的控制领域,磁场定向控制(Field-Oriented Control,简称 FOC)凭借其转矩平稳、噪声低、效率高及动态响应快的核心优势,已成为高性能电机控制的主流方案。这种算法通过精准控制电机磁场的大小与方向,将复杂的三相交流控制问题转化为简单的直流控制模型,解决了传统六步换相控制中转矩脉动大的痛点。
本文从电机基础原理切入,系统拆解 FOC 算法的核心流程,结合数学推导、可视化图表与 STM32 实战代码,解析 FOC 控制技术的实现逻辑。
一、电机基础:从结构到控制原理铺垫
1. 无刷电机核心构成与优势
无刷电机由定子(三相绕组,星形连接)和转子(永磁体)组成,通过电子换向替代传统有刷电机的机械电刷,核心优势如下:
- 高效率:无电刷摩擦损耗,能量转换效率可达 90% 以上;
- 高可靠性:减少电刷、换向器等易损件,寿命提升 5-10 倍;
- 宽调速范围:支持 0-10000rpm 无级调速,低速力矩稳定;
- 低噪声:电子换向无机械冲击,运行噪音低于 50dB。
2. BLDC 与 PMSM 的核心区别
两者结构相似,最关键的差异在于反电动势波形,这直接决定了控制算法的选择:
| 特性 | 无刷直流电机(BLDC) | 永磁同步电机(PMSM) |
|---|
| 反电动势波形 | 梯形波 | 正弦波 |
| 控制方式 | 方波驱动(六步换相) | 正弦波驱动(FOC 矢量控制) |
| 电流波形 | 矩形波 | 正弦波 |
| 转矩脉动 | 中等(6%~10%) | 极低(<2%) |
3. 传统控制与 FOC 的本质差异
以有感 BLDC 为例,传统六步换相与 FOC 的核心区别如下:

二、FOC 核心原理:从坐标系变换到 SVPWM 实现
FOC 算法的本质是'坐标变换 + 闭环控制 + 脉冲调制'的组合,通过三次关键变换将三相交流量转化为可独立控制的直流量,核心流程如下:
1. FOC 算法整体框架

2. 核心坐标变换:从三相到两相的降维魔法
(1)Clarke 变换:静止坐标系降维
将三相静止坐标系(Ia、Ib、Ic,相位差 120°)转化为两相静止坐标系(Iα、Iβ,正交 90°),利用基尔霍夫电流定律(Ia+Ib+Ic=0)简化计算。
变换公式推导:
基于矢量分解原理,将三相电流投影到α-β坐标系,等幅值变换结果为:
{ = I_a
{ = (/sqrt()) * I_a + (/sqrt()) * I_b
I_alpha
I_beta
1
3
2
3
{ I_a = I_alpha
{ I_b = (sqrt(3)*I_beta - I_alpha) / 2
{ I_c = (-I_alpha - sqrt(3)*I_beta) / 2
(2)Park 变换:静止到旋转的解耦
将两相静止坐标系(Iα、Iβ)转化为随转子旋转的 d-q 坐标系(Id、Iq),实现转矩与励磁的解耦控制:
- d 轴:与转子磁链方向重合(励磁轴),Id 控制磁场强度;
- q 轴:与转子磁链方向垂直(转矩轴),Iq 直接决定输出转矩。
变换公式推导:
设 d 轴与α轴夹角为θ(转子位置角),通过三角投影可得:
{ I_d = I_alpha * cos(theta) + I_beta * sin(theta)
{ I_q = -I_alpha * sin(theta) + I_beta * cos(theta)
{ U_alpha = U_d * cos(theta) - U_q * sin(theta)
{ U_beta = U_d * sin(theta) + U_q * cos(theta)
3. SVPWM:空间矢量的脉冲合成
空间矢量脉宽调制(SVPWM)是 FOC 的"执行终端",通过控制 6 个功率管的开关状态,合成接近圆形的磁链轨迹,核心实现分为四步:
(1)基本电压矢量与扇区划分
三相逆变桥的 8 种开关状态(6 个非零矢量 +2 个零矢量)构成 6 个扇区,每个扇区对应 60°电角度:
| 矢量 | 开关状态(S1,S2,S3) | 电压幅值 | 扇区范围 |
|---|
| U0(000) | 0,0,0 | 0 | 零矢量 |
| U60(110) | 1,1,0 | 2Udc/3 | 扇区 I(0°~60°) |
| U120(010) | 0,1,0 | 2Udc/3 | 扇区 II(60°~120°) |
| U180(011) | 0,1,1 | 2Udc/3 | 扇区 III(120°~180°) |
| U240(001) | 0,0,1 | 2Udc/3 | 扇区 IV(180°~240°) |
| U300(101) | 1,0,1 | 2Udc/3 | 扇区 V(240°~300°) |
| U360(100) | 1,0,0 | 2Udc/3 | 扇区 VI(300°~360°) |
| U7(111) | 1,1,1 | 0 | 零矢量 |
(2)扇区判断逻辑
通过 Uα、Uβ计算三个特征值,根据正负性确定扇区:
{ U1 = U_beta
{ U2 = (sqrt(3)*U_alpha - U_beta) / 2
{ U3 = -(sqrt(3)*U_alpha + U_beta) / 2
定义 A=(U1>0?1:0)、B=(U2>0?1:0)、C=(U3>0?1:0),扇区编码 N=A+2B+4C,对应关系如下:
| N 值 | 扇区 | A,B,C 状态 |
|---|
| 3 | I | 1,1,0 |
| 1 | II | 1,0,0 |
| 5 | III | 1,0,1 |
| 4 | IV | 0,0,1 |
| 6 | V | 0,1,1 |
| 2 | VI | 0,1,0 |
(3)矢量作用时间计算
根据电压矢量合成原理,非零矢量作用时间需满足:
U_ref * T = U_x * T_x + U_y * T_y + U_z * T_z
其中 T 为 PWM 周期,Tx、Ty 为相邻非零矢量作用时间,Tz 为零矢量作用时间(T0=T7=Tz/2)。以扇区 I 为例,计算公式为:
{ T_4 = (sqrt(3)*U_2*T) / U_dc
{ T_6 = (sqrt(3)*U_1*T) / U_dc
{ T_0 = T_7 = (T - T_4 - T_6) / 2
(4)PWM 占空比生成
采用七段式 SVPWM(谐波失真低),以扇区 I 为例,占空比计算如下:
value1 = (tpwm - ta - tb)/4;
value2 = value1 + ta / 2;
value3 = value2 + tb / 2;
ccr1 = value1;
ccr2 = value2;
ccr3 = value3;
三、硬件与软件实战:STM32F103 实现 FOC 控制
1. 硬件系统架构
- 主控单元:STM32F103C8T6,72MHz 主频,12 位 ADC,高级定时器 TIM1
- 功率驱动单元:三相全桥逆变器,IR2104 栅极驱动,50V/10A 功率管
- 反馈单元:分流电阻(电流采样),霍尔传感器(位置采样),运放调理电路
- 电源单元:12V 输入,5V/3.3V 稳压,过压保护
- 电机负载:400W BLDC 电机,极对数 4,额定转速 3000rpm
2. STM32CubeMX 配置流程
(1)核心配置清单
| 模块 | 配置参数 | 用途 |
|---|
| 时钟 | 外部晶振 8MHz→PLL→72MHz | 保证 ADC 与定时器同步 |
| 高级定时器 | TIM1,PWM 模式,频率 10kHz | 生成三路互补 PWM |
| ADC | 双通道,规则组,12 位分辨率 | 采样 Ia、Ib 电流 |
| GPIO | 推挽输出(驱动使能) | 控制功率桥使能信号 |
| 中断 | TIM1 更新中断(PWM 周期中断) | 触发 FOC 算法执行 |
(2)定时器与 ADC 同步关键配置
- 定时器 TIM1:计数模式向上计数,ARR=7199(10kHz 频率);
- ADC 触发源:TIM1_CH4 事件,保证电流采样与 PWM 同步;
- 死区时间:5μs(避免上下桥臂直通短路)。
3. 核心软件代码实现
(1)FOC 算法核心函数(foc.c)
#include "foc.h"
#include "math.h"
#define sqrt3 1.73205f
#define PI 3.14159f
void ClarkeTransform(float Ia, float Ib, float *Ialpha, float *Ibeta){
*Ialpha = Ia;
*Ibeta = (Ia + 2* Ib) / sqrt3;
}
void ParkTransform(float Ialpha, float Ibeta, float theta, float *Id, float *Iq){
float cos_theta = cos(theta);
float sin_theta = sin(theta);
*Id = Ialpha * cos_theta + Ibeta * sin_theta;
*Iq = -Ialpha * sin_theta + Ibeta * cos_theta;
}
void RevParkTransform(float Ud, float Uq, float theta, float *Ualpha, float *Ubeta){
float cos_theta = cos(theta);
float sin_theta = sin(theta);
*Ualpha = Ud * cos_theta - Uq * sin_theta;
*Ubeta = Ud * sin_theta + Uq * cos_theta;
}
uint8_t SectorJudge(float Ualpha, float Ubeta){
float U1 = Ubeta;
float U2 = (sqrt3 * Ualpha - Ubeta)/2.0f;
float U3 = (-sqrt3 * Ualpha - Ubeta)/2.0f;
uint8_t A = (U1 > 0)?1:0;
uint8_t B = (U2 > 0)?1:0;
uint8_t C = (U3 > 0)?1:0;
return A + 2* B + 4* C;
}
void VectorActionTime(uint8_t sector, float Ualpha, float Ubeta, uint32_t Udcbus, uint32_t tpwm, float *ta, float *tb){
float K = (sqrt3 * tpwm) / Udcbus;
float U1 = Ubeta;
float U2 = (sqrt3 * Ualpha - Ubeta)/2.0f;
float U3 = (-sqrt3 * Ualpha - Ubeta)/2.0f;
switch(sector){
case 3:
*ta = U2 * K;
*tb = U1 * K;
break;
case 1:
*ta = -U2 * K;
*tb = -U3 * K;
break;
default:
*ta = 0;
*tb = 0;
break;
}
}
void CCRCalculate(uint8_t sector, float ta, float tb, uint32_t tpwm, uint32_t *ccr1, uint32_t *ccr2, uint32_t *ccr3){
if(ta + tb > tpwm){
float scale = tpwm /(ta + tb);
ta *= scale;
tb *= scale;
}
float v1 = (tpwm - ta - tb)/4.0f;
float v2 = v1 + ta /2.0f;
float v3 = v2 + tb /2.0f;
switch(sector){
case 3:
*ccr1 = (uint32_t)v1;
*ccr2 = (uint32_t)v2;
*ccr3 = (uint32_t)v3;
break;
case 1:
*ccr1 = (uint32_t)v2;
*ccr2 = (uint32_t)v1;
*ccr3 = (uint32_t)v3;
break;
}
}
(2)主控制逻辑(main.c)
#include "stm32f1xx_hal.h"
#include "foc.h"
uint32_t tpwm = 7199;
uint32_t Udcbus = 24;
int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM1_Init();
MX_ADC1_Init();
hfoc.Id_ref = 0;
hfoc.Iq_ref = 5.0f;
hfoc.Kp_speed = 0.1f;
hfoc.Ki_speed = 0.5f;
hfoc.Kp_current = 2.0f;
hfoc.Ki_current = 10.0f;
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);
while(1){
hfoc.Ia = ADC_GetValue(ADC_CHANNEL_0);
hfoc.Ib = ADC_GetValue(ADC_CHANNEL_1);
hfoc.theta = Hall_GetAngle();
hfoc.speed = Hall_GetSpeed();
ClarkeTransform(hfoc.Ia, hfoc.Ib, &hfoc.Ialpha, &hfoc.Ibeta);
ParkTransform(hfoc.Ialpha, hfoc.Ibeta, hfoc.theta, &hfoc.Id, &hfoc.Iq);
float speed_err = hfoc.speed_ref - hfoc.speed;
hfoc.Iq_ref = PI_Controller(speed_err, &hfoc.speed_i, hfoc.Kp_speed, hfoc.Ki_speed);
float Id_err = hfoc.Id_ref - hfoc.Id;
float Iq_err = hfoc.Iq_ref - hfoc.Iq;
hfoc.Ud = PI_Controller(Id_err, &hfoc.Id_i, hfoc.Kp_current, hfoc.Ki_current);
hfoc.Uq = PI_Controller(Iq_err, &hfoc.Iq_i, hfoc.Kp_current, hfoc.Ki_current);
RevParkTransform(hfoc.Ud, hfoc.Uq, hfoc.theta, &hfoc.Ualpha, &hfoc.Ubeta);
hfoc.sector = SectorJudge(hfoc.Ualpha, hfoc.Ubeta);
VectorActionTime(hfoc.sector, hfoc.Ualpha, hfoc.Ubeta, Udcbus, tpwm, &hfoc.ta, &hfoc.tb);
CCRCalculate(hfoc.sector, hfoc.ta, hfoc.tb, tpwm, &hfoc.ccr1, &hfoc.ccr2, &hfoc.ccr3);
TIM1->CCR1 = hfoc.ccr1;
TIM1->CCR2 = hfoc.ccr2;
TIM1->CCR3 = hfoc.ccr3;
}
}
4. 算法执行时序
以 PWM 周期(100μs)为触发周期,FOC 算法的执行时序如下:
- 定时器中断触发
- ADC 模块采集电流 Ia/Ib
- FOC 算法层执行:
- Clarke 变换
- Park 变换
- 速度环 PI 计算
- 电流环 PI 计算
- Park 逆变换
- SVPWM 扇区判断
- 矢量时间与占空比计算
- 更新 CCR1/CCR2/CCR3
- 输出三相 PWM 电压
- 反馈转子位置θ
四、开发流程与状态管理
1. FOC 开发实施计划
- 准备阶段:需求分析与方案设计,硬件选型与原理图设计,PCB 绘制与打样
- 开发阶段:CubeMX 配置与底层驱动,FOC 核心算法编码调试与优化
- 验证阶段:性能测试(转矩/转速),可靠性测试(连续运行),文档整理
2. 电机运行状态管理
- 待机 -> 初始化 -> 预定位 -> 闭环运行 -> 弱磁调速 -> 停机
- 异常处理:硬件异常 -> 故障清除 -> 复位指令
五、性能测试与总结
1. 核心性能指标测试
在 24V 母线电压、5A 转矩电流条件下,测试结果如下:
- 转速范围:0~3500rpm(超额定转速 16.7%);
- 转矩脉动:<1.5%(六步换相为 8.2%);
- 动态响应:转速阶跃响应时间<50ms;
- 效率:满载时效率 92.3%(六步换相为 85.1%)。
2. 优缺点与应用场景
| 特性 | 说明 |
|---|
| 优点 | 转矩平稳、噪声低、调速范围宽、效率高 |
| 缺点 | 算法复杂、对 MCU 性能要求高(需 FPU) |
| 应用场景 | 工业机器人、无人机、电动汽车、精密机床 |
3. 进阶优化方向
- 无感 FOC 实现:通过反电动势观测器替代霍尔传感器,降低成本;
- 参数自整定:自动识别电机电阻、电感等参数,简化调试;
- 弱磁扩速优化:提升高速区转矩输出,扩大调速范围;
- 故障诊断:增加过流、过压、缺相保护,提升可靠性。
结语
FOC 控制算法是嵌入式电机控制领域的核心技术,其本质是通过数学变换实现复杂系统的解耦控制。本文从原理推导到代码实现,结合多种可视化工具拆解了 FOC 的核心逻辑,为嵌入式开发者提供清晰的学习路径。
随着 MCU 性能的提升与算法的优化,FOC 技术正从工业领域向消费电子领域渗透,掌握这一技术将为智能硬件开发提供核心竞争力。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online