基于STM32CubeMX和keil采用USART/UART实现非中断以及中断方式数据回环测试借助CH340以及XCOM
文章目录
- 前言
- 1. 接口概述
- 1.1 USART/UART接口
- 1.2 串口通信参数
- 1.3 波特率计算
- 2. 传输函数
- 3. 回环测试
- 3.1 上位机环境配置
- 3.2 阻塞模式
- 3.3 中断模式
- 4. STM32CubeMX配置
- 4.1 时钟配置
- 4.2 调试配置
- 4.3 串口引脚配置
- 4.4 工程配置
- 5. 测试效果
- 6. 不借助上位机回环测试
- 总结
前言
这篇博客从串口通信的接口讲起,阐述原理,介绍通信方式,最后上机测试。
本篇博客主要以异步通信为例。
1. 接口概述
串口分为很多种,我们STM32学习过程中常见的就是UART/USART,前者是同步模式,后者是异步模式。还有RS485,RS232这种也是串口。我们平常使用的串口模块,大多都是类似于USB转TTL模块,为什么叫USB转TTL而不是USB转串口,因为MCU上的串口是逻辑电平(TTL或者CMOS电平),MCU和模块的通信通过逻辑电平的串口信号线直接连接。所以两种叫法,后者包含前者。前者更为常用。
1.1 USART/UART接口
下面是USART/UART对应的一般接口图

各个引脚说明如下:
请注意各个箭头方向。
| 引脚标识 | 引脚含义 | 备注 |
|---|---|---|
| TX | 串行输出信号 | MCU向对方设备发送数据 |
| RX | 串行输入信号 | MCU接收对方设备发送的数据 |
| nCTS | 允许发送信号 | 低电平有效,是对方设备发来的信号。如果nCTS为低电平,则表示对方设备准备好了接受数据,本机可以发送数据了;否则,不能发送数据。 |
| nRTS | 请求发送信号 | 低电平有效,是发送给给对方设备的一个信号。如果本机准备好了接受数据,则将nRTS置为低电平,通知对方设备可以发送数据了 |
| SCLK | 发送器输出的时钟信号 | 时钟信号线仅用于同步模式,USART没有这个引脚,UART有。 |
上面的图和表是串口最全的情况,是带有硬件流控制,同时又是同步模式的情况。
其实一般我们使用异步模式,并且没有硬件流控制。所以上面的5个引脚,最常用的只有RX,TX。
拿USB转TTL模块来举例,我们只需要接RX,TX,GND,VCC四个脚就行。这里RX和TX注意要交叉接,主机的TX接从机的RX,从机的TX接主机的RX。这个也很好理解,就是数据发送与接收的方向。
1.2 串口通信参数
串口发送数据是以数据帧的方式发送数据,下图是以传输一个8为字长的数据帧的时序图。

参数说明:
数据位:8位/9位,一般设置为8位,即8bit,即1byte。这样一帧传输1字节的有效数据。
奇偶校验位:可以无奇偶校验位,也可以设置奇校验或者偶校验。
停止位:1个或者2个停止位,一般设置为1个停止位。
波特率:串行数据传输的速率,单位是bit/s,常用的波特率有9600、19200、115200等。最高波特率的计算是根据时钟来的。一个串口单元的时钟由APB1或APB2总线提供,所以挂在不同APB总线上的串口单元的最高波特率不同。
1.3 波特率计算
波特率 = 时钟频率 ( UART的分频因子 × 过采样次数 ) \text{波特率} = \frac{\text{时钟频率}}{(\text{UART的分频因子} \times \text{过采样次数})} 波特率=(UART的分频因子×过采样次数)时钟频率
分频因子我查了一下,使用STM32CubeMX似乎是自动配置的,我就没有管了。
不过手动配置多少的话,可以算。
比如波特率115200,时钟频率100MHz,过采样次数16
算出来的UART的分频因子大约为54.2534,四舍五入到最近的整数。即54
2. 传输函数
这一小节主要介绍一下串口传输数据的三种方式对应的函数
| 传输类别 | 函数名 | 功能说明 |
| 阻塞式传输 | HAL_UART_Transmit() | 阻塞方式发送一个缓冲区的数据,发送完成或超时后才返回 |
| HAL_UART_Receive() | 阻塞方式将数据接收到一个缓冲区,接收完成或擦手后才返回 | |
| 中断方式传输 | HAL_UART_Transmit_IT() | 以中断方式(非阻塞式)发送一个缓冲区的数据 |
| HAL_UART_Receive_IT() | 以中断方式(非阻塞方式)将指定长度的数据接收到一个缓冲区 | |
| DMA方式传输 | HAL_UART_Transmit_DMA() | 以DMA方式发送一个缓冲区数据 |
| HAL_UART_Receive_DMA() | 以DMA方式将指定长度的数据接收到缓冲区 | |
| HAL_UART_DMAPause() | 暂停DMA传输过程 | |
| HAL_UART_DMAResume() | 继续先前暂停的DMA传输过程 | |
| HAL_UART_DMAStop | 停止DMA传输过程 |
上表中我只列举了函数名称,对于其中的参数并没有详细介绍,具体参数可以参考对应的驱动文件。

3. 回环测试
简单的回环测试,先接收上位机PC用XCOM发来的信息,再把数据发回去。
3.1 上位机环境配置
使用的是CH340,安装驱动。


如果出现预安装成功,但是你用USB接开发板之后没反应,不妨换一根数据线(我这里踩坑饿了),有些垃圾数据线不支持协议。
XCOM的话,点击就能用,主要是上下位机的波特率要一致。


3.2 阻塞模式
使用到的函数为
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
函数对应的参数说明如下:
UART_HandleTypeDef *huart: 串口响应对象
const uint8_t *pData:发送/接受的数据
uint16_t Size:发送/接收数据的大小
uint32_t Timeout:发送或接收数据超时时间。超时后结束函数。
测试代码
uint8_t testBuf[5]="hello";
uint8_t receiveBuf[20]={0};
while (1){ if(HAL_UART_Receive(&huart1,receiveBuf,sizeof(testBuf),100)==HAL_OK) {HAL_UART_Transmit(&huart1,receiveBuf,sizeof(testBuf),100);}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}
3.3 中断模式
使用到的函数为
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
函数对应的参数说明如下:
UART_HandleTypeDef *huart: 串口响应对象
uint8_t *pData:发送/接受的数据
uint16_t Size:发送/接收数据的大小
测试代码
uint8_t testBuf[5]="hello";
uint8_t receiveBuf[20]={0};
while (1){ if(HAL_UART_Receive_IT(&huart1,receiveBuf,sizeof(testBuf))==HAL_OK) {HAL_UART_Transmit_IT(&huart1,receiveBuf,sizeof(testBuf));}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}
4. STM32CubeMX配置
4.1 时钟配置

4.2 调试配置

4.3 串口引脚配置

开启中断

4.4 工程配置


5. 测试效果
使用中断还是阻塞,在这个回环测试都一个效果。

6. 不借助上位机回环测试
原始版本,这个代码和上面的很类似,不同的地方在于硬件的连接。
uint8_t testBuf[5]="hello";
uint8_t receiveBuf[20]={0};
while (1){HAL_UART_Transmit(&huart1,testBuf,sizeof(testBuf),100);HAL_UART_Receive(&huart1,receiveBuf,sizeof(testBuf),100);
}
我这里将STM32F407ZET6的TX1直接接到RX1上了,按道理来说这样的效果使用debug来看的话,receiveBuf接收到的值应该是"hello",但是实际效果却不是这样的,我用debug来看,得到的数据却一直是h。后面的数据根本过不来。我一开始以为是发送需要时间,我没给延时,后来给了延时也是一样的效果。
按照显示的现象,我修改了部分代码
for(int i=0;i<sizeof(testBuf);i++)
{HAL_UART_Transmit(&huart1,testBuf+i,sizeof(testBuf),100);HAL_UART_Receive(&huart1,receiveBuf+i,sizeof(testBuf),100);
}
改完后,再用debug来看,发现数据正常了。
一直不太明白为什么,目前自己暂时认为,GPIO脚一次只能接受1bit数据,虽然每次发送了5个数据,但是只能收一个数据,这就导致只能收到h这个数据。
后来用了个for循环,其实就是多次发送,每次接受不同位置的数据,达到我们最终想要的效果。
总结
这个平时用的时候没有遇到第六小节的情况,因为都是借助上位机以及对应的USB转TTL做的测试。只关注了波特率,校验位等配置。没有过多考虑TX直接RX这种情况。这次出现的问题还有待确切的答案,暂时只能先这样认定。
相关文章:
基于STM32CubeMX和keil采用USART/UART实现非中断以及中断方式数据回环测试借助CH340以及XCOM
文章目录 前言1. 接口概述1.1 USART/UART接口1.2 串口通信参数1.3 波特率计算 2. 传输函数3. 回环测试3.1 上位机环境配置3.2 阻塞模式3.3 中断模式 4. STM32CubeMX配置4.1 时钟配置4.2 调试配置4.3 串口引脚配置4.4 工程配置 5. 测试效果6. 不借助上位机回环测试总结 前言 这…...
Spring cloud负载均衡 @LoadBalanced注解原理
接上一篇文章,案例代码也在上一篇文章的基础上。 在上一篇文章的案例中,我们创建了作为Eureka server的Eureka注册中心服务、作为Eureka client的userservice、orderservice。 orderservice引入RestTemplate,加入了LoadBalanced注解&#x…...
C#when关键字
在C#中,when关键字用于在模式匹配表达式中添加条件。它允许您在模式匹配的过程中指定额外的条件,以进一步过滤匹配的模式。当模式匹配和附加条件都为真时,相关的代码块将被执行。 以下是when关键字的详细解释以及示例说明: 语法…...
华为政企无线局域网产品集
产品类型产品型号产品说明 室内接入点AirEngine 5760-51AirEngine 5760-51是华为发布的支持Wi-Fi 6(802.11ax)标准的新一代室内AP,适合部署在企业办公、零售、制造等场景。 通过软件定义射频,能够在双频、三频模式灵活切换&a…...
解释 RESTful API
RESTful API是一种基于HTTP协议的API设计风格,它的核心思想是将每个资源(如用户、订单等)抽象成一个URI(统一资源标识符),通过HTTP协议定义的方法(如GET、POST、PUT、DELETE等)对资源…...
青翼科技-国产化ARM系列TES720D-KIT
板卡概述 TES720D-KIT是专门针对我司TES720D(基于复旦微FMQL20S400的全国产化ARM核心板)的一套开发套件,它包含1个TES720D核心板,加上一个TES720D-EXT扩展底板。 FMQL20S400是复旦微电子研制的全可编程融合芯片,在单…...
Tomcat为什么支持线程池?
Tomcat作为一个Java Servlet容器,支持线程池是因为它能够处理多个并发请求。这些请求可以是对Web应用程序的HTTP请求、Servlet的请求,或其他支持的协议。 支持线程池的主要原因包括: 并发处理能力: 提高性能: 使用线程…...
Mac安装VMware
去官网下载一下VMware Download VMware Fusion | VMware | SG 下载完成之后,打开直接闪退,参考这篇文章解决 解决macOS13安装Fusion13闪退的问题-CSDN博客 然后即可成功顺行...
项目部署文档
申请SSL证书 先申请,用免费的 下载证书 先将下载下来的保存起来 服务器安装JDK: 创建develop目录 mkdir /usr/local/develop/ 把JDK压缩包上传到/usr/local/develop/目录 解压安装包 并且将安装到指定目录 tar -zxvf /usr/local/develop/jdk-8u191-linux-x64.tar.gz -C /us…...
HTML+CSS阶段知识点梳理
目录 一、简单的网页结构 二、常用标签 三、列表 四、CSS引入方式 五、常用选择器 1、标签(元素)选择器 2、id选择器 3、class选择器 4、通配选择器 5、复合选择器 6、关系选择器 7、属性选择器 8、伪类选择器 9、a元素的伪类 10、伪元素…...
网易按照作者批量采集新闻资讯软件说明文档
大家好,我是淘小白~ 今天给大家介绍的爬虫软件是网易按照作者采集的软件 1、软件语言: Python 2、使用到的工具 Python selenium库、谷歌浏览器、谷歌浏览器驱动 3、文件说明: 4、配置文件说明: 5、环境配置 安装Python&am…...
SwiftUI 代码调试之都是“变心”惹的祸
0. 概览 这是一段非常简单的 SwiftUI 代码,我们将 Item 数组传递到子视图并在子视图中对其进行修改,修改的结果会立即在主视图中反映出来。 不幸的是,当我们修改 Item 名称时却发现不能连续输入:每次敲一个字符键盘都会立即收起并…...
u20.04安装slam库
git clone https://github.com/strasdat/Sophus.git // 下载的最新版是模板类的 git checkout a621ff // 切换为非模板类的历史版本 模板类Sophus的依赖库是Eigen(版本为3.3.X)和fmt,需提前安装好Eigen库和fmt库 git clone https://github.c…...
齐纳二极管,肖特基二极管,瞬态电压抑制二极管
普通二极管,齐纳二极管,肖特基二极管的符号: 瞬态电压抑制(TVS)二极管是一种特殊的齐纳二极管,其符号如下: 普通二极管 普通二极管由n类型 的半导体和p类型的半导体结合而成。 硅材料制成的二…...
axios 全局错误处理和请求取消
这两个功能都是用拦截器实现。 前景提要: ts 简易封装 axios,统一 API 实现在 config 中配置开关拦截器 全局错误处理 在构造函数中,添加一个响应拦截器即可。在构造函数中注册拦截器的好处是,无论怎么实例化封装类,…...
无法加载文件 C:\Program Files\nodejs\cnpm.ps1,因为在此系统上禁止运行脚本。有
cnpm : 无法加载文件 C:\Program Files\nodejs\cnpm.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_Execution_Poli cies。 所在位置 行:1 字符: 1 cnpm run debug ~~~~ Categ…...
学电脑编程零基础,计算机编程入门先学什么
学电脑编程零基础,计算机编程入门先学什么,建议先从容易学习的语言入手,比如中文编程。 给大家分享一款中文编程工具,零基础轻松学编程,不需英语基础,编程工具可下载。 这款工具不但可以连接部分硬件&…...
SQL左连接实战案例
要求:用表df1和表df2的数据,得到df3 一、创建表 CREATE TABLE df1 (姓名 varchar(255) DEFAULT NULL,年龄 int DEFAULT NULL,部门 varchar(255) DEFAULT NULL,id int DEFAULT NULL );CREATE TABLE df2 (部门 varchar(255) DEFAULT NULL,年龄 int DEFAU…...
2、Sentinel基本应用限流规则(2)
2.2.1 是什么 Sentinel 是阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。 2.2.2 基本概念 • 资源 (需要被保护的东西…...
Qt的事件
2023年11月5日,周日上午 还没写完,不定期更新 目录 事件处理函数的字体特点Qt事件处理的工作原理一些常用的事件处理函数Qt中的事件类型QEvent类的type成员函数可以用来判断事件的类型事件的类型有哪些?有多少种事件类 事件处理函数的字体特…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
