
TI MSPM0G3507开发板串口通信实战基于SysConfig与中断的UART0收发实验很多刚开始接触TI MSPM0系列单片机的朋友尤其是准备电赛的同学都会卡在串口通信这一步。看着手册里一堆寄存器不知道从哪下手。今天我就以手头的这块MSPM0G3507电赛开发板为例带大家走一遍完整的流程——从图形化工具配置到代码编写实现一个“你发什么我回什么”的串口回环实验。咱们不用死磕寄存器用TI官方提供的SysConfig工具点点鼠标就能搞定大部分配置把精力集中在代码逻辑上。这个实验会用到板载的CH340E USB转串口芯片你只需要一根Type-C数据线连接电脑和开发板就能在电脑上用串口调试助手和单片机“对话”了。1. 实验准备认识我们的硬件与工具在开始动手前咱们先搞清楚要用的东西。硬件连接很简单开发板上已经集成了CH340E芯片它负责把电脑USB信号转换成单片机能懂的串口信号。这个芯片已经连接到了单片机特定的两个引脚上PA10: 这是UART0的接收引脚RX负责接收来自电脑的数据。PA11: 这是UART0的发送引脚TX负责向电脑发送数据。所以你只需要用Type-C线连接开发板和电脑硬件部分就准备好了不需要自己额外接线。软件工具链Keil MDK: 咱们写代码和编译下载的IDE。TI SysConfig: 一个图形化的配置工具集成在Keil里用来配置时钟、外设引脚、工作模式等它能自动生成初始化代码省去我们手动查手册、算参数的麻烦。工程准备你需要从TI官方SDK包里找到一个针对G3507的“empty”空白工程模板。把它复制到你的SDK根目录下然后用Keil打开。这一步很关键因为工程路径关系到配置文件能否正确找到。注意原始教程特别强调空白工程必须复制到SDK的根目录下否则后续SysConfig工具可能会找不到相关文件而报错。2. 手把手配置用SysConfig点亮串口打开工程后咱们的重点就是那个empty.syscfg文件。双击它Keil会打开SysConfig的图形界面。接下来咱们像搭积木一样把串口需要的各个部分配置好。2.1 第一步给串口配上时钟单片机的外设就像一个个小机器要让它们动起来必须先接通“电源”——也就是时钟。MSPM0G3507的串口时钟可以从三个来源选BUSCLK主系统时钟默认是32MHz速度快。MFCLK固定的4MHz时钟需要专门开启。LFCLK32KHz的低速时钟用于低功耗场景。我们这个实验选择**MFCLK4MHz**作为串口时钟。原因很简单4MHz的时钟频率在配置9600这类常用波特率时计算出来的分频系数比较整齐误差小。配置步骤在SysConfig左侧找到SYSCTL选项。在右侧勾选Use Clock Tree这会启用时钟树配置界面。界面顶部会出现三个图标点击中间那个像“波形图”的图标进入时钟树视图。找到SYSOSC_4M这一路点击上面的开关块把它打开。当右边显示“4.0000MHz”时就说明MFCLK时钟已经开启了。2.2 第二步添加并设置UART0外设时钟有了现在来配置串口本身。在左侧外设列表中找到UART点击ADD按钮添加一个UART实例。在右侧的参数面板中我们需要设置几个关键参数Instance: 选择UART0对应我们硬件连接的PA10和PA11。Baud Rate: 设为9600。这是最常用的波特率和电脑串口调试助手保持一致就行。Data Length: 选择8 bits。一个字节8位是标准配置。Stop Bits: 选择1 bit。Parity Type: 选择None不用校验位。Hardware Flow Control: 选择None我们不用RTS/CTS这些流控引脚。高级设置Oversampling这个参数很重要它叫“过采样率”。选项有3、8、16。简单理解这个值越高抗时钟误差的能力越强但也会限制最高波特率。我们的时钟是4MHz波特率9600分频系数不是整数为了避免误差这里按照教程建议选择16。SysConfig工具很智能如果你选的参数导致无法计算出有效的分频系数它会报错这时你就需要调整波特率或Oversampling值。配置中断我们打算让单片机在收到数据时立刻打断主程序去处理这就需要中断。在配置页找到中断设置勾选Receive Interrupt接收中断。这样每当UART0收到一个字节就会触发一次中断。引脚分配最后告诉芯片哪个物理引脚用作串口。在Pinmux引脚复用设置里为UART0 RX选择PA10为UART0 TX选择PA11。SysConfig通常会自动根据你的选择高亮对应的引脚检查一下是否正确。2.3 第三步可选加个LED当“心跳”第一次做实验为了确认程序在跑咱们可以再加个LED闪烁功能当作系统的心跳指示灯。 在SysConfig中找到GPIO选项添加一个GPIO输出比如连接到板上的一个用户LED教程示例中是PIN_22。配置它为输出模式。这样我们在主循环里让它闪烁如果下载后LED闪了至少说明程序基本运行起来了。保存并生成代码所有配置完成后点击保存。回到Keil点击编译按钮。这时SysConfig会自动根据你的图形化配置生成对应的C语言初始化代码主要在ti_msp_dl_config.c/.h文件里。编译无误硬件配置部分就大功告成了3. 编写代码让串口“活”起来配置工具帮我们生好了“骨架”现在需要我们自己编写“灵魂”——也就是应用程序逻辑。我们打开empty.c这个主文件。3.1 主函数main的编写主函数里要做三件事初始化系统、设置中断、然后让LED闪起来。#include ti_msp_dl_config.h // 定义一个简单的毫秒延时函数基于CPU频率循环 #define delay_ms(X) delay_cycles((CPUCLK_FREQ/1000)*(X)); // 定义全局变量用于在中断和主程序间传递数据 volatile unsigned char uart_data 0; int main(void) { // 1. 初始化这行代码至关重要它调用了SysConfig生成的所有初始化函数。 SYSCFG_DL_init(); // 2. 串口中断配置 // 先清除可能存在的旧中断标志避免一开中断就误触发 NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN); // 使能打开UART0的中断开关 NVIC_EnableIRQ(UART_0_INST_INT_IRQN); // 3. 主循环让LED闪烁证明程序在运行 while(1) { DL_GPIO_setPins(LED1_PORT, LED1_PIN_22_PIN); // LED亮 delay_ms(500); DL_GPIO_clearPins(LED1_PORT, LED1_PIN_22_PIN); // LED灭 delay_ms(500); } }3.2 编写串口发送函数虽然接收用中断但发送我们可以先写两个辅助函数发送一个字符和发送一个字符串。// 发送单个字符 void uart0_send_char(char ch) { // 等待串口发送器空闲。这是为了防止数据覆盖。 // 比如上一个字节A还没发完就急着发B会导致数据丢失。 while( DL_UART_isBusy(UART_0_INST) true ); // 发送字符 DL_UART_Main_transmitData(UART_0_INST, ch); } // 发送字符串基于发送字符函数 void uart0_send_string(char* str) { // 判断字符串是否有效且未到结尾 while(*str ! 0 str ! 0) { uart0_send_char(*str); // 发送当前字符 str; // 指针移动到下一个字符 } }3.3 核心串口中断服务函数这是本实验的关键。当串口收到数据时硬件会自动跳转到这个函数执行。// UART0的中断服务函数函数名是固定的不能改 void UART_0_INST_IRQHandler(void) { // 获取是哪种中断触发了本次调用 switch( DL_UART_getPendingInterrupt(UART_0_INST) ) { case DL_UART_IIDX_RX: // 如果是接收中断 // 1. 从接收数据寄存器中读取刚刚收到的字节 uart_data DL_UART_Main_receiveData(UART_0_INST); // 2. 立刻将这个字节原样发送回去回环 uart0_send_char(uart_data); break; default: // 其他类型的中断如发送完成中断本例中不处理 break; } }重要提示中断函数的名字UART_0_INST_IRQHandler是芯片启动文件里定义好的必须一模一样。你可以在工程目录下的.s汇编启动文件里找到它或者在 SysConfig 生成的ti_msp_dl_config.h头文件里看到它的宏定义。4. 实验验证与结果代码写完后编译、下载到开发板下载方法参考环境搭建章节。打开电脑上的串口调试助手如XCOM、SSCOM等进行如下设置选择正确的串口号电脑设备管理器中查看CH340生成的COM口波特率9600数据位8停止位1校验位无在发送框输入任意字符或字符串点击发送。你应该能在接收框里看到开发板原封不动返回的数据。同时开发板上的LED在规律闪烁。实验现象你在调试助手发“Hello”接收区就会显示“Hello”。这就实现了一个最简单的串口回环Echo功能证明了串口收发通路完全正确。5. 进阶如何使用printf函数直接调用uart0_send_string虽然可以但不如printf用起来方便。下面教你如何将printf重定向到我们的串口0。方法一使用微库简单但占用内存稍多在Keil的Target Options - Target 中勾选Use MicroLIB。在empty.c中重写fputc函数#include stdio.h int fputc(int ch, FILE *stream) { while( DL_UART_isBusy(UART_0_INST) true ); DL_UART_Main_transmitData(UART_0_INST, ch); return ch; }之后就可以直接在代码里用printf(Value: %d\r\n, value);了。方法二使用半主机模式更节省资源如果觉得微库占用大可以改用此方法取消勾选Use MicroLIB。在Target Options - C/C 中优化等级选择-O2。在empty.c中除了上面的fputc函数还需添加以下代码#if !defined(__MICROLIB) #if (__ARMCLIB_VERSION 6000000) struct __FILE { int handle; }; #endif FILE __stdout; void _sys_exit(int x) { x x; } #endif同样需要#include stdio.h。两种方法都可以根据你的项目对内存的敏感程度来选择。做完这一步你的串口调试输出就会变得非常方便了。好了以上就是基于SysConfig和中断实现MSPM0G3507串口通信的完整流程。整个过程的核心思路是用图形化工具解决复杂的硬件配置问题而我们则专注于编写业务逻辑代码。这种开发方式效率高不易出错特别适合初学者和快速原型开发。遇到问题多检查串口参数是否一致、中断函数名是否正确、以及时钟是否成功开启。