STM32串口通信基础与HAL库实现 1. STM32串口通信基础与实验目标在嵌入式系统开发中串口通信是最基础也最常用的外设功能之一。STM32系列微控制器内置了USART通用同步异步收发器模块能够灵活地实现设备与上位机之间的数据交互。本次实验的核心目标是使用STM32F103C8T6开发板通过USART1模块向上位机Windows系统持续发送Hello Windows!字符串。串口通信的本质是两位设备通过TX发送和RX接收两根信号线按照约定的协议进行数据交换。在STM32中USART模块支持全双工通信意味着可以同时进行数据的发送和接收。对于初学者而言理解以下几个关键参数至关重要波特率决定数据传输速度常见值有9600、115200等。本实验采用115200bps即每秒传输115200位数据。数据位每个字符包含的位数通常为8位。停止位标志一个字符传输结束本实验使用1位停止位。校验位用于错误检测本实验不启用。提示在嵌入式开发中串口通信不仅是调试利器通过printf输出调试信息更是设备间通信的基础协议。掌握好串口通信将为后续学习I2C、SPI等更复杂的通信协议打下坚实基础。2. 硬件准备与环境搭建2.1 所需硬件清单要完成本实验需要准备以下硬件设备STM32F103C8T6开发板蓝色药丸板USB转TTL模块如CH340、CP2102等杜邦线若干建议使用母对母Windows电脑安装好串口调试助手2.2 硬件连接示意图正确的硬件连接是实验成功的前提。按照以下方式连接设备STM32F103C8T6 USB转TTL模块 PA9(TX) ------ RX PA10(RX) ------ TX GND ------ GND 3.3V ------ 3.3V可选为模块供电注意STM32的TX引脚应连接USB转TTL的RX引脚RX连接TX这是初学者最容易接反的地方。如果连接后无法通信首先检查这两根线是否接反。2.3 开发环境配置软件方面需要准备Keil MDK-ARM开发环境建议V5.25以上版本STM32CubeMX图形化配置工具串口调试助手如SSCOM、Putty等安装STM32F1的Device Family PackDFP包打开Keil点击Pack Installer图标搜索STM32F1安装最新版本的STM32F1xx_DFP安装完成后在新建项目时就能选择STM32F103C8系列芯片3. 使用HAL库实现串口通信3.1 CubeMX工程配置STM32CubeMX极大简化了外设初始化流程。新建工程后按以下步骤配置选择STM32F103C8Tx芯片在Pinout视图中启用USART1Mode选择Asynchronous自动配置PA9为USART1_TXPA10为USART1_RX配置USART1参数Baud Rate: 115200Word Length: 8 BitsStop Bits: 1Parity: NoneHardware Flow Control: Disable时钟配置HCLK设置为72MHzSTM32F103的最高主频在USART1配置中确保波特率准确显示为115200生成代码时选择Toolchain为MDK-ARM并勾选Generate peripheral initialization as a pair of .c/.h files。3.2 关键代码实现CubeMX生成的代码已经完成了USART1的初始化我们只需调用HAL库的发送函数即可。在main.c文件中添加以下代码/* 用户代码开始 0 */ uint8_t greeting[] Hello Windows!\r\n; /* 用户代码结束 0 */ /* 在main函数的while循环中添加 */ while (1) { HAL_UART_Transmit(huart1, greeting, sizeof(greeting)-1, HAL_MAX_DELAY); HAL_Delay(1000); // 每秒发送一次 }代码解析HAL_UART_Transmit函数参数依次为USART句柄、发送数据缓冲区、数据长度、超时时间sizeof(greeting)-1是为了不发送字符串结尾的\0字符HAL_MAX_DELAY表示无限等待直到发送完成\r\n是回车换行符确保每次发送后光标移动到下一行开头3.3 重定向printf实现调试输出为了方便调试可以重定向printf到串口。在usart.c文件中添加以下代码#include stdio.h #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { HAL_UART_Transmit(huart1, (uint8_t *)ch, 1, HAL_MAX_DELAY); return ch; }然后在工程属性的Target选项卡中勾选Use MicroLIB。现在就可以使用printf输出了printf(System initialized!\r\n);4. 调试与问题排查4.1 常见问题及解决方案无输出或乱码检查波特率是否匹配双方必须严格一致确认硬件连接正确TX-RX交叉连接测量晶振是否起振部分板载晶振质量不佳只能接收部分字符检查地线是否连接良好尝试降低波特率测试如改为9600检查电源稳定性可并联100uF电容Keil编程后无反应检查BOOT0和BOOT1引脚状态正常运行时BOOT0应接地确认程序是否成功烧录查看Keil输出窗口的编程进度4.2 逻辑分析仪调试在没有示波器的情况下Keil内置的逻辑分析仪是强大的调试工具。设置方法进入Debug模式点击View - Analysis Windows - Logic Analyzer点击Setup添加要观察的信号输入USART1_SR观察状态寄存器或直接监控PA9引脚设置Display Type为Bit运行程序可以看到串口输出的波形时序正常波形应该呈现规律的脉冲序列每个字符的起始位为低电平接着是8位数据位LSB先发送最后是高电平的停止位。4.3 性能优化建议中断方式当前查询方式会阻塞CPU实际项目中建议使用中断或DMA环形缓冲区建立发送/接收缓冲区提高通信效率协议设计添加帧头、校验和等提高通信可靠性功耗优化通信间隔期间可进入低功耗模式5. 进阶应用与扩展5.1 中断方式实现修改CubeMX配置启用USART1全局中断。然后修改发送代码void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { if(huart-Instance USART1) { HAL_UART_Transmit_IT(huart1, greeting, sizeof(greeting)-1); } } // 在main中启动第一次发送 HAL_UART_Transmit_IT(huart1, greeting, sizeof(greeting)-1);5.2 自定义通信协议一个简单的协议示例#pragma pack(1) typedef struct { uint8_t header; // 0xAA uint8_t cmd; uint8_t len; uint8_t data[32]; uint8_t checksum; } UART_Frame; #pragma pack() void SendFrame(uint8_t cmd, uint8_t* data, uint8_t len) { UART_Frame frame; frame.header 0xAA; frame.cmd cmd; frame.len len; memcpy(frame.data, data, len); uint8_t sum 0; for(int i0; ioffsetof(UART_Frame, checksum); i) sum ((uint8_t*)frame)[i]; frame.checksum sum; HAL_UART_Transmit(huart1, (uint8_t*)frame, sizeof(frame), HAL_MAX_DELAY); }5.3 与Windows应用交互可以使用Python的pyserial库开发上位机程序import serial ser serial.Serial(COM3, 115200, timeout1) while True: data ser.readline().decode(ascii).strip() if data: print(fReceived: {data}) if data Hello Windows!: ser.write(bACK\r\n)6. 项目总结与工程实践建议通过这个基础实验我们实现了STM32与Windows系统之间的简单串口通信。在实际项目开发中还需要注意以下几点抗干扰设计信号线使用双绞线适当添加终端电阻如120Ω在TX/RX线上串联33Ω电阻错误处理机制添加超时重发功能实现软件校验如CRC16监控线路状态如使用RS485时需要DE/RE控制多任务集成在RTOS中创建专用通信任务使用消息队列传递通信数据设置合理的任务优先级生产测试考虑预留测试点如引出TX/RX到排针实现自动化测试脚本添加版本查询指令如发送VER?返回固件版本串口通信作为嵌入式开发的基石其稳定性和可靠性直接影响整个系统的表现。建议初学者在掌握基础用法后进一步研究以下方向硬件流控制RTS/CTS多串口协同工作高速串口如STM32H7系列的12.5Mbps无线串口如通过蓝牙模块透传最后分享一个调试技巧当通信异常时可以尝试短接板载TX和RX引脚发送的数据应立即回显这是验证串口硬件是否正常的快速方法。