2026-07-17 15:18:46 +08:00
|
|
|
|
# FOC 电机控制工程
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
## 1. 工程概述
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
本工程是基于 **TI MSPM0G3507** 微控制器的 **FOC(磁场定向控制)** 电机控制方案,用于驱动无刷直流电机(BLDC),实现高精度角度控制。
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
### 硬件平台
|
|
|
|
|
|
- **MCU**: MSPM0G3507(MSPM0系列,Cortex-M0+内核)
|
|
|
|
|
|
- **开发板**: LP_MSPM0G3507 LaunchPad
|
|
|
|
|
|
- **编码器**: MT6701(磁编码器,I2C接口,14位分辨率)
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
### 软件特性
|
|
|
|
|
|
- 完整的FOC算法实现(克拉克逆变换、帕克逆变换)
|
|
|
|
|
|
- 开环/闭环双控制模式
|
|
|
|
|
|
- 单角度环PID控制
|
|
|
|
|
|
- UART串口指令接收
|
|
|
|
|
|
- 模块化代码结构
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
---
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
## 2. 工程结构
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
```
|
|
|
|
|
|
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 # 工程文档
|
|
|
|
|
|
```
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
---
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
## 3. 核心模块说明
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
### 3.1 FOC算法 (`dfoc.c`)
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
FOC核心算法实现,包含坐标变换和控制逻辑。
|
2025-11-10 18:05:11 +08:00
|
|
|
|
|
2026-07-17 15:18:46 +08:00
|
|
|
|
**功能列表**:
|
|
|
|
|
|
|
|
|
|
|
|
| 函数 | 功能 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| `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`)
|
|
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
|
#define DEBUG_ENABLED true // 总调试开关
|
|
|
|
|
|
#define DEBUG_MT_ENABLED false // 编码器调试输出
|
|
|
|
|
|
#define DEBUG_DFOC_ENABLED false // FOC算法调试输出
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 控制模式
|
|
|
|
|
|
|
|
|
|
|
|
### 7.1 闭环角度控制(默认)
|
|
|
|
|
|
|
|
|
|
|
|
通过PID控制器实现精确角度定位:
|
|
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
|
// 主循环中调用
|
|
|
|
|
|
if(gCheckUART)
|
|
|
|
|
|
{
|
|
|
|
|
|
gCheckUART = false;
|
|
|
|
|
|
parse_uart_cmd();
|
|
|
|
|
|
Set_Angle(Target); // 闭环控制
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**控制流程**:
|
|
|
|
|
|
1. 读取编码器当前角度
|
|
|
|
|
|
2. 计算角度误差(目标角度 - 当前角度)
|
|
|
|
|
|
3. PID控制器输出Uq电压
|
|
|
|
|
|
4. 执行FOC变换,输出PWM
|
|
|
|
|
|
|
|
|
|
|
|
### 7.2 开环速度控制
|
|
|
|
|
|
|
|
|
|
|
|
直接按目标速度旋转,无位置反馈:
|
|
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
|
// 主循环中调用(需注释掉闭环代码)
|
|
|
|
|
|
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 调试
|
|
|
|
|
|
|
|
|
|
|
|
1. 连接串口到PA10/PA11(UART0)
|
|
|
|
|
|
2. 打开串口助手,波特率设置为115200
|
|
|
|
|
|
3. 发送指令格式: `T+数值+\n`,例如 `T1.57\n`
|
|
|
|
|
|
4. 观察电机响应和串口输出
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 10. 代码说明
|
|
|
|
|
|
|
|
|
|
|
|
### 10.1 编码规范
|
|
|
|
|
|
|
|
|
|
|
|
- 使用C语言编写,符合C99标准
|
|
|
|
|
|
- 变量命名: 小写+下划线(如 `voltage_limit`)
|
|
|
|
|
|
- 函数命名: 首字母大写(如 `SetPhaseVoltage`)
|
|
|
|
|
|
- 中文注释,便于理解
|
|
|
|
|
|
|
|
|
|
|
|
### 10.2 注意事项
|
|
|
|
|
|
|
|
|
|
|
|
1. 修改电机极对数时需同时修改 `empty.c` 中的 `pp` 参数
|
|
|
|
|
|
2. 编码器方向不对时调整 `Dir` 参数
|
|
|
|
|
|
3. PID参数需根据实际电机调试优化
|
|
|
|
|
|
4. 电压参数需与实际供电电压匹配
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 11. 版本信息
|
|
|
|
|
|
|
|
|
|
|
|
| 项目 | 说明 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| SDK版本 | MSPM0 SDK 2.07.00.05 |
|
|
|
|
|
|
| 编译工具 | Keil MDK |
|
|
|
|
|
|
| 目标MCU | MSPM0G3507 |
|
|
|
|
|
|
| FOC算法 | 无传感器FOC(仅位置闭环)
|