
TI MSPM0G3507开发板串口通信实战基于CH340E与UART0的收发中断配置详解最近在带几个刚接触嵌入式的新手做项目发现大家拿到TI的MSPM0G3507开发板后第一个想玩的就是串口通信。毕竟这是单片机跟电脑“对话”最直接的方式调试信息、控制指令都靠它。但很多朋友在配置串口特别是用中断接收数据时总会遇到各种小问题。今天我就以这块板子为例手把手带你走一遍完整的串口配置流程重点讲讲如何用中断实现可靠的数据收发。跟着做一遍你就能掌握这个嵌入式开发中最基础也最重要的技能。1. 先聊聊串口它是什么为什么重要在开始动手前咱们得先搞清楚串口到底是什么。你可以把它想象成一条数据“单行道”但这条道很窄一次只能通过一辆“车”一个比特位。数据是一位接一位排着队发送的。虽然速度比不上并行的“八车道”但它的优点是接线简单只需要两根线一根发一根收加一根地线就能实现双向通信成本低抗干扰能力还强适合长距离传输。要让两个设备通过串口聊上天它们必须事先约定好“暗号”这就是通信参数波特率好比说话的速度。两边必须用同样的语速否则就听不清了。常见的有9600、115200等表示每秒传输的比特数。数据位每个“字”由几位二进制数组成通常是8位一个字节。停止位用来表示一个“字”说完了通常是1位。校验位一个简单的纠错机制检查这个“字”在传输过程中有没有出错可以选奇校验、偶校验或者不用。咱们的MSPM0G3507芯片内部有4个串口UART0到UART3。开发板上已经贴心地集成了一颗CH340E芯片它的作用就是把电脑USB接口的信号转换成单片机UART能理解的TTL电平信号。这样你只需要一根Type-C数据线连接电脑和开发板就完成了硬件连接非常方便。注意CH340E芯片连接到了芯片的PA10和PA11这两个引脚而这两个引脚正好是UART0的发送TX和接收RX脚。所以咱们这次实验就用UART0。2. 实战开始用SysConfig工具配置UART0理论说再多不如动手。TI为MSPM0系列提供了强大的图形化配置工具——SysConfig它集成在Keil MDK开发环境里能帮我们自动生成底层驱动代码大大节省时间。2.1 创建与打开工程首先在Keil中打开SDK里提供的empty空白工程。然后在工程目录里找到并双击empty.syscfg文件。当这个文件在Keil编辑器中打开后你会在编辑器上方看到一个“Open SysConfig”的按钮点击它就能启动图形化的配置界面了。2.2 配置串口时钟源单片机里任何外设要工作都得有时钟驱动串口也不例外。MSPM0G3507的串口时钟有三个来源BUSCLK主系统时钟默认32MHz。MFCLK固定的4MHz时钟。LFCLK32.768kHz的低速时钟用于低功耗模式。我们这个实验选择**MFCLK4MHz**作为时钟源。为什么因为用固定的低频时钟来计算波特率分频值更准确误差小。配置步骤如下在SysConfig界面左侧找到并点击SYSCTL选项。在右侧详情页中勾选Use Clock Tree来启用时钟树配置。这时界面左侧会出现三个图标点击中间那个像“树状图”的图标进入时钟树视图。找到SYSOSC_4M这一路分支点击上面的开关块将其打开。当右侧显示频率变为4.0000 MHz时就说明MFCLK时钟已经成功开启了。2.3 添加并配置UART外设现在来配置主角——UART0。在左侧外设列表中找到并点击UART。点击ADD按钮来添加一个UART实例默认就是UART0。在右侧的配置面板中我们进行如下设置Basic Configuration基本配置Baud Rate:9600(一个很常用的速率)Data Length:8 bitsStop Bits:1 bitParity Type:NoneHardware Flow Control:None(我们不用硬件流控)Advanced Configuration高级配置这里有个关键参数Oversampling过采样率。它和时钟精度有关为了在4MHz时钟下精确产生9600波特率我们选择16。简单理解选这个值能让SysConfig正确计算出分频系数不报错。Interrupt Configuration中断配置勾选RX Interrupt接收中断。这样每当串口收到一个字节数据就会触发一次中断我们的程序就能立刻去处理。Pin Configuration引脚配置在引脚分配图上找到PA10和PA11分别将其功能设置为UART0 RX和UART0 TX。这步至关重要它把芯片内部的UART0信号引到了具体的物理引脚上从而连接到CH340E芯片。全部配置好后点击保存按钮。回到Keil点击编译SysConfig会自动根据你的图形化配置生成对应的C代码头文件和源文件。3. 编写代码实现中断收发与回传配置工具帮我们做好了底层设置但“收到数据后具体干什么”还得我们自己写代码。我们要实现的功能是开发板收到电脑发来的任意字符马上通过串口把这个字符原样发回给电脑这叫“回显”。3.1 了解中断服务函数的名字用中断就得写中断服务函数。这个函数的名字是固定的不能乱改否则中断发生时程序找不到入口。 有两种方法可以查到UART0的中断函数名查看工程里的.s启动文件里面列出了所有中断的入口。更简单的方法是打开SysConfig生成的头文件ti_msp_dl_config.h搜索UART0你会找到类似#define UART_0_INST_IRQHandler ...的宏这就是中断函数名。3.2 编写主程序与中断函数接下来在包含main()函数的文件比如empty.c中编写以下代码。我会在关键地方加上注释。#include ti_msp_dl_config.h // 定义两个全局变量用于延时和存储串口数据 volatile unsigned int delay_times 0; volatile unsigned char uart_rx_data 0; // 函数声明 void delay_ms(unsigned int ms); void uart0_send_char(char ch); int main(void) { // 初始化系统这行代码包含了SysConfig生成的所有外设初始化配置 SYSCFG_DL_init(); // 关键步骤1清除UART0可能已有的旧中断标志避免一开中断就误触发 NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN); // 关键步骤2使能打开UART0的中断 NVIC_EnableIRQ(UART_0_INST_INT_IRQN); // 主循环里让一个LED闪烁表明程序在运行 while (1) { DL_GPIO_setPins(LED1_PORT, LED1_PIN_14_PIN); // LED亮 delay_ms(500); DL_GPIO_clearPins(LED1_PORT, LED1_PIN_14_PIN); // LED灭 delay_ms(500); } } // 利用SysTick系统滴答定时器实现的毫秒级延时函数 void delay_ms(unsigned int ms) { delay_times ms; while(delay_times ! 0); } // 串口发送单个字符的函数 void uart0_send_char(char ch) { // 发送前先检查串口是否忙上一字节是否发完避免数据覆盖丢失 while(DL_UART_isBusy(UART_0_INST) true); // 发送字符 DL_UART_Main_transmitData(UART_0_INST, ch); } // SysTick中断服务函数用于递减延时计数 void SysTick_Handler(void) { if(delay_times ! 0) { delay_times--; } } // 核心UART0的中断服务函数 void UART_0_INST_IRQHandler(void) { // 首先判断是哪种串口中断 switch(DL_UART_getPendingInterrupt(UART_0_INST)) { case DL_UART_IIDX_RX: // 如果是接收中断 // 从接收数据寄存器中读取刚刚收到的字节 uart_rx_data DL_UART_Main_receiveData(UART_0_INST); // 将收到的字节立刻发送回去回显 uart0_send_char(uart_rx_data); break; default: // 其他类型的中断如发送完成中断本例中不处理 break; } }代码要点解析中断的开启光在SysConfig里勾选中断不够必须在main函数里用NVIC_EnableIRQ函数显式地打开中断开关。开启前先用NVIC_ClearPendingIRQ清一下标志位是个好习惯。发送的“忙等待”uart0_send_char函数里的while(DL_UART_isBusy(...))这行很重要。串口发送一个字节需要时间这行代码的作用就是等上一个字节完全发出去后才把新字节放入发送寄存器。没有这个等待连续发送数据时会丢失。中断的处理在UART_0_INST_IRQHandler函数中我们用switch语句判断中断来源。DL_UART_IIDX_RX表示是接收数据中断。进入这个分支后立刻用DL_UART_Main_receiveData函数读取数据然后调用发送函数将其送回。3.3 下载与测试将代码编译、下载到开发板。用Type-C线连接开发板和电脑。在电脑上打开一个串口调试助手软件如XCOM、SSCOM等进行如下设置选择正确的串口号在设备管理器中查看CH340E生成的COM口。波特率9600数据位8停止位1校验位无设置好后打开串口。在发送框输入任意字符或字符串点击发送。你应该能在接收框里看到开发板原样返回的数据。同时开发板上的LED也在规律闪烁说明程序运行正常。4. 进阶技巧让printf函数指向串口调试时如果能直接使用printf函数向串口打印信息会方便很多。这需要重定向C库的fputc函数。这里给你一个最常用的方法使用微库修改堆栈大小在Keil中打开.s启动文件找到堆栈大小设置适当调大比如将Heap_Size改为0x100。启用微库在Keil的“Options for Target” - “Target”选项卡中勾选“Use MicroLIB”。重写fputc函数在main.c文件中添加以下代码#include stdio.h // 必须包含这个头文件 // 重定向fputc函数到UART0 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(Hello MSPM0!\\n);了信息会自动从串口0输出。提示使用微库简单但可能会增加一点代码体积。如果对体积敏感可以采用“半主机模式”替代方案具体方法在原始资料里有详细说明这里不赘述。好了关于MSPM0G3507串口通信的中断配置和使用核心内容就是这些。整个过程可以总结为硬件连接已固定 - SysConfig图形化配置时钟、引脚、参数、中断- 代码中手动开启中断 - 编写中断服务函数处理数据。多练几次你就能牢牢掌握。在实际项目中串口通信是调试和交互的基石一定要玩熟。