FOC 电机控制工程
1. 工程概述
本工程是基于 TI MSPM0G3507 微控制器的 FOC(磁场定向控制) 电机控制方案,用于驱动无刷直流电机(BLDC),实现高精度角度控制。
硬件平台
- MCU: MSPM0G3507(MSPM0系列,Cortex-M0+内核)
- 开发板: LP_MSPM0G3507 LaunchPad
- 编码器: MT6701(磁编码器,I2C接口,14位分辨率)
软件特性
- 完整的FOC算法实现(克拉克逆变换、帕克逆变换)
- 开环/闭环双控制模式
- 单角度环PID控制
- UART串口指令接收
- 模块化代码结构
2. 工程结构
FOC/
├── 3rd/ # 第三方模块
│ ├── dfoc.c/h # FOC核心算法
│ ├── mt6701.c/h # MT6701编码器驱动
│ ├── pid_control.c/h # PID控制器
│ ├── pwm.c/h # PWM输出控制
│ ├── lowpass_filter.c/h # 低通滤波器
│ ├── uart_redircet.c/h # printf重定向
│ ├── delay.c/h # 延时函数
│ └── config.h # 调试配置
├── keil/ # Keil工程文件
│ ├── empty_LP_MSPM0G3507_nortos_keil.uvprojx
│ ├── mspm0g3507.sct
│ └── startup_mspm0g350x_uvision.s
├── empty.c # 主程序入口
├── empty.syscfg # SysConfig配置文件
├── ti_msp_dl_config.c/h # SysConfig生成的配置代码
└── README.md # 工程文档
3. 核心模块说明
3.1 FOC算法 (dfoc.c)
FOC核心算法实现,包含坐标变换和控制逻辑。
功能列表:
| 函数 | 功能 |
|---|---|
SetPhaseVoltage() |
帕克逆变换 + 克拉克逆变换,计算三相电压 |
SetPwm() |
将电压转换为占空比,输出PWM |
electricAngle() |
计算电气角度 |
normalizeAngle() |
角度归一化到0~2π |
constrain() |
幅值限幅 |
FOC_Init() |
FOC初始化,校准零电角度 |
Set_Angle() |
单角度环闭环控制 |
velocityopenloop() |
开环速度控制 |
关键参数:
| 参数 | 值 | 说明 |
|---|---|---|
voltage_limit |
8V | 输出电压限幅 |
voltage_power_supply |
12.0V | 供电电压 |
3.2 编码器驱动 (mt6701.c)
MT6701磁编码器驱动,通过I2C接口读取角度数据。
特性:
- 通信方式: I2C(从设备地址0x06)
- 分辨率: 14位(16384脉冲/圈)
- 支持单圈/多圈角度读取
函数列表:
| 函数 | 功能 |
|---|---|
MT6701_iic_read_angel() |
I2C读取原始角度数据 |
GetAngle_NoTrack() |
获取单圈角度(弧度) |
GetAngle() |
获取多圈累计角度(弧度) |
GetVelocity() |
计算角速度 |
3.3 PID控制器 (pid_control.c)
增量式PID控制器实现。
参数:
- Kp: 0.067(比例系数)
- Ki: 0.01(积分系数)
- Kd: 0(微分系数)
- 输出限幅: ±5.0
- 积分限幅: ±5.0
3.4 PWM控制 (pwm.c)
3路独立PWM输出控制。
配置:
- 定时器: TIMA0
- 频率: 15kHz
- 通道: 3路
- 引脚: PA21, PA22, PB20
3.5 UART重定向 (uart_redircet.c)
将标准printf重定向到UART,支持串口调试输出。
4. 通信接口
4.1 UART指令接口
- 波特率: 115200
- 数据位: 8位
- 停止位: 1位
- 校验: 无
指令格式: T+数值+\n
| 示例 | 说明 |
|---|---|
T1.57\n |
设置目标角度为1.57弧度 |
T-0.785\n |
设置目标角度为-0.785弧度 |
接收机制:
- DMA方式接收6字节数据包
- 接收完成触发中断,解析指令并更新目标角度
4.2 I2C编码器接口
- 速度: 100kHz
- 用于读取MT6701编码器角度数据
5. 主程序流程
main()
│
├─→ SYSCFG_DL_init() // 初始化所有硬件外设
├─→ DMA配置 // 配置UART接收DMA
├─→ NVIC_EnableIRQ() // 使能UART和定时器中断
├─→ DL_TimerA_startCounter() // 启动PWM定时器
├─→ DL_TimerG_startCounter() // 启动通用定时器
├─→ FOC_Init(12.6) // FOC初始化,校准零电角度
│
└─→ while(1)
├─→ 检查gCheckUART标志
├─→ 解析UART命令 → 更新Target
└─→ Set_Angle(Target) // 执行闭环控制
中断服务函数:
| 中断 | 功能 |
|---|---|
TIMER_0_INST_IRQHandler |
定时器中断(调试用,LED闪烁,打印目标值) |
UART_0_INST_IRQHandler |
UART DMA接收完成中断,设置接收标志 |
6. 关键配置参数
6.1 电机参数 (empty.c)
| 参数 | 值 | 说明 |
|---|---|---|
pp |
7 | 电机极对数 |
Dir |
-1 | 电机方向(-1为反转,1为正转) |
6.2 系统时钟 (ti_msp_dl_config.h)
| 参数 | 值 | 说明 |
|---|---|---|
CPUCLK_FREQ |
32MHz | CPU系统时钟 |
PWM_0_INST_CLK_FREQ |
16MHz | PWM定时器时钟 |
6.3 调试配置 (config.h)
#define DEBUG_ENABLED true // 总调试开关
#define DEBUG_MT_ENABLED false // 编码器调试输出
#define DEBUG_DFOC_ENABLED false // FOC算法调试输出
7. 控制模式
7.1 闭环角度控制(默认)
通过PID控制器实现精确角度定位:
// 主循环中调用
if(gCheckUART)
{
gCheckUART = false;
parse_uart_cmd();
Set_Angle(Target); // 闭环控制
}
控制流程:
- 读取编码器当前角度
- 计算角度误差(目标角度 - 当前角度)
- PID控制器输出Uq电压
- 执行FOC变换,输出PWM
7.2 开环速度控制
直接按目标速度旋转,无位置反馈:
// 主循环中调用(需注释掉闭环代码)
velocityopenloop(Target);
8. 引脚分配
8.1 PWM输出
| 通道 | 引脚 | 功能 |
|---|---|---|
| PWM CH0 | PA21 | U相 |
| PWM CH1 | PA22 | V相 |
| PWM CH2 | PB20 | W相 |
8.2 I2C编码器
| 引脚 | 功能 |
|---|---|
| PB2 | I2C_SCL |
| PB3 | I2C_SDA |
8.3 UART
| 引脚 | 功能 |
|---|---|
| PA10 | UART_TX |
| PA11 | UART_RX |
8.4 其他
| 引脚 | 功能 |
|---|---|
| PA0 | LED |
| PA19 | SWDIO |
| PA20 | SWCLK |
9. 使用方法
9.1 编译
使用Keil MDK打开 keil/empty_LP_MSPM0G3507_nortos_keil.uvprojx 工程文件,编译生成固件。
9.2 烧录
通过XDS-110调试器将固件烧录到LP_MSPM0G3507开发板。
9.3 调试
- 连接串口到PA10/PA11(UART0)
- 打开串口助手,波特率设置为115200
- 发送指令格式:
T+数值+\n,例如T1.57\n - 观察电机响应和串口输出
10. 代码说明
10.1 编码规范
- 使用C语言编写,符合C99标准
- 变量命名: 小写+下划线(如
voltage_limit) - 函数命名: 首字母大写(如
SetPhaseVoltage) - 中文注释,便于理解
10.2 注意事项
- 修改电机极对数时需同时修改
empty.c中的pp参数 - 编码器方向不对时调整
Dir参数 - PID参数需根据实际电机调试优化
- 电压参数需与实际供电电压匹配
11. 版本信息
| 项目 | 说明 |
|---|---|
| SDK版本 | MSPM0 SDK 2.07.00.05 |
| 编译工具 | Keil MDK |
| 目标MCU | MSPM0G3507 |
| FOC算法 | 无传感器FOC(仅位置闭环) |
Description
Languages
C
81%
Assembly
19%