1. 永磁同步电机无感FOC驱动技术概述
永磁同步电机(PMSM)因其高效率、高功率密度和优异的动态性能,在工业伺服、电动汽车和家用电器等领域得到广泛应用。而无传感器磁场定向控制(Sensorless FOC)技术通过算法估算转子位置,省去了机械传感器,显著提高了系统可靠性和降低成本。
我在工业伺服领域实践多年,发现高频注入法在零低速段的稳定性和观测器在高速段的动态响应,是工程师们最常遇到的痛点。这次开源的驱动代码正是针对这两个核心问题,实现了高频注入启动与观测器平滑切换的全速度域控制方案。
这套代码完全手写,避免了自动生成代码的冗余和低效问题。所有关键算法都用C语言逐行实现,确保在STM32等主流MCU上高效运行。代码结构采用模块化设计,方便移植到不同硬件平台,特别适合需要快速验证算法的研发团队和电机控制学习者。
2. 高频注入启动技术实现细节
2.1 高频信号注入原理
在电机静止或低速时,反电动势信号微弱难以检测。我们采用脉振高频电压注入法,在d轴注入1-2kHz的高频正弦信号。这个频率远高于基波频率,但低于PWM开关频率,确保不影响正常控制。
具体实现时,在FOC的电压输出上叠加:
c复制Vdh = Vh * sin(ωh*t);
Vqh = 0; // 只在d轴注入
其中Vh通常设为额定电压的10-15%,ωh=2πfh。我在某400W电机上实测发现,12%的注入电压能在信号强度和额外损耗间取得最佳平衡。
2.2 位置信号提取算法
电机凸极效应导致高频电流响应包含位置信息。通过带通滤波和解调处理:
c复制// 1. 采集三相电流并Clarke变换
Iα = (2*Ia - Ib - Ic)/3;
Iβ = (Ib - Ic)/√3;
// 2. 带通滤波(中心频率=ωh)
BPF(&Iαh, Iα, ωh);
BPF(&Iβh, Iβ, ωh);
// 3. 解调得到位置误差信号
ε = Iαh*cos(ωht) - Iβh*sin(ωht);
这个ε信号经过锁相环(PLL)处理,最终输出转子位置θ。实际调试时要注意,电机参数不对称会导致位置误差,需要在校准阶段补偿。
关键提示:滤波器的相位延迟会直接影响位置估算精度。建议使用IIR滤波器并精确校准群延迟,我在某项目中因忽略这点导致启动抖动,后来改用FIR滤波器后解决。
3. 滑模观测器设计与切换策略
3.1 滑模观测器数学模型
当转速超过10%额定转速后,切换到基于反电动势的滑模观测器。建立电机状态方程:
code复制diα/dt = (Vα - Rs*iα + eα)/Ls
diβ/dt = (Vβ - Rs*iβ + eβ)/Ls
其中eα、eβ为反电动势分量。设计滑模面:
code复制sα = iα_hat - iα
sβ = iβ_hat - iβ
采用符号函数作为切换控制律:
c复制eα_hat = Ks * sign(sα);
eβ_hat = Ks * sign(sβ);
Ks取值很关键,过大会引入抖振,过小则收敛慢。我的经验公式是Ks=1.2*max(反电动势)。
3.2 平滑切换逻辑实现
从高频注入切换到观测器时,采用加权过渡策略:
c复制if (ω < ω_switch_low) {
θ = θ_hfi; // 纯高频注入
} else if (ω < ω_switch_high) {
// 过渡区混合
θ = k*θ_hfi + (1-k)*θ_smo;
k = (ω_switch_high - ω)/(ω_switch_high - ω_switch_low);
} else {
θ = θ_smo; // 纯观测器
}
典型切换区间设为5%-15%额定转速。在某风机应用中,设置ω_switch_low=50rpm,ω_switch_high=150rpm时切换最平滑。
4. 代码架构与关键实现
4.1 模块化代码结构
code复制├── Drv/
│ ├── pwm.c // PWM生成与死区控制
│ └── adc.c // 同步采样处理
├── Alg/
│ ├── hfi.c // 高频注入算法
│ ├── smo.c // 滑模观测器
│ └── foc.c // 矢量变换与PI调节
└── Sys/
├── ctrl.c // 状态机与切换逻辑
└── monitor.c // 保护与诊断
特别设计了硬件抽象层(HAL),移植时只需修改Drv目录下的外设驱动。例如在STM32F4上,PWM更新采用:
c复制void PWM_Update(uint16_t uα, uint16_t uβ) {
TIM1->CCR1 = (uα + uβ)/2;
TIM1->CCR2 = (uβ - uα)/2;
// 硬件自动插入死区
}
4.2 定点数优化技巧
为提升计算效率,全部算法采用Q15格式定点数实现。例如Park变换优化为:
c复制void Park(int16_t iα, int16_t iβ, int16_t sinθ, int16_t cosθ) {
id = (iα*cosθ + iβ*sinθ) >> 15;
iq = (iβ*cosθ - iα*sinθ) >> 15;
}
通过预计算三角函数表,在STM32F103上单次FOC循环仅需12μs。
5. 实测波形与调试要点
5.1 启动过程分析
图1展示成功启动的电流波形:
- t0-t1:高频注入阶段,电流幅值约0.5A
- t1-t2:混合过渡区,转速平稳上升
- t2后:纯观测器模式,电流纹波明显减小
常见启动失败原因排查表:
| 现象 | 可能原因 | 解决措施 |
|---|---|---|
| 电机抖动不转 | 初始位置误差>30° | 加强注入信号或校准偏移 |
| 启动后失步 | 切换转速设置过高 | 降低ω_switch_high阈值 |
| 过渡区振动 | 权重系数k变化过快 | 加宽切换区间或改为S曲线过渡 |
5.2 参数自整定方法
- 电阻辨识:注入直流,Rs = Vdc / Idc
- 电感辨识:施加交流电压,Ls = Vrms / (2πf*Irms)
- 惯量辨识:阶跃速度响应,J=τ*Tq/Δω
我在代码中内置了自动辨识流程,上电后发送'M'命令即可触发。某750W电机实测参数如下:
code复制Rs = 0.82Ω Ls=2.1mH ψf=0.12Wb
6. 移植适配指南
6.1 硬件接口适配
- PWM配置:中心对齐模式,死区时间≥500ns
- ADC同步:在PWM中点触发采样
- 引脚分配示例:
c复制// STM32配置
PWM: TIM1_CH1/CH2
ADC: IN1/IN2/IN3 (三相电流)
GPIO: EN(使能), BRAKE(刹车)
6.2 性能优化建议
- 中断优先级:PWM更新>ADC采样>FOC计算
- 电流采样:推荐使用Σ-Δ ADC+数字滤波
- 对于低成本方案,可采用电阻采样+运放,但要注意共模电压范围
在某扫地机器人项目中,我们将代码移植到GD32F303,通过DMA双缓冲采样,将控制周期缩短到50μs。