1. 项目概述
作为一名从事电机控制算法开发多年的工程师,今天我想分享一个基于国产SWM190 Cortex-M0内核MCU的永磁同步电机(PMSM)无感FOC控制方案。这个方案已经在风机产品中实现量产,包含完整的源码和原理图,特别适合需要进行电机控制算法研究或产品开发的同行参考。
这个方案有几个突出的特点:
- 采用无位置传感器设计,通过龙伯格观测器实现转子位置和速度估算
- 专门针对风机应用优化,具备顺风/逆风启动能力
- 完整的三电阻电流采样方案
- 支持SVPWM调制,包含五段式和七段式两种调制方式
- 模块化设计,便于移植到其他MCU平台
2. 系统架构与控制流程
2.1 整体架构设计
整个系统采用分层模块化设计,主要包含以下几个部分:
- 电机控制核心:实现FOC算法,包括Clarke/Park变换、PI调节器等
- 状态观测器:基于龙伯格观测器的无感算法实现
- 电流/速度闭环:双闭环控制结构
- 故障保护模块:过压、欠压、堵转等保护功能
- 用户接口:支持线控和红外遥控
- 底层驱动:ADC、PWM、GPIO等硬件驱动
2.2 控制主循环详解
系统以PWM载波频率为基准执行控制循环,典型流程如下:
-
电流采样:
- 通过ADC采集两相电流(Ia, Ib)
- 第三相电流通过基尔霍夫定律计算:Ic = -Ia - Ib
- 采样时机选择在PWM中点,以消除开关噪声影响
-
Clarke变换:
c复制Iα = Ia Iβ = (Ia + 2*Ib)/sqrt(3) -
Park变换:
c复制Id = Iα*cosθ + Iβ*sinθ Iq = -Iα*sinθ + Iβ*cosθ其中θ为观测器估算的电角度
-
闭环控制:
- 速度环:根据目标转速与实际转速的误差,通过PI调节器输出Iq_ref
- 电流环:分别调节Id和Iq到目标值,输出Vd和Vq
-
反Park变换:
c复制Vα = Vd*cosθ - Vq*sinθ Vβ = Vd*sinθ + Vq*cosθ -
SVPWM调制:
- 将Vα、Vβ转换为三相PWM占空比
- 支持五段式和七段式调制
-
观测器更新:
- 根据当前电压、电流更新转子位置和速度估算值
关键点:整个控制循环必须在PWM周期中断内完成,通常要求在10-20μs内完成所有计算,这对M0内核的运算能力是个挑战。
3. 核心算法实现
3.1 龙伯格观测器设计
龙伯格观测器是本方案的核心技术,其实现原理如下:
-
建立电机模型:
PMSM在α-β坐标系下的电压方程:code复制Vα = Rs*Iα + Ls*dIα/dt - ω*ψf*sinθ Vβ = Rs*Iβ + Ls*dIβ/dt + ω*ψf*cosθ其中ψf为永磁体磁链
-
观测器方程:
code复制dÎα/dt = (Vα - Rs*Îα + K1*(Iα-Îα))/Ls + ω̂*ψf*sinθ̂ dÎβ/dt = (Vβ - Rs*Îβ + K1*(Iβ-Îβ))/Ls - ω̂*ψf*cosθ̂其中K1为观测器增益
-
位置估算:
通过反电动势误差计算角度:code复制θ̂ = atan2(-Eα, Eβ)其中Eα = ω̂ψfsinθ̂,Eβ = -ω̂ψfcosθ̂
实际代码实现中,我们使用Q15定点数格式来优化运算效率,关键函数包括:
c复制void STO_CalcElAngle(void) {
// 观测器核心计算
// ...
}
void STO_Init(void) {
// 观测器初始化
// ...
}
3.2 启动策略优化
风机应用的特殊性在于停机后可能因自然风导致转子转动,我们设计了自适应启动策略:
-
初始定位阶段:
- 施加固定电压矢量(如U相导通)100-200ms
- 将转子拉至已知位置
-
开环加速阶段:
- 以固定斜率增加开环频率
- 同时监测观测器输出的速度估算值
- 电流限制在安全范围内
-
方向检测:
- 比较观测器速度方向与开环旋转方向
- 如果相反,则调整开环旋转方向
-
闭环切换:
- 当观测器速度稳定且达到阈值(通常为额定速度的5-10%)
- 平滑过渡到闭环控制
关键实现代码在状态机中:
c复制typedef enum {
MOTOR_STOP,
ALIGNMENT,
OPEN_LOOP,
CLOSE_LOOP,
FAULT
} MotorState;
void MC_StateMachine(void) {
switch(currentState) {
case ALIGNMENT:
// 初始定位处理
break;
case OPEN_LOOP:
// 开环加速处理
break;
// ...
}
}
4. 关键实现细节
4.1 三电阻采样方案
在低成本应用中,我们采用三电阻采样方案:
-
采样电阻布局:
- 在下桥臂串联采样电阻
- 通常选择50-100mΩ阻值
-
采样时机:
- 在PWM周期中点进行采样
- 需要精确计算采样窗口
-
电流重构:
- 根据PWM状态选择有效的采样值
- 通过基尔霍夫定律计算第三相电流
ADC配置示例:
c复制void ADC_Config(void) {
// 配置ADC为定时器触发
// 设置采样通道和采样时间
// 配置DMA传输
}
4.2 SVPWM实现
空间矢量PWM的实现要点:
-
基本矢量:
- 定义6个非零矢量和2个零矢量
- 计算各矢量的作用时间
-
五段式调制:
- 每个PWM周期有5个段
- 开关损耗较小
-
七段式调制:
- 每个PWM周期有7个段
- 谐波特性更好
实现代码框架:
c复制void SVPWM_Gen(float Vα, float Vβ) {
// 扇区判断
// 矢量作用时间计算
// 比较值计算
// 更新PWM寄存器
}
4.3 定点数优化
针对M0内核无FPU的特点,我们采用Q格式定点数优化:
-
Q15格式:
- 表示范围:-1到0.999969
- 精度:2^-15
-
常用运算:
- 乘法:使用__SMULBB等CMSIS指令
- 除法:转换为乘法运算
-
PI调节器实现:
c复制typedef struct {
int32_t Kp; // Q15格式
int32_t Ki; // Q15格式
int32_t OutMax; // 输出限幅
int32_t Sum; // 积分项
} PI_Controller;
int32_t PI_Calc(PI_Controller *pi, int32_t error) {
pi->Sum += error * pi->Ki;
// 积分限幅
int32_t out = (error * pi->Kp) >> 15;
out += (pi->Sum >> 15);
// 输出限幅
return out;
}
5. 保护机制与调试技巧
5.1 多级保护设计
-
电压保护:
- 过压阈值:通常设为额定电压的115%
- 欠压阈值:通常设为额定电压的85%
-
电流保护:
- 硬件过流:通过比较器实现快速保护
- 软件过流:ADC采样值超过阈值
-
温度保护:
- 监测MOSFET温度
- 超过阈值降额运行或停机
保护状态机实现:
c复制void FLT_CheckFault(void) {
if(VDC > OverVoltageThreshold) {
SetFault(FAULT_OVERVOLTAGE);
}
// 其他故障检查...
}
void FLT_HandleFault(void) {
// 立即关闭PWM输出
// 记录故障代码
// 进入保护状态
}
5.2 调试经验分享
-
观测器调试:
- 先从开环运行开始,确认观测器能正确估算速度
- 逐步调整观测器增益,确保动态响应和稳定性
-
PI参数整定:
- 先调电流环,再调速度环
- 电流环响应速度应比速度环快5-10倍
-
启动参数优化:
- 开环加速斜率影响启动成功率
- 切换闭环时的速度阈值需要根据负载调整
-
常见问题排查:
- 电机抖动:检查观测器参数或电流采样
- 启动失败:调整开环参数或检查方向检测
- 过流保护:检查电流采样电路或PWM死区
6. 性能优化与移植指南
6.1 针对M0内核的优化
-
编译器优化:
- 使用-O2或-O3优化等级
- 关键函数添加__RAMFUNC修饰符
-
查表法优化:
- 三角函数使用查表法
- 平方根运算使用近似算法
-
中断优化:
- 控制循环放在PWM中断中
- 非实时任务放在主循环
6.2 移植到其他平台
-
硬件抽象层:
- 封装PWM、ADC、GPIO等硬件操作
- 提供统一的接口函数
-
平台相关代码:
- 时钟配置
- 中断优先级设置
- 外设初始化
-
性能评估:
- 测试控制循环执行时间
- 评估CPU负载率
移植检查清单:
- [ ] PWM模块配置
- [ ] ADC采样配置
- [ ] 定时器中断配置
- [ ] 硬件接口适配
- [ ] 编译器兼容性检查
在实际项目中,这个方案已经成功应用于多个风机产品,实现了稳定的无感FOC控制。特别是在顺逆风启动方面表现优异,大大提高了产品可靠性。通过模块化设计,我们也顺利将其移植到了多个不同型号的MCU平台上。