1. 项目概述
作为一名从事电机控制开发多年的工程师,我深知永磁同步电机(PMSM)矢量控制(FOC)系统开发的难点。今天要分享的这套WYB-FOC-PMSM-XB-V2开源工程,是我在实际产品开发中提炼出的精华版本,特别适合那些已经学习FOC理论但苦于无法落地的开发者。
这套代码基于TI的TMS320F28335 DSP平台开发,采用旋变作为位置传感器,实现了完整的三闭环(电流、速度、位置)矢量控制。与市面上常见的"玩具级"代码不同,这套方案已经通过工业产品的验证,代码架构清晰,注释详尽,特别注重工业应用中的实际问题。
2. 硬件架构解析
2.1 核心硬件选型
主控芯片选用TI的C2000系列旗舰型号TMS320F28335,主要考虑其强大的浮点运算能力和丰富的外设资源:
- 150MHz主频,32位浮点单元
- 16通道12位ADC,采样速率12.5MSPS
- 18路PWM输出,支持死区插入
- 多路SPI、SCI、CAN接口
位置传感器采用AD2S1210旋变解码芯片,相比光电编码器具有更好的抗干扰能力,特别适合工业环境。旋变的多对极设计(通常5-7对极)提供了更高的位置分辨率。
2.2 功率驱动设计
驱动部分采用典型的三相全桥拓扑:
- IGBT模块选用1200V/50A规格
- 栅极驱动采用隔离型驱动芯片如ADuM4136
- 电流采样使用霍尔传感器,带宽>100kHz
- 母线电压采样采用电阻分压+运放调理
PCB设计为4层板,特别注意:
- 功率地和信号地分开布局
- PWM走线等长处理
- 模拟信号远离数字噪声源
3. 软件架构设计
3.1 分层架构
整个软件采用分层设计,从下到上分为:
- 驱动层:直接操作寄存器,包括PWM、ADC、SPI等外设
- 数学层:实现Clarke/Park变换、SVPWM等算法
- 控制层:三闭环PID控制算法
- 应用层:指令解析、通信协议等
这种架构保证了代码的可移植性,更换硬件平台时只需修改驱动层。
3.2 实时调度机制
系统以8kHz(125μs)为基本时钟节拍,通过软件计数器实现多任务调度:
- 125μs:电流环控制、SVPWM更新
- 1ms:速度环控制
- 2ms:位置环控制
- 10ms:故障检测、状态上报
所有实时任务都在中断中完成,主循环仅处理非实时任务如通信协议解析。
4. 核心算法实现
4.1 电流采样与处理
三相电流通过两个霍尔传感器采样(IU、IW),IV通过计算得到:
c复制void GetIPhase() {
IPhase.Iunew = AdcRegs.ADCRESULT0 >> 4; // 12bit转16bit
IPhase.Iwnew = AdcRegs.ADCRESULT1 >> 4;
// 电流标幺化处理,1pu=25A
IPhase.Iu = (IPhase.Iunew - IPhase.Iuoffset) * 0.0007273f;
IPhase.Iw = (IPhase.Iwnew - IPhase.Iwoffset) * 0.0007273f;
IPhase.Iv = -IPhase.Iu - IPhase.Iw; // 三相平衡
}
关键点:
- ADC结果需要减去偏置(offset)
- 系数0.0007273=1/(25A55A/V3.3V/4096)由传感器变比决定
- 采样时刻严格对准PWM周期中点
4.2 坐标变换
Clarke变换将三相静止坐标系转换为两相静止坐标系:
c复制void ClarkeTransform() {
Ia = Iu;
Ib = (Iv - Iw) * 0.57735027f; // 1/sqrt(3)
}
Park变换将静止坐标系转换为旋转坐标系:
c复制void ParkTransform() {
Id = Ia * COS_elec + Ib * SIN_elec;
Iq = Ib * COS_elec - Ia * SIN_elec;
}
注意:电角度θ需要根据极对数和机械角度计算得到。
4.3 SVPWM实现
SVPWM算法将电压矢量转换为PWM占空比:
c复制void FocSvpwm() {
// 电压矢量归一化
Ualpha *= 1.73205081f * 0.5f; // sqrt(3)/2
Ubeta *= 0.5f;
// 扇区判断
sector = (Ualpha > 0) ? 1 : 0;
sector += (Ubeta > 0) ? 2 : 0;
sector += (fabs(Ubeta) > 0.866f*fabs(Ualpha)) ? 4 : 0;
// 计算各相占空比
switch(sector) {
case 1: // 扇区I
Ta = 0.5f + (Ualpha - Ubeta);
Tb = 0.5f + Ubeta;
Tc = 0.5f - (Ualpha + Ubeta);
break;
// 其他扇区类似...
}
}
5. 控制环路设计
5.1 电流环设计
电流环是内环,直接影响系统动态性能:
c复制void CurrentLoopPI() {
// d轴PI
err_d = IdRef - Id;
integral_d += Ki_d * err_d;
integral_d = Saturate(integral_d, LIMIT_D);
Ud = Kp_d * err_d + integral_d;
// q轴PI
err_q = IqRef - Iq;
integral_q += Ki_q * err_q;
integral_q = Saturate(integral_q, LIMIT_Q);
Uq = Kp_q * err_q + integral_q;
}
调试要点:
- 先调d轴,再调q轴
- Kp决定响应速度,Ki消除静差
- 积分限幅防止windup
5.2 速度环设计
速度环周期1ms,输出作为q轴电流给定:
c复制void SpeedLoopPI() {
err = SpeedRef - Speed;
integral += Ki_s * err;
integral = Saturate(integral, LIMIT_S);
IqRef = Kp_s * err + integral;
}
调试技巧:
- 先调Kp使系统稳定
- 再调Ki提高抗扰能力
- 注意限幅值要小于电流环限幅
5.3 位置环设计
位置环周期2ms,输出作为速度给定:
c复制void PositionLoopPI() {
err = PosRef - Pos;
integral += Ki_p * err;
integral = Saturate(integral, LIMIT_P);
SpeedRef = Kp_p * err + integral;
}
应用场景:
- 伺服定位控制
- 需要前馈补偿提高响应速度
6. 通信协议实现
6.1 串口通信协议
帧格式:14字节固定长度
code复制[Head1][Data1...Data12][Check]
典型指令:
- 0xCC:运行模式指令
- 0x55:测试模式指令
- 0xBB:参数调整指令
6.2 CAN通信协议
采用29位扩展帧,250kbps波特率:
code复制ID[31:16]:指令码
ID[15:0]:节点地址
Data[0:7]:参数数据
常用指令:
- 0x4D4F("MO"):电机启动
- 0x4D46("MF"):电机停止
7. 调试技巧与经验
7.1 旋变零位校准
- 将转子机械定位到d轴位置
- 读取AD2S1210输出的原始角度值
- 将该值写入ElecThetaOffset变量
- 重新编译程序
7.2 电流环快速调试
- 通过上位机发送BB指令进入调参模式
- 设置IdRef=0.1pu(约2.5A)
- 逐步增加Kp直到出现轻微超调
- 调整Ki使阶跃响应快速且无静差
- 重复上述过程调试q轴
7.3 常见问题排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 电机振动大 | 电流采样相位错误 | 检查采样时刻是否对准PWM中点 |
| 速度波动大 | 速度环PI参数不当 | 降低Kp或增加Ki |
| 定位不准 | 旋变零位偏差 | 重新校准零位 |
| 过流保护 | 死区时间不足 | 增加DBRED/DBFED寄存器值 |
8. 性能优化建议
- 启用CLA协处理器处理电流环,可降低CPU负载约30%
- 使用IQmath库替代浮点运算,提高计算效率
- 优化中断服务程序,减少不必要的计算
- 采用预测电流控制提高动态响应
- 增加前馈补偿改善跟踪性能
9. 移植到其他平台
移植到不同硬件平台时需要注意:
- 修改GPIO引脚定义
- 根据电流传感器规格调整标幺系数
- 适配不同的位置传感器接口
- 调整PWM频率和死区时间
- 修改时钟初始化代码
对于STM32平台,主要改动在驱动层,算法层可以完全复用。
10. 开发工具链
推荐使用以下工具进行开发:
- 编译器:TI CCS v5及以上
- 调试器:XDS100v2或XDS510
- 上位机:基于Qt开发的监控软件
- 仿真:MATLAB/Simulink模型验证
这套代码经过实际产品验证,在工业伺服、电动汽车、机器人等领域都有成功应用案例。通过系统学习和实践,开发者可以在1-2个月内掌握完整的FOC开发技能。