diff --git a/README.md b/README.md
index ce86fb3..1719caf 100644
--- a/README.md
+++ b/README.md
@@ -1,41 +1,308 @@
-## Example Summary
+# FOC 电机控制工程
-Empty project using DriverLib.
-This example shows a basic empty project using DriverLib with just main file
-and SysConfig initialization.
+## 1. 工程概述
-## Peripherals & Pin Assignments
+本工程是基于 **TI MSPM0G3507** 微控制器的 **FOC(磁场定向控制)** 电机控制方案,用于驱动无刷直流电机(BLDC),实现高精度角度控制。
-| Peripheral | Pin | Function |
-| --- | --- | --- |
-| SYSCTL | | |
-| DEBUGSS | PA20 | Debug Clock |
-| DEBUGSS | PA19 | Debug Data In Out |
+### 硬件平台
+- **MCU**: MSPM0G3507(MSPM0系列,Cortex-M0+内核)
+- **开发板**: LP_MSPM0G3507 LaunchPad
+- **编码器**: MT6701(磁编码器,I2C接口,14位分辨率)
-## BoosterPacks, Board Resources & Jumper Settings
+### 软件特性
+- 完整的FOC算法实现(克拉克逆变换、帕克逆变换)
+- 开环/闭环双控制模式
+- 单角度环PID控制
+- UART串口指令接收
+- 模块化代码结构
-Visit [LP_MSPM0G3507](https://www.ti.com/tool/LP-MSPM0G3507) for LaunchPad information, including user guide and hardware files.
+---
-| Pin | Peripheral | Function | LaunchPad Pin | LaunchPad Settings |
-| --- | --- | --- | --- | --- |
-| PA20 | DEBUGSS | SWCLK | N/A |
- PA20 is used by SWD during debugging
- `J101 15:16 ON` Connect to XDS-110 SWCLK while debugging
- `J101 15:16 OFF` Disconnect from XDS-110 SWCLK if using pin in application
|
-| PA19 | DEBUGSS | SWDIO | N/A | - PA19 is used by SWD during debugging
- `J101 13:14 ON` Connect to XDS-110 SWDIO while debugging
- `J101 13:14 OFF` Disconnect from XDS-110 SWDIO if using pin in application
|
+## 2. 工程结构
-### Device Migration Recommendations
-This project was developed for a superset device included in the LP_MSPM0G3507 LaunchPad. Please
-visit the [CCS User's Guide](https://software-dl.ti.com/msp430/esd/MSPM0-SDK/latest/docs/english/tools/ccs_ide_guide/doc_guide/doc_guide-srcs/ccs_ide_guide.html#sysconfig-project-migration)
-for information about migrating to other MSPM0 devices.
+```
+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 # 工程文档
+```
-### Low-Power Recommendations
-TI recommends to terminate unused pins by setting the corresponding functions to
-GPIO and configure the pins to output low or input with internal
-pullup/pulldown resistor.
+---
-SysConfig allows developers to easily configure unused pins by selecting **Board**→**Configure Unused Pins**.
+## 3. 核心模块说明
-For more information about jumper configuration to achieve low-power using the
-MSPM0 LaunchPad, please visit the [LP-MSPM0G3507 User's Guide](https://www.ti.com/lit/slau873).
+### 3.1 FOC算法 (`dfoc.c`)
-## Example Usage
+FOC核心算法实现,包含坐标变换和控制逻辑。
-Compile, load and run the example.
+**功能列表**:
+
+| 函数 | 功能 |
+|------|------|
+| `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(仅位置闭环)
\ No newline at end of file
diff --git a/empty.syscfg b/empty.syscfg
index fa56caf..2e1736d 100644
--- a/empty.syscfg
+++ b/empty.syscfg
@@ -1,8 +1,8 @@
/**
* These arguments were used when this file was generated. They will be automatically applied on subsequent loads
* via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
- * @cliArgs --device "MSPM0G350X" --part "Default" --package "LQFP-48(PT)" --product "mspm0_sdk@2.07.00.05"
- * @v2CliArgs --device "MSPM0G3507" --package "LQFP-48(PT)" --product "mspm0_sdk@2.07.00.05"
+ * @cliArgs --device "MSPM0G350X" --part "Default" --package "VQFN-32(RHB)" --product "mspm0_sdk@2.07.00.05"
+ * @v2CliArgs --device "MSPM0G3507" --package "VQFN-32(RHB)" --product "mspm0_sdk@2.07.00.05"
* @versions {"tool":"1.25.0+4268"}
*/
@@ -11,16 +11,18 @@
*/
const GPIO = scripting.addModule("/ti/driverlib/GPIO", {}, false);
const GPIO1 = GPIO.addInstance();
+const GPIO2 = GPIO.addInstance();
const I2C = scripting.addModule("/ti/driverlib/I2C", {}, false);
const I2C1 = I2C.addInstance();
+const MATHACL = scripting.addModule("/ti/driverlib/MATHACL");
+const MCAN = scripting.addModule("/ti/driverlib/MCAN", {}, false);
+const MCAN1 = MCAN.addInstance();
const PWM = scripting.addModule("/ti/driverlib/PWM", {}, false);
const PWM1 = PWM.addInstance();
const SYSCTL = scripting.addModule("/ti/driverlib/SYSCTL");
const SYSTICK = scripting.addModule("/ti/driverlib/SYSTICK");
const TIMER = scripting.addModule("/ti/driverlib/TIMER", {}, false);
const TIMER1 = TIMER.addInstance();
-const UART = scripting.addModule("/ti/driverlib/UART", {}, false);
-const UART1 = UART.addInstance();
/**
* Write custom configuration values to the imported modules.
@@ -37,6 +39,9 @@ gate7.enable = true;
const multiplier2 = system.clockTree["PLL_QDIV"];
multiplier2.multiplyValue = 4;
+const mux2 = system.clockTree["CANCLKMUX"];
+mux2.inputSelect = "CANCLKMUX_PLLCLK1_OUT";
+
const mux4 = system.clockTree["EXHFMUX"];
mux4.inputSelect = "EXHFMUX_XTAL";
@@ -46,24 +51,36 @@ mux8.inputSelect = "HSCLKMUX_SYSPLL2X";
const mux12 = system.clockTree["SYSPLLMUX"];
mux12.inputSelect = "zSYSPLLMUX_HFCLK";
-const pinFunction4 = system.clockTree["HFXT"];
-pinFunction4.enable = true;
-pinFunction4.inputFreq = 40;
+const pinFunction4 = system.clockTree["HFXT"];
+pinFunction4.enable = true;
+pinFunction4.inputFreq = 40;
+pinFunction4.peripheral.$assign = "SYSCTL";
+pinFunction4.peripheral.hfxInPin.$assign = "PA5";
+pinFunction4.peripheral.hfxOutPin.$assign = "PA6";
-GPIO1.$name = "LED";
-GPIO1.associatedPins[0].$name = "PA0";
-GPIO1.associatedPins[0].pin.$assign = "PA0";
+GPIO1.$name = "GPIO_GRP_0";
+GPIO1.port = "PORTA";
+GPIO1.associatedPins[0].$name = "PIN_0";
+GPIO1.associatedPins[0].direction = "INPUT";
+GPIO1.associatedPins[0].pin.$assign = "PA14";
const Board = scripting.addModule("/ti/driverlib/Board", {}, false);
Board.peripheral.$assign = "DEBUGSS";
Board.peripheral.swclkPin.$assign = "PA20";
Board.peripheral.swdioPin.$assign = "PA19";
+GPIO2.$name = "GPIO_GRP_1";
+GPIO2.port = "PORTA";
+GPIO2.associatedPins[0].$name = "PIN_1";
+GPIO2.associatedPins[0].direction = "INPUT";
+GPIO2.associatedPins[0].pin.$assign = "PA15";
+
I2C1.$name = "I2C_1";
I2C1.advAnalogGlitchFilter = "DISABLED";
I2C1.basicEnableController = true;
-I2C1.peripheral.sdaPin.$assign = "PB3";
-I2C1.peripheral.sclPin.$assign = "PB2";
+I2C1.peripheral.$assign = "I2C1";
+I2C1.peripheral.sdaPin.$assign = "PA16";
+I2C1.peripheral.sclPin.$assign = "PA17";
I2C1.sdaPinConfig.hideOutputInversion = scripting.forceWrite(false);
I2C1.sdaPinConfig.onlyInternalResistor = scripting.forceWrite(false);
I2C1.sdaPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
@@ -73,6 +90,13 @@ I2C1.sclPinConfig.onlyInternalResistor = scripting.forceWrite(false);
I2C1.sclPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
I2C1.sclPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric3";
+MCAN1.$name = "MCAN0";
+MCAN1.peripheral.$assign = "CANFD0";
+MCAN1.peripheral.rxPin.$assign = "PA27";
+MCAN1.peripheral.txPin.$assign = "PA26";
+MCAN1.txPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric7";
+MCAN1.rxPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric8";
+
PWM1.$name = "PWM_0";
PWM1.ccIndex = [0,1,2];
PWM1.clockDivider = 2;
@@ -83,14 +107,14 @@ PWM1.PWM_CHANNEL_1.$name = "ti_driverlib_pwm_PWMTimerCC1";
PWM1.ccp0PinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric4";
PWM1.ccp1PinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric5";
PWM1.peripheral.$assign = "TIMA0";
-PWM1.peripheral.ccp0Pin.$assign = "PA21";
-PWM1.peripheral.ccp1Pin.$assign = "PA22";
-PWM1.peripheral.ccp2Pin.$assign = "PB20";
+PWM1.peripheral.ccp0Pin.$assign = "PA8";
+PWM1.peripheral.ccp1Pin.$assign = "PA9";
+PWM1.peripheral.ccp2Pin.$assign = "PA10";
PWM1.PWM_CHANNEL_2.$name = "ti_driverlib_pwm_PWMTimerCC2";
PWM1.ccp2PinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric6";
SYSCTL.forceDefaultClkConfig = true;
-SYSCTL.peripheral.$assign = "SYSCTL";
+SYSCTL.clockTreeEn = true;
SYSTICK.periodEnable = true;
SYSTICK.systickEnable = true;
@@ -105,41 +129,5 @@ TIMER1.timerClkSrc = "LFCLK";
TIMER1.timerPeriod = "1";
TIMER1.peripheral.$assign = "TIMG0";
-UART1.$name = "UART_0";
-UART1.rxFifoThreshold = "DL_UART_RX_FIFO_LEVEL_ONE_ENTRY";
-UART1.targetBaudRate = 115200;
-UART1.uartClkDiv = "8";
-UART1.enableFIFO = true;
-UART1.txFifoThreshold = "DL_UART_TX_FIFO_LEVEL_ONE_ENTRY";
-UART1.enabledDMATXTriggers = "DL_UART_DMA_INTERRUPT_TX";
-UART1.enabledInterrupts = ["DMA_DONE_RX"];
-UART1.enabledDMARXTriggers = "DL_UART_DMA_INTERRUPT_RX";
-UART1.peripheral.$assign = "UART0";
-UART1.peripheral.rxPin.$assign = "PA11";
-UART1.peripheral.txPin.$assign = "PA10";
-UART1.txPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric0";
-UART1.rxPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric1";
-UART1.DMA_CHANNEL_TX.$name = "DMA_CH0";
-UART1.DMA_CHANNEL_TX.addressMode = "b2f";
-UART1.DMA_CHANNEL_TX.srcLength = "BYTE";
-UART1.DMA_CHANNEL_TX.dstLength = "BYTE";
-UART1.DMA_CHANNEL_TX.peripheral.$assign = "DMA_CH0";
-UART1.DMA_CHANNEL_RX.$name = "DMA_CH1";
-UART1.DMA_CHANNEL_RX.addressMode = "f2b";
-UART1.DMA_CHANNEL_RX.srcLength = "BYTE";
-UART1.DMA_CHANNEL_RX.dstLength = "BYTE";
-UART1.DMA_CHANNEL_RX.transferMode = "FULL_CH_REPEAT_SINGLE";
-
const ProjectConfig = scripting.addModule("/ti/project_config/ProjectConfig", {}, false);
ProjectConfig.migrationCondition = true;
-
-/**
- * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
- * version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to
- * re-solve from scratch.
- */
-pinFunction4.peripheral.$suggestSolution = "SYSCTL";
-pinFunction4.peripheral.hfxInPin.$suggestSolution = "PA5";
-pinFunction4.peripheral.hfxOutPin.$suggestSolution = "PA6";
-I2C1.peripheral.$suggestSolution = "I2C1";
-UART1.DMA_CHANNEL_RX.peripheral.$suggestSolution = "DMA_CH1";