ti板例程1学习

📅 2026/7/19 3:39:58 👁️ 阅读次数 📝 编程学习
ti板例程1学习

2026-07-18 电赛ti板例程1学习:empty_project_led

一、今日目标

  • 跑通例程1(LED闪烁),验证Keil + J-Link + MSPM0G3507 链路
  • 完成基础拓展(改延时、单独控制RGB三色)
  • 尝试SysConfig换引脚,初步理解IOMUX复用机制
  • 记录学习过程中的问题与概念连接

二、环境确认

项目状态备注
Keil MDK✅ 正常已安装TI MSPM0支持包
J-Link驱动✅ 正常昨天更新过
核心板连接✅ 正常SWD四线连接
例程工程编译✅ 0 Error, 0 Warning直接打开1_empty_project_led.uvprojx

硬件:无名创新24年电赛H题小车套件,MSPM0G3507核心板


三、例程1核心代码分析

3.1 main.c 完整结构

#include"ti_msp_dl_config.h"// SysConfig生成的配置头文件#defineDELAY(16000000)// 循环计数,决定延时长短intmain(void){SYSCFG_DL_init();// 一键初始化:时钟、GPIO、电源等while(1){delay_cycles(DELAY);// 空转延时DL_GPIO_togglePins(PORTB_PORT,PORTB_RGB_R_PIN|PORTB_RGB_G_PIN|PORTB_RGB_B_PIN);}}

3.2 代码元素逐行拆解

代码元素作用对应STM32标准库关键理解
#include "ti_msp_dl_config.h"包含SysConfig生成的配置头无(直接写寄存器或用HAL)TI把配置封装成宏,不用手动记寄存器地址
SYSCFG_DL_init()调用SysConfig生成的总初始化函数RCC_APB2PeriphClockCmd()+GPIO_Init()一键完成时钟使能+引脚复用+方向配置
delay_cycles(DELAY)阻塞式空转延时for(i=0; i<delay; i++);纯软件延时,CPU在此期间空转
DL_GPIO_togglePins()翻转引脚电平GPIO_WriteBit()高变低,低变高
PORTB_PORT宏定义,对应GPIOBGPIOBTI用PORTB_PORT代替GPIOB
PORTB_RGB_R_PIN宏定义,对应PB26GPIO_Pin_26具体引脚号封装在宏里

3.3 SysConfig生成的配置解读

ti_msp_dl_config.h关键宏:

#definePORTB_PORT(GPIOB)#definePORTB_RGB_R_PIN(DL_GPIO_PIN_26)#definePORTB_RGB_R_IOMUX(IOMUX_PINCM57)#definePORTB_RGB_G_PIN(DL_GPIO_PIN_27)#definePORTB_RGB_G_IOMUX(IOMUX_PINCM58)#definePORTB_RGB_B_PIN(DL_GPIO_PIN_22)#definePORTB_RGB_B_IOMUX(IOMUX_PINCM50)#defineCPCLK_FREQ(32000000)// 32MHz主频

核心理解——IOMUX的作用:

物理引脚PB26 → IOMUX_PINCM57 → 可以连到GPIO/PWM/UART/ADC... ↑ SysConfig在这里配置

Codex的原话:“如果你不理解IOMUX决定了一个物理引脚到底连到GPIO还是PWM/UART,那么你就无法解释:为什么把PB26改成PWM输出时,必须在SysConfig里重新配置,而不是只改代码里的API。”


四、拓展练习详细记录

拓展1:修改延时时间

操作:修改DELAY宏定义,重新编译烧录,观察LED闪烁频率

DELAY值理论计算实际现象验证结论
1600000016000000 / 32MHz = 0.5sLED约0.5秒闪烁一次✅ 基准正确
80000008000000 / 32MHz = 0.25sLED闪烁加快✅ 时间减半
3200000032000000 / 32MHz = 1sLED闪烁变慢✅ 时间翻倍

关键公式:

延时时间(秒) = DELAY / CPCLK_FREQ = DELAY / 32000000

理解delay_cycles()就是让CPU空转N个时钟周期。32MHz主频下,1600万个周期 = 0.5秒。

对比STM32:以前用for(i=0; i<0xFFFFF; i++);这种魔法数字,现在用delay_cycles(16000000),语义更清晰。


拓展2:单独控制RGB三色

目标:实现红灯亮0.5s → 绿灯亮0.5s → 蓝灯亮0.5s → 循环

代码:

while(1){// 状态1:红灯亮DL_GPIO_setPins(PORTB_PORT,PORTB_RGB_R_PIN);DL_GPIO_clearPins(PORTB_PORT,PORTB_RGB_G_PIN|PORTB_RGB_B_PIN);delay_cycles(DELAY);// 状态2:绿灯亮DL_GPIO_clearPins(PORTB_PORT,PORTB_RGB_R_PIN);DL_GPIO_setPins(PORTB_PORT,PORTB_RGB_G_PIN);DL_GPIO_clearPins(PORTB_PORT,PORTB_RGB_B_PIN);delay_cycles(DELAY);// 状态3:蓝灯亮DL_GPIO_clearPins(PORTB_PORT,PORTB_RGB_R_PIN|PORTB_RGB_G_PIN);DL_GPIO_setPins(PORTB_PORT,PORTB_RGB_B_PIN);delay_cycles(DELAY);}

API对比表:

操作MSPM0 DriverLibSTM32标准库
置高电平DL_GPIO_setPins(port, pin)GPIO_SetBits(GPIOx, GPIO_Pin)
置低电平DL_GPIO_clearPins(port, pin)GPIO_ResetBits(GPIOx, GPIO_Pin)
翻转电平DL_GPIO_togglePins(port, pin)GPIO_WriteBit(GPIOx, Pin, Bit_SET/RESET)
读取电平DL_GPIO_readPins(port, pin)GPIO_ReadInputDataBit(GPIOx, GPIO_Pin)

命名习惯差异:

  • TI用set/clear/read/toggle,动词在前
  • ST用SetBits/ResetBits/ReadInputDataBit/WriteBit,更强调寄存器操作

拓展3:SysConfig换引脚

操作步骤:

  1. 打开empty_project_led.syscfg(SysConfig图形化配置界面)
  2. 在GPIO配置面板中,找到RGB_R的配置
  3. 将引脚从PB26改为PA0(或其他可用引脚)
  4. 点击Save→ 自动生成ti_msp_dl_config.cti_msp_dl_config.h
  5. 回到Keil,编译 → 烧录 → 观察现象

遇到的问题:

现象尝试的引脚结果
LED正常闪烁PB26(原配置)✅ 正常
LED不亮PA0❌ 不亮
LED不亮某些其他PB引脚❌ 不亮

初步分析(待验证):

可能原因1:IOMUX未配置为GPIO模式

  • 在SysConfig里选了PA0,但可能没把复用功能(MUX)设为GPIO
  • 需要检查生成的代码中DL_GPIO_initDigitalOutput()的参数

可能原因2:该引脚被其他功能占用

  • MSPM0G3507某些引脚默认是调试口(SWD)、晶振口(XIN/XOUT)或电源脚
  • 需要查数据手册确认引脚功能表

可能原因3:物理连接问题

  • 核心板上PA0没有接LED,或者接了其他外设
  • 需要用万用表量引脚电平确认

关键教训:

在MSPM0上,“选了引脚"不等于"能用GPIO”。必须同时确认:

  1. SysConfig里该引脚的IOMUX设为GPIO模式
  2. 该引脚物理上没有被其他功能(调试口、晶振等)占用
  3. 该引脚在硬件上连接了你想要的设备(LED)

五、概念连接:状态机

5.1 从例程1发现状态机

例程1的LED闪烁,如果显式写出状态,就是一个极简状态机

uint8_tled_state=0;// 0=灭, 1=亮while(1){if(led_state==0){DL_GPIO_setPins(PORTB_PORT,PORTB_RGB_R_PIN);// 动作:亮led_state=1;// 转移:灭→亮}else{DL_GPIO_clearPins(PORTB_PORT,PORTB_RGB_R_PIN);// 动作:灭led_state=0;// 转移:亮→灭}delay_cycles(DELAY);// 条件:延时到期才转移}
当前状态触发条件下一个状态执行动作
LED灭(0)延时到期LED亮(1)setPins
LED亮(1)延时到期LED灭(0)clearPins

5.2 与上学期经验的连接

上学期循迹小车——隐式状态机:

// 没有状态变量,状态藏在条件判断里while(1){if(传感器==黑线)直走();elseif(传感器==偏左)右转();elseif(传感器==偏右)左转();else停止();}
当前状态谁决定的状态转移条件
直走传感器实时读数传感器==偏左 → 右转
右转传感器实时读数传感器==黑线 → 直走

特点:无记忆性,当前状态完全由传感器实时决定,不需要记住"之前在哪"。


H题代码——显式状态机:

// duty1:从A点出发,循迹到B点,声光提示voidauto_drive_smartcar_duty1(void){staticuint8_tn=8;// 任务编号if(flight_subtask_cnt[n]==0){// 状态0:初始化speed_ctrl_mode=1;trackless_output.yaw_ctrl_mode=ROTATE;flight_subtask_cnt[n]=1;// 转移到状态1}elseif(flight_subtask_cnt[n]==1){// 状态1:行驶中distance_control_with_speed_limit(50);if(ABS(distance_ctrl.error)<distance_precision_cm){flight_subtask_cnt[n]=2;// 条件满足,转移到状态2}}else{// 状态2:到达,声光提示speed_expect[0]=0;// 停止电机speed_expect[1]=0;bling_set(&light_red,2000,500,0.5,0,0);// 红灯闪烁beep.reset=1;beep.times=2;}}
状态值含义转移条件动作
0初始化无条件设置速度、启动循迹 → 进入状态1
1行驶中distance_ctrl.error < 1cm距离控制、速度控制 → 到达后进入状态2
2到达提示无(结束)停止电机、红灯闪烁、蜂鸣器响

特点:有记忆性,必须记住"走到哪一步了",状态转移是单向的(0→1→2)。


5.3 隐式 vs 显式状态机对比

维度隐式状态机(循迹小车)显式状态机(H题代码)
状态记录无状态变量,状态藏在if-elseflight_subtask_cnt[n]显式记录
状态转移双向/多向,传感器变就跳单向,0→1→2,不回头
记忆性无记忆,只看当前输入有记忆,必须知道"之前在哪"
适用场景响应式、实时反馈(循迹)流程式、时序控制(A→B→C)
代码复杂度状态少时简单状态多时更清晰,易扩展
调试难度难,不知道卡在哪个逻辑分支易,看cnt值就知道在哪一步

5.4 为什么H题必须用显式状态机

H题需求隐式能否满足显式如何解决
"从A到B"是固定流程❌ 不能靠传感器实时判断cnt记录步骤,按顺序执行
需要记住"已经启动过"❌ 无记忆cnt=1表示"已启动,正在行驶"
多个任务(duty1~4)共享调度❌ 每个任务逻辑混杂✅ 每个任务有自己的cnt数组
非阻塞执行(不能卡死)while循环会阻塞✅ 每个状态执行一次,立即返回

六、今日问题清单

序号问题描述当前状态优先级下一步行动
1换引脚后LED不亮的具体原因?🔍 待验证查MSPM0G3507数据手册引脚功能表;用万用表量引脚电平
2IOMUX_PINCMx和物理引脚号的对应关系?🔍 待理解阅读数据手册IOMUX章节;对比SysConfig生成的前后代码
3哪些引脚"确定可用"作GPIO输出?🔍 待整理整理一份48引脚封装的安全GPIO清单
4delay_cycles的精确性如何?受中断影响吗?🔍 待验证对比例程8的systick精准延时
5状态机从隐式到显式的改写练习📝 待做把上学期循迹代码改成显式状态机版本

七、下一步学习计划

近期(下周)

优先级任务目标预计时间
P0跑通例程10(keyscan)理解GPIO输入、按键消抖1-2天
P0跑通例程8(systick)理解精准延时、替代delay_cycles1天
P1确认"换引脚不亮"原因查数据手册,整理安全引脚清单半天
P1跑通例程6(timer_period)理解定时器中断、周期触发1-2天

中期(暑假)

里程碑目标标志
M1跑完前5个例程1, 10, 8, 6, 7
M2让电机转起来用例程7输出PWM,控制左右轮
M3建立速度闭环例程14编码器测速 + 例程7 PWM
M4接触H题代码骨架提取电机驱动层,理解状态机调度

八、今日感悟与模式记录

学习节奏

“进度太快跟不上” → 主动刹车 → 记录消化 → 下周继续

这个节奏比"一天刷完5个例程但只记得最后一个"效率高得多。

验证ISTP学习模式

  • ✅ 边做边调整(跑例程→发现问题→定向查资料)
  • ✅ 问题导向补理论(不前置灌输,遇到卡点再深入)
  • ✅ 最小闭环验证(每个例程跑通+改参数+确认现象)

工具链使用

工具今日用途效果
Keil编译、烧录、调试熟悉,无卡点
SysConfig图形化配置GPIO、IOMUX新接触,换引脚时遇到复用问题
J-Link程序下载昨天已配好,今日顺畅
Codex扫描24个例程、生成学习路径输出质量高,已建立信任
Kimi实时答疑、概念连接、记录整理长期陪伴,理解上下文

关键认知更新

  1. IOMUX是TI的灵魂:不是选了引脚就能用,必须理解复用配置
  2. 状态机不是新概念:上学期已经用过,只是不知道名字
  3. 显式状态机的价值:在"流程式任务"(A→B→C)中,记忆性是必须的
  4. Codex的边界:适合代码扫描、路径规划;Kimi适合实时对话、概念连接

记录时间:2026-07-18 17:53
下次学习:2026-07-21(周一)