当前位置: 首页 > news >正文

嵌入式开发学习记录:USART串口通信

📋 文章目录

本文记录了嵌入式开发中 USART 串口通信的学习过程,包含理论学习、环境搭建、代码实现与问题排查等内容。以下是文章结构概览:

  1. 📅 学习进度概览
  2. 📝 学习记录与问题追踪
    1. 1. 理论学习与概念梳理
    2. 2. 环境搭建与第一个工程
    3. 3. 轮询模式工程创建:代码实现与调试过程
    4. 4. 中断模式工程创建:代码实现与调试过程
    5. 5. DMA模式工程创建:代码实现与调试过程
    6. 6. printf重定向到usart串口上,实现printf打印信息到串口助手上

📅 学习进度概览

当前学习阶段:嵌入式开发 - USART 串口通信

当前使用的开发板:STM32F407VGT6-Disk

开始时间:2026 年 8 月 22 日

学习目标:

  • 理解 USART(通用同步异步收发器)的基本工作原理
  • 掌握 STM32(或其他 MCU)的 USART 外设配置流程
  • 能够实现基本的串口收发功能(查询/中断/DMA 方式)
  • 记录并解决学习过程中遇到的实际问题

注意:本文中每个实验均另开了一个工作空间并重新创建项目,并非在原先工程上做出改变


📝 学习记录与问题追踪

1. 理论学习与概念梳理

时间:2026/08/16

内容:

  • 复习了串行通信与并行通信的区别。
  • 理解了 USART 与 UART 的关键差异:USART 支持同步模式(有时钟线),UART 仅支持异步。
  • 学习了波特率、数据位、停止位、奇偶校验等关键参数的含义。

2. 环境搭建与第一个工程

时间:2026/08/20

内容:

  • 使用 STM32CubeMX 初始化 USART 外设,生成代码。
  • 使用 STM32CubeIDE 进行开发。
  • 使用 USB 转 TTL 模块连接电脑配合串口助手工具进行调试。

遇到的问题:

  • 串口助手打印结果乱码
  • 串口助手无打印结果
  • 配合 printf 函数重定向但 printf 函数没能打印出结果

3.轮询模式工程创建:代码实现与调试过程

时间:2026/08/20

使用 STM32CubeMX 创建新工程,并开启外部高速晶振(HSE)作为系统时钟源。

创建工程,开启外部晶振:

配置时钟:

修改 debug 模式:

开启串口为异步模式:

勾选为每个外设单独生成 .c/.h 文件

生成代码,使用 VS Code 打开项目,借助扩展包采用提示词工程给出的代码写好测试发送的代码

打开 CubeIDE,代码自动更新,点击小锤子编译,无报错无警告

按照设置的串口连接好硬件及开发板,为 USB 转 TTL 模块下载好驱动,本文采用波特律动串口助手中提供的驱动下载链接下载好 CH340 型号驱动,并按如图方式连接好硬件部分,TXD 接 PA10,RXD 接 PA9,并将 USB 口接在电脑上

烧录代码

打开波特律动串口助手,选择好串口并开启,查看串口信息打印

遇到的实际问题与解决方案:

  • 发现串口有东西打印出来,且打印间隔为原 while 函数中设置的 1 秒,但是打印出来的数据是乱码,本应该是 "Hello World"
  • 时间间隔没问题,则程序确实进入了 while 循环,且循环没问题,但数据乱码,问题大概率出在波特率不匹配,硬件接线问题
  • [最终解决方案]:修改连接的串口,我最终改成使用usart2串口,使用PA2,PA3两个引脚,--取消时钟配置--并重新生成代码,代码最终逻辑如图,波特率,校验位等无任何修改,最终得到串口输出结果

改写代码为接收电脑发送的数据,并用发送函数检验是否收到

最终也能成功返回发送的数据

  • 最后总结原因:成功与失败的最大区别是取消了外部晶振提供时钟,采用的内部HSI,大概率就是这个原因影响了串口

4.中断模式工程创建:代码实现与调试过程

时间:2026/08/21

MX工程创建与轮询方式类似,但本次不使用外部时钟,且勾选usart2的全局中断,点击usart2的NVIC标签,勾选全局中断,保存并生成代码,代码仅需将发送,接收函数加上_IT后缀,将传递的超时时间字段去掉即可。

编译并烧录,查看串口助手打印结果

结果在未发送任何数据时界面不断发送空,发送了R0后界面不断发送R0回来

查看代码发现将两个中断模式的发送接收函数都写到while循环里了,中断模式不像轮询模式一样,是非阻塞的,会一直循环执行,导致循环过快而显示如图样式,只要将中断接收函数放到while循环外即可,但是一般不会将中断发送放在while循环里,不然也会导致上述结果,一般是中断接收后调用中断处理函数HAL_UART_RxCpltCallback,此函数可自己重新定义一下,并将逻辑写入,而后中断接收完成后将执行函数中的逻辑

那有要求中断接收不能放在while循环里,要保证能不断接收则可将中断接收函数放在中断处理函数的末尾,这样中断处理函数逻辑完成前就会进入下一次中断接收。

5.DMA模式工程创建:代码实现与调试过程

时间:2026/08/21

MX项目创建只要基于中断模式下再添加DMA通道即可,如图分别添加Rx和Tx的DMA通道保持默认设置即可

保存并生成代码,发送、接收函数仅需在中断发送函数的基础上将_IT后缀改为_DMA即可,我在中断回调处理函数中加上了阻塞式发送并在末尾补上DMA接收,将接收数组放在PV注释对中以防报错

编译,烧录,查看串口助手,发现能正常接收并回复

接收不定长数据

主要靠的是串口空闲中断,使用HAL_UARTEx_ReceiveToIdle,这个函数也有阻塞,中断,DMA三种方式,也是通过修改后缀即可使用,另外,使用此函数对应的回调函数也有所不同,这里应使用HAL_UARTEx_RxEventCallback回调函数,这里我直接使用DMA方式在本工程里进行测试结果如图,由于我定义的数组长度是50,所以发送过长时触发了传输过半中断,故而后面的数据没能返回,可以使用_HAL_DMA_DISABLE_IT函数取消传输过半中断。

6.printf重定向到usart串口上,实现printf打印信息到串口助手上

时间:2026/08/21

目前尝试了各种方法,如重写fputc函数,重写_write函数,关闭半主机模式(代码实现,写在fputc函数后)均未能实现,须待解决

http://www.cnnetsun.cn/news/4169576.html

相关文章:

  • 物理审计智能体发现:让AI科学探索既高效又守规矩
  • Agent跑通Demo后崩了?小团队如何聪明做工程化
  • 后端开发常见误区盘点:如何写出更稳健的接口代码
  • 嵌入式系统核心解析:MCU、MPU与SoC的本质区别与应用选型
  • Ornith-1.5 号称自改进:但它真的不是「自己给自己出题自己给自己打满分」?
  • 学生党开学季显示器选购指南:泰坦军团26款型号深度解析
  • 大厂 MCP 面试实录:可复用模板工作流与向量检索结合方案设计
  • 卖货难、招商难、运营难:你的私域系统真的在解决问题吗?
  • 从 Scratch 到 NOI:一套能走通的科技特长生培养路径
  • 爬虫老手转大模型:数据能力凭什么从采集变成 RAG 的护城河
  • 数学建模期末高效复习:从知识地图到代码模板的实战指南
  • AI大模型人才争夺战:技能要求与求职指南
  • 小批量梯度下降(MBGD)原理、实现与调优:从数学建模到深度学习实战
  • C++可变参数模板深度解析:从习题到工程实践
  • LangChain.js与Nuxt.js:AI全栈开发实战与招聘风向解读
  • Rust专属招聘平台RustyBoard的技术架构与实现
  • FCL启动器全面指南:从零搭建与管理Minecraft模组环境
  • 聚宽、米筐、掘金、优矿与QMT参数迁移:类型、单位和默认值必须同存
  • GitHub大项目断点续传实战:从浅克隆到渐进式获取的完整方案
  • Kafka Producer事务与幂等性原理及生产实践
  • Windows 11虚拟机搭建指南:VMware Workstation安全测试环境配置
  • Windows账户锁定策略详解与实战解锁指南
  • Grok 4.6多模态大模型实测:中文语音、代码生成与本地部署指南
  • 从LLM API窃取推理轨迹:安全风险与模拟验证
  • Git指令速查表:从核心概念到实战场景的高效开发指南
  • 多尺度混合世界模型:让AI在动态环境中稳健学习与决策
  • Canal数据同步实战:自定义JSON格式优化与Kafka集成方案
  • dsh-tui:将AI编程助手无缝集成到终端工作流的实践指南
  • 信息论与决策树在算法竞赛小球称重问题中的应用与实现
  • 深入Eigen源码:揭秘C++高性能数值计算的模板元编程与表达式模板