电机驱动开发学习19. 霍尔 BLDC 三段式 FOC 启动算法
电机驱动开发学习19. 霍尔 BLDC 三段式 FOC 启动算法
- 一、为什么需要三段式 FOC 启动
- 1.1 三段式启动是什么
- 1.2 与六步「三段启动」的区别
- 二、实验简介
- 2.1 本章目标
- 2.2 硬件
- 三、程序设计
- 3.1 目录结构(相对 lesson18 新增/变更)
- 3.2 状态机流程
- 阶段 1:定位(Align)
- 阶段 2:拖转(Drag)
- 阶段 3:运行(Run)
- 3.3 关键代码
- 四、调参与串口命令
- 4.1 串口(与 lesson18 相同,启动自动化)
- 4.2 FreeMASTER 建议通道
- 4.3 现场整定参数(与 `bsp_foc_boot.c` 一致)
- 五、实验现象
- 5.1 预期波形
- 5.2 VOFA+ 三通道
- 六、本章小结
一、为什么需要三段式 FOC 启动
lesson17/18 已实现速度外环 + DQ 电流内环 + SVPWM,电角度 θ 来自霍尔 6 态 + TIM5 扇区内插值。但在转子静止或极低速时,存在两个根本矛盾:
| 问题 | 原因 | 后果 |
|---|---|---|
| θ 不更新 | 霍尔只在转子转过 60° 电角度时才跳变 | Park 变换用的 θ 与实际转子位置脱节 |
| 无法直接闭环 | 电流环需要准确 θ 才能解耦 Id/Iq | 一上电就s 1/w 1,电机抖动、堵转或倒转 |
lesson16 已说明:不是 PI 公式错,而是零速时霍尔给不了连续 θ。
本章在 lesson18 工程基础上,增加工业界常用的三段式启动,解决「从静止到稳定闭环」的衔接。
硬件输出:Align/Drag 与 Run 均走六步桥单占空比(接口 2);SVPWM 仅在 Run 中作 FreeMASTER 扇区监视,不驱动三相 CCR。
1.1 三段式启动是什么
借鉴无感 BLDC「预定位 → 外同步加速 → 自同步切换」思路,结合霍尔 FOC特点,本章划分为:
| 阶段 | 英文名 | θ 来源 | 执行方式 | 目标 |
|---|---|---|---|---|
| 1 定位 | Align | 当前霍尔扇区中心 | 六步固定占空比(lesson4 开环,不用 FOC) | 转子对齐到已知扇区 |
| 2 拖转 | Drag | 软件插值 θ(扇区中心 + 步内比例) | 六步定时/边沿换相 + duty 斜坡 | 加速到霍尔边沿可靠 |
| 3 运行 | Run | 霍尔 + TIM5 插值(lesson17) | FOC 速度/电流双环+ |V|→单占空比(六步板) | 稳定闭环调速 |
说明:Align/Drag 在野火六步桥上刻意不用 InvPark/SVPWM(与真实导通相不匹配);Run 阶段才是完整 FOC 双环。SVPWM 模块仍参与扇区监视(FreeMASTER),硬件输出走 lesson17 的 |V| 映射——与 lesson11 同级 PWM 利用率,
1.2 与六步「三段启动」的区别
野火官方六步换相例程也有「定位 → 升频换相 → 霍尔闭环」,本章在此基础上叠加FOC 运行阶段:
- Align/Drag:与 lesson4 相同六步开环(定位 duty + 拖转换相序),但维护开环 θ供监视与交接;
- Drag期间
motor_set_openloop_comm()强制换相步,霍尔已跟上时可提前对齐; - Run:θ 切回霍尔插值,启用速度→Iq→电流 PI→InvPark双环,输出|V|→单占空比;
- 切换条件(
bsp_foc_boot.c,拖转满FOC_BOOT_DRAG_MIN_MS=600后,满足任一):- 霍尔边沿 ≥2且 RPM ∈ [60, target+120](下限至少到 200);
- 或强拖步数 ≥18且边沿 ≥2且 RPM 同上。
二、实验简介
2.1 本章目标
在 lesson18 工程基础上新增bsp_foc_boot.c三段式启动状态机:
w 1/s 1时自动执行 Align → Drag → Run,无需手动开环v命令;- FreeMASTER 监视
g_fm_boot_stage(0 idle / 1 align / 2 drag / 3 run / 4 fail); - 拖转失败(10 s超时)触发 fault=3 并关断;
- 运行阶段保留 lesson17速度环 + DQ 电流环;六步板上 Run 输出为 |V|→单占空比(lesson18 SVPWM 作扇区监视)。
2.2 硬件
与 lesson4~18 相同:野火骄阳 F407+无刷驱动板+霍尔 BLDC,「无刷电机驱动接口2」排线。
三、程序设计
3.1 目录结构(相对 lesson18 新增/变更)
User/ ├── foc/ │ ├── bsp_foc_boot.c/h ★ 三段式启动状态机(本章核心) │ ├── bsp_foc.c/h ★ θ 在 Align/Drag 改读开环角 │ └── bsp_svpwm.c/h (lesson18 沿用,Run 仅监视) ├── pid/ │ └── bsp_pid_app.c/h ★ 启停时触发 foc_boot_request();Run 用 |V|→duty ├── tim/ │ └── bsp_motor_tim.c/h ★ motor_set_openloop_comm() 强制换相 └── main.c3.2 状态机流程
阶段 1:定位(Align)
- 读当前霍尔态,
motor_set_openloop_comm(1, hall)强制该步六步换相; - 施加固定占空比
FOC_BOOT_ALIGN_DUTY=1200(不用 FOC / 不用 Vd)约FOC_BOOT_ALIGN_MS=500ms。
阶段 2:拖转(Drag)
- 按霍尔正转序
1→3→2→6→4→5→1定时换相(速率 4→22 Hz 斜坡)+占空比 1200→4000(每周期 +80); - 若下一霍尔态已到位,则提前同步强制换相步(转子跟上时不再盲拖);
- 切换条件见1.2(最短拖转 600 ms);超时10 s→ fail=3。
- Run 阶段才启用 FOC 双闭环(Clark/Park → PI → InvPark → |V|→duty)。
阶段 3:运行(Run)
foc_get_electrical_theta():Align/Drag 读foc_boot_get_theta(),Run/Idle 恢复霍尔 + TIM5 插值;foc_spd_poll:速度环 →g_fm_target_iq;dq_curr_poll:电流环 → Vd/Vq → InvPark →dq_apply_vmag_sixstep_output()(六步板);svpwm_calc()仅更新g_fm_svpwm_sector等监视量,不set三相独立 CCR 驱动桥臂。
3.3 关键代码
启动请求(bsp_foc_boot.c)
/** * @brief FOC三段式启动:启动请求触发函数 * @note 当系统收到电机启动指令时调用,进入三段式启动流程第一阶段【转子定位Align】 * 适用:带霍尔传感器BLDC/内置霍尔PMSM,霍尔原始扇区作为初始位置依据 * 三段式启动流程:ALIGN定位 → DRAG开环拖转 → RUN霍尔闭环FOC */voidfoc_boot_request(void){// 1. 实时读取当前霍尔电平,获取霍尔原始扇区编号(0~5 六扇区)hall=motor_hall_read_now();// 2. 将开环换相步长初始化为当前霍尔扇区// 开环拖转阶段会基于该变量持续递增实现强制换相s_openloop_step=hall;// 3. 根据当前霍尔扇区,计算该扇区中心点电角度// 目的:定位阶段向中心点角度施加恒定电压,把转子牢牢吸附到该角度s_theta=foc_boot_hall_center_theta(hall);// 4. 启动状态机切换至【转子对齐阶段 ALIGN】(三段式第1阶段)s_stage=FOC_BOOT_ALIGN;// 5. 配置开环换相模式,参数1:使能开环;hall:初始霍尔扇区基准motor_set_openloop_comm(1U,hall);// 6. 施加对齐占空比,输出恒定矢量电压,执行转子定位// 持续通电一段时间(例500ms),保证转子机械角度收敛到目标角度foc_boot_apply_duty(FOC_BOOT_ALIGN_DUTY);// ...后续省略:对齐阶段定时计时、超时后自动跳入开环拖转DRAG阶段}拖转阶段 θ 插值与切换(bsp_foc_boot.c)
/* 扇区中心 + 步内比例,供 foc_get_electrical_theta() 在 Drag 期间读取 */s_theta=foc_boot_hall_center_theta(s_openloop_step);s_theta+=(sub_ratio-0.5f)*(FOC_PI/3.0f);/* 切换:边沿≥2 且 RPM≥60,或强拖步数≥18 且边沿≥2 */if(s_hall_edges>=FOC_BOOT_HANDOVER_EDGES&&rpm>=FOC_BOOT_HANDOVER_RPM)foc_boot_enter_run();θ 来源切换(bsp_foc.c)
floatfoc_get_electrical_theta(void){if(foc_boot_is_active())/* Align / Drag */returnfoc_boot_get_theta();/* 霍尔 + TIM5 插值 ... */}开环强制换相(bsp_motor_tim.c)
if(s_openloop_comm)bldcm_commutate(s_openloop_step);elsebldcm_commutate(get_hall_state());| 模块 | lesson11 | lesson17 | lesson18 | lesson19(本章) |
|---|---|---|---|---|
| 速度外环 | ✓ 直出 PWM | ✓→Iq | ✓ | ✓(Run 阶段) |
| 输出映射 | PWM 0~5500 | |V|→单占空比 | 七段 SVPWM | Run:|V|→单占空比(六步板) |
| SVPWM | — | — | ✓ | 仅 FreeMASTER 扇区监视 |
| 电角度 | 霍尔换相 | 霍尔中心 | 霍尔+插值 | 拖转开环 θ + 运行霍尔 |
| 启动 | 无 | 无 | 无 | 三段式状态机 |
四、调参与串口命令
4.1 串口(与 lesson18 相同,启动自动化)
| 命令 | 含义 |
|---|---|
t 500 | 目标 RPM 500 |
w 1 | 开速度环(自动三段式启动 → 闭环) |
s 1 | 仅电流环(同样走三段式启动) |
s 0 | 关断并重校电流零偏 |
pid | 打印状态(含 boot_stage) |
? | 帮助 |
推荐首次上电流程:
- 上电等待
cal=1(电流零偏完成) t 500→w 1- 观察串口:
FOC boot start→align done -> drag→FOC boot handover - FreeMASTER 看
g_fm_boot_stage从 1→2→3
4.2 FreeMASTER 建议通道
| 变量 | 含义 |
|---|---|
g_fm_boot_stage | 0 idle / 1 align / 2 drag / 3 run / 4 fail |
g_fm_boot_theta_deg | 开环/运行电角度 |
g_fm_boot_omega | 拖转等效电角速度(由换相频率换算) |
g_fm_boot_hall_edges | 拖转阶段霍尔边沿计数 |
g_fm_target_rpm/g_fm_actual_rpm | 速度环(Run 后) |
g_fm_iq_actual | 拖转/运行 Iq 反馈 |
4.3 现场整定参数(与bsp_foc_boot.c一致)
| 宏 | 默认值 | 说明 |
|---|---|---|
FOC_BOOT_ALIGN_MS | 500 | 定位时间 (ms) |
FOC_BOOT_ALIGN_DUTY | 1200 | 定位六步占空比(不是Vd) |
FOC_BOOT_DRAG_DUTY_MAX | 4000 | 拖转占空比上限 |
FOC_BOOT_DRAG_DUTY_RAMP | 80 | 拖转每周期 duty 增量 |
FOC_BOOT_DRAG_RATE_INIT_HZ | 4 | 拖转换相初频 (Hz) |
FOC_BOOT_DRAG_RATE_MAX_HZ | 22 | 拖转换相最高频 |
FOC_BOOT_DRAG_MIN_MS | 600 | 允许切换前最短拖转时间 |
FOC_BOOT_HANDOVER_RPM | 60 | 切换最低 RPM |
FOC_BOOT_HANDOVER_EDGES | 2 | 切换最少霍尔边沿 |
FOC_BOOT_HANDOVER_STEPS | 18 | 强拖步数备选切换条件 |
FOC_BOOT_DRAG_TIMEOUT_MS | 10000 | 拖转超时 (ms) |
FOC_BOOT_RUN_STALL_GRACE_MS | 4000 | Run 交接后堵转保护放宽 |
README 旧稿中的
FOC_BOOT_ALIGN_VD_V/FOC_BOOT_DRAG_IQ_MA/FOC_BOOT_OMEGA_MAX在本工程中不存在(Align/Drag 不走 Vd/Iq FOC)。
常见问题:
- 拖转超时 fail=3:提高
FOC_BOOT_DRAG_DUTY_MAX/ 加快FOC_BOOT_DRAG_RATE_*,或略降FOC_BOOT_HANDOVER_RPM - Run 后转速卡在 ~350、改 t 无效:确认 Run 走的是
dq_apply_vmag_sixstep_output(|V|),不是三相 SVPWM 直驱;可t 700再w 1复测 - 仍低于 lesson11:FOC 双环有电流限幅,属正常;可略增
FOC_SPD_IQ_FF_PER_RPM或速度环kp - 转一点就停 / 彻底不转:先
s 0再t 600+w 1;查看是否 Stall;交接后4 s内堵转保护放宽 - 定位时反转:检查霍尔线序与
MOTOR_FWD方向
五、实验现象
5.1 预期波形
- Align(~500 ms):θ 恒定,六步duty=1200,转子轻微锁定;
- Drag(0.5数 s):θ 随换相步进爬升,
g_fm_boot_omega随换相频率上升,霍尔边沿计数递增; - Run:
g_fm_boot_stage=3,RPM 跟踪g_fm_target_rpm,Iq 由电流环调节。
5.2 VOFA+ 三通道
- 速度模式:
RPM_SP / RPM_ACT / Iq - 电流模式:
Iq_SP / Iq_ACT / PWM
六、本章小结
| 要点 | 内容 |
|---|---|
| 问题 | 零速时霍尔 θ 不更新,无法直接 FOC 闭环 |
| 方案 | Align 六步定位 → Drag 六步开环拖转 → Run 霍尔 FOC(|V|→duty) |
| 新增文件 | bsp_foc_boot.c/h |
| 改动点 | bsp_foc.cθ 切换、bsp_motor_tim.c开环换相、bsp_pid_app.c启停挂钩与 |V| 输出 |
| 下一章 | lesson20:迁到接口 1,Align/Drag/Run 全程真 SVPWM(不是无感观测器) |
至此,野火霍尔 BLDC接口 2上的FOC 双闭环 + 可靠三段启动链路已完整。。
