第30讲:实战——USART串口收发原型快速搭建+调试
CSDN专栏嵌入式程序开发实战嵌入式双范式AI编程嵌入式开发必掌握嵌入式求职面试技术资料第30讲实战——USART串口收发原型快速搭建调试一、USART基础USART通用同步/异步收发器是嵌入式最常用的通信接口用于与PC、其他MCU、模块通信。1.1 USART配置要点基本参数波特率9600、19200、38400、57600、115200等数据位8位最常用停止位1位最常用校验位无最常用流控无最常用引脚配置USART1PA9(TX)、PA10(RX)USART2PA2(TX)、PA3(RX)USART3PB10(TX)、PB11(RX)1.2 通信模式轮询模式特点阻塞等待适用简单应用、调试中断模式特点非阻塞、事件驱动适用实际应用DMA模式特点高效、CPU占用少适用高速、大数据量二、串口发送实战2.1 基础发送需求串口发送Hello WorldPrompt生成STM32F103 USART发送代码 - USART1PA9(TX)、PA10(RX) - 波特率115200 - 功能发送Hello World - 使用HAL库AI生成#includestm32f1xx_hal.hUART_HandleTypeDef huart1;voidUSART1_Init(void){huart1.InstanceUSART1;huart1.Init.BaudRate115200;huart1.Init.WordLengthUART_WORDLENGTH_8B;huart1.Init.StopBitsUART_STOPBITS_1;huart1.Init.ParityUART_PARITY_NONE;huart1.Init.ModeUART_MODE_TX_RX;huart1.Init.HwFlowCtlUART_HWCONTROL_NONE;huart1.Init.OverSamplingUART_OVERSAMPLING_16;HAL_UART_Init(huart1);}intmain(void){HAL_Init();SystemClock_Config();USART1_Init();char*msgHello World\r\n;HAL_UART_Transmit(huart1,(uint8_t*)msg,strlen(msg),100);while(1);}2.2 printf重定向需求使用printf输出到串口代码// 重定向fputcintfputc(intch,FILE*f){HAL_UART_Transmit(huart1,(uint8_t*)ch,1,100);returnch;}// 使用intmain(void){HAL_Init();SystemClock_Config();USART1_Init();printf(System Start\r\n);printf(Version: 1.0\r\n);while(1){printf(Tick: %d\r\n,HAL_GetTick());HAL_Delay(1000);}}Keil配置Options → Target → Use MicroLIB勾选2.3 格式化输出需求输出各种格式的数据代码voidPrint_Data(void){uint8_tdata0x55;uint16_tvalue1234;floattemperature25.6f;// 十进制printf(Value: %d\r\n,value);// 十六进制printf(Hex: 0x%02X\r\n,data);// 浮点数printf(Temperature: %.2f\r\n,temperature);// 二进制printf(Binary: );for(inti7;i0;i--){printf(%d,(datai)1);}printf(\r\n);}三、串口接收实战3.1 轮询接收需求接收数据并回显代码intmain(void){HAL_Init();SystemClock_Config();USART1_Init();uint8_trxData;while(1){// 接收数据if(HAL_UART_Receive(huart1,rxData,1,100)HAL_OK){// 回显HAL_UART_Transmit(huart1,rxData,1,100);}}}3.2 中断接收需求使用中断接收数据Prompt生成STM32F103 USART中断接收代码 - USART1PA9(TX)、PA10(RX) - 波特率115200 - 功能中断接收并回显 - 使用HAL库AI生成uint8_trxData;voidUSART1_Init(void){huart1.InstanceUSART1;huart1.Init.BaudRate115200;huart1.Init.WordLengthUART_WORDLENGTH_8B;huart1.Init.StopBitsUART_STOPBITS_1;huart1.Init.ParityUART_PARITY_NONE;huart1.Init.ModeUART_MODE_TX_RX;huart1.Init.HwFlowCtlUART_HWCONTROL_NONE;huart1.Init.OverSamplingUART_OVERSAMPLING_16;HAL_UART_Init(huart1);// 启动接收中断HAL_UART_Receive_IT(huart1,rxData,1);}voidUSART1_IRQHandler(void){HAL_UART_IRQHandler(huart1);}voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){if(huart-InstanceUSART1){// 回显HAL_UART_Transmit(huart1,rxData,1,100);// 继续接收HAL_UART_Receive_IT(huart1,rxData,1);}}intmain(void){HAL_Init();SystemClock_Config();USART1_Init();while(1){// 主循环可以做其他事情}}3.3 环形缓冲区接收需求使用环形缓冲区接收数据避免数据丢失代码#defineBUFFER_SIZE256typedefstruct{uint8_tbuffer[BUFFER_SIZE];uint16_thead;uint16_ttail;}RingBuffer_t;RingBuffer_t rxBuffer{0};voidRingBuffer_Write(uint8_tdata){uint16_tnextHead(rxBuffer.head1)%BUFFER_SIZE;if(nextHead!rxBuffer.tail){// 缓冲区未满rxBuffer.buffer[rxBuffer.head]data;rxBuffer.headnextHead;}}uint8_tRingBuffer_Read(uint8_t*data){if(rxBuffer.headrxBuffer.tail){// 缓冲区空return0;}*datarxBuffer.buffer[rxBuffer.tail];rxBuffer.tail(rxBuffer.tail1)%BUFFER_SIZE;return1;}uint16_tRingBuffer_Available(void){return(rxBuffer.head-rxBuffer.tailBUFFER_SIZE)%BUFFER_SIZE;}// 中断回调voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){if(huart-InstanceUSART1){RingBuffer_Write(rxData);HAL_UART_Receive_IT(huart1,rxData,1);}}// 主循环处理voidProcess_UartData(void){uint8_tdata;while(RingBuffer_Read(data)){// 处理数据printf(Received: 0x%02X\r\n,data);}}四、串口调试技巧4.1 串口工具常用工具- 串口调试助手SSCOM、XCOM、串口精灵 - 终端工具PuTTY、Tera Term、SecureCRT - 分析工具逻辑分析仪、协议分析仪配置波特率115200 数据位8 停止位1 校验位无 流控无4.2 调试输出分级日志#defineLOG_LEVEL3// 0:无 1:错误 2:警告 3:信息 4:调试#defineLOG_ERROR(fmt,...)if(LOG_LEVEL1)printf([ERROR] fmt\r\n,##__VA_ARGS__)#defineLOG_WARN(fmt,...)if(LOG_LEVEL2)printf([WARN] fmt\r\n,##__VA_ARGS__)#defineLOG_INFO(fmt,...)if(LOG_LEVEL3)printf([INFO] fmt\r\n,##__VA_ARGS__)#defineLOG_DEBUG(fmt,...)if(LOG_LEVEL4)printf([DEBUG] fmt\r\n,##__VA_ARGS__)// 使用LOG_ERROR(UART initialization failed);LOG_WARN(Buffer nearly full: %d,usage);LOG_INFO(System started);LOG_DEBUG(Received byte: 0x%02X,data);4.3 数据分析十六进制输出voidPrint_Hex(uint8_t*data,uint16_tlen){printf(Hex: );for(uint16_ti0;ilen;i){printf(%02X ,data[i]);}printf(\r\n);}ASCII输出voidPrint_ASCII(uint8_t*data,uint16_tlen){printf(ASCII: );for(uint16_ti0;ilen;i){if(data[i]32data[i]126){// 可打印字符printf(%c,data[i]);}else{printf(.);}}printf(\r\n);}混合输出voidPrint_Data_Mixed(uint8_t*data,uint16_tlen){printf(Data[%d]:\r\n,len);for(uint16_ti0;ilen;i){printf(%02X ,data[i]);if((i1)%160){// 每16字节换行printf( );for(uint16_tji-15;ji;j){if(data[j]32data[j]126){printf(%c,data[j]);}else{printf(.);}}printf(\r\n);}}// 处理剩余字节if(len%16!0){for(uint16_tilen%16;i16;i){printf( );}printf( );for(uint16_tjlen-(len%16);jlen;j){if(data[j]32data[j]126){printf(%c,data[j]);}else{printf(.);}}printf(\r\n);}}五、常见问题与解决5.1 乱码问题现象串口输出乱码原因1. 波特率不匹配 2. 系统时钟配置错误 3. 数据格式不匹配解决// 验证波特率voidVerify_Baudrate(void){printf(SystemCoreClock: %d\r\n,SystemCoreClock);printf(UART BRR: 0x%04X\r\n,USART1-BRR);uint32_tactualBaudSystemCoreClock/(USART1-BRR0xFFFF);printf(Actual baudrate: %d\r\n,actualBaud);}5.2 数据丢失现象接收数据丢失原因1. 接收缓冲区溢出 2. 处理速度慢 3. 中断被阻塞解决// 使用环形缓冲区// 提高处理速度// 优化中断优先级5.3 发送卡死现象发送函数卡死原因1. 超时时间过短 2. UART未初始化 3. 引脚配置错误解决// 增加超时时间HAL_UART_Transmit(huart1,data,len,1000);// 1秒超时// 检查初始化if(huart1.Instance!USART1){printf(UART not initialized\r\n);}六、本讲核心要点6.1 记住这三句话串口配置波特率、数据位、停止位、校验位最常用8N1接收方式轮询简单、中断常用、DMA高效调试技巧printf重定向、分级日志、数据分析6.2 实践建议对于新手学习串口配置实践中断接收使用调试工具对于有经验工程师建立串口驱动模板实现环形缓冲区优化调试输出6.3 下讲预告第31讲将深入讲解实战SPI屏驱动快速试错、点亮屏幕SPI常用于驱动屏幕如何快速试错点亮屏幕下一讲将详细讲解。

相关新闻

Claude---s1---框架梳理

Claude---s1---框架梳理

详细数据流转:1️⃣ 用户发起指令与系统组装 (CLI & Initialization)用户动作:在终端输入 RuiZN run --goal "读取当前目录下的 README.md"。数据流转:cli/main.py 接收到原生命令行参数,argparse 将其解析为字符串…

2026/11/14 10:24:46 阅读更多 →
孩子成绩持续落后,盲目刷题没用!挑选 AI 智习室,为什么很多家长选择佐管家?

孩子成绩持续落后,盲目刷题没用!挑选 AI 智习室,为什么很多家长选择佐管家?

不少家长都有同样的困扰:孩子成绩长期跟不上,作业拖拉、错题反复出现;上课似懂非懂,考试一塌糊涂。补习班跟不上进度,居家辅导矛盾不断。双减背景下,越来越多家庭把目光投向 AI 智习室,但市面上…

2026/11/10 21:18:06 阅读更多 →
飞轮储能精密储能舱车间通风 易互德防静电稳温布风管保障储能设备装配安全

飞轮储能精密储能舱车间通风 易互德防静电稳温布风管保障储能设备装配安全

飞轮储能装置属于高速旋转精密储能装备,转子、磁悬浮轴承对环境粉尘、静电、温湿度变化高度敏感。微米级粉尘进入装配舱,会造成高速轴承磨损、动平衡失衡;静电放电极易损伤电控模块;温度波动引发材料热胀冷缩,降低转子…

2026/11/5 17:28:59 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/14 5:13:29 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/14 5:13:29 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/14 5:13:29 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/13 22:08:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/14 2:41:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/14 5:13:29 阅读更多 →

日新闻

周新闻

月新闻