STM32 串口通信①:USART 全面理解 + 代码详解
一 前言
本篇文章并不会系统的从零开始讲起,适合大家对USART有一定的学习,再看本篇文章会有一定的收获,祝大家在本文中,吸收到新的知识。
二 通信方式
1)按数据传输的方式分(这就是“串行 vs 并行”)
(1)串行通信
串行通信:是指数据一位一位地按顺序传输,比如我们常见的 UART、USART、SPI、I2C 等都是串行通信。这种方式的优点是连线少,成本低,尤其适合远距离传输和资源受限的场合。
特点:速度较慢,硬件连接简单,数据线只有一根,
(2)并行通信
并行通信:是同时传输多个位,比如计算机内部的总线、老式的并口打印机接口等。这种方式的数据吞吐量大,但需要更多的连线和同步机制,通常用于短距离和高速数据传输。
特点:速度较快,需要更多的数据线
不知道大家有没有这样一个疑问:
大家再看串行通信这里的举例,USART、UART他不是连接了四根线,其中两根数据线吗,分别是Rx、Tx吗,你怎么就能说他们俩是串行通信呢?
答:大家想的确实没错,但是在实际的硬件连接中,像 UART 或 USART 这样的串行通信确实会有四根线:VCC(电源)、GND(地线)、TX(发送)、RX(接收)。其中 TX 和 RX 是用于数据传输的两根线。
我之前说的“串行通信只有一根数据线”其实是指数据在一根线上按位串行传输,而不是像并行通信那样同时在多条线上并行传输多个位。TX 和 RX 是串行通信中用于发送和接收的两根数据线,数据是按位依次传输的。所以,串行通信的“串”是指数据在一条数据线上按顺序传输,而并不是指有多少根物理线。
2)按通信方向分(这就是“单工/半双工/全双工”)
类型 | 特点 | 举例 |
---|---|---|
单工 | 只能单向通信 | 收音机(只能接收) |
半双工 | 双向通信但不能同时进行 | 对讲机(你说我听,不能同时) |
全双工 | 双向通信可同时进行 | 电话、UART串口 |
3)按时钟控制方式分(这就是“同步 vs 异步”)
类型 | 特点 | 举例 |
---|---|---|
同步通信 | 依靠共享时钟信号,时序精确 | SPI、USART 同步模式 |
异步通信 | 没有时钟线,靠起始位/停止位来同步 | UART、USART 异步模式 |
在这里就要引出我们本文的主角了,USART
三 USART
大家有没有经常搞混USART和UART呢,我简单的给大家找一下相关的数据和分类,
UART 是一种“异步串行通信协议”;
USART 是 STM32 中的“通用同步/异步串口外设”,它能实现 UART,也能实现更多。
UART能干的,USART就给他干完了,所以USART我们更常用。我们平常说的UART说的应该就是USART下的UART模式,他叫异步串行通信。
下两张表是他们所对应的模式
USART:
模式名称 | 描述 |
---|---|
UART 模式 | 异步串行通信,最常用的方式,用 TX/RX 就行 |
同步模式 | 增加了一个时钟引脚(CK),用于同步通信(类似 SPI) |
单线半双工模式 | 只有一根数据线,TX 和 RX 复用(比如红外通信) |
智能卡模式 | 主要用来对接智能卡协议(ISO 7816),包含特定帧结构和校验要求 |
IrDA 模式 | 红外通信协议,STM32 USART 支持内建调制和解调 |
LIN 模式 | 本地互连网络(Local Interconnect Network),汽车中常用的低速通信协议 |
DMX 模式(高级型号) | 灯光控制系统协议(部分高级芯片才有) |
UART:
功能 | 有/无 |
---|---|
异步通信(TX/RX) | ✅ |
同步通信(带时钟) | ❌ |
IrDA / LIN / Smartcard | ❌ |
大家观看上面这两张表,大家也能发现,USART要比UART的功能更加的强大,而我们更常用USART下的UART模式,也就是我们最经常接触的有Rx、Tx引脚的串口器件,USB转TTL电平的模块,如图:
在这里要特别说明一点:如果用异步的通信就一定会包含起始位、停止位、校验位、数据位,如果想要保证异步通信的准确性,就需要这些去判断,而不像同步通信,同步通信靠的是标准的时钟信号CLK
四 基础概念
1)波特率和比特率
比特率Bit Rate:每秒传输了多少个 0 或 1,传输了几位二进制的数
波特率 Baud Rate:传输的是码元,码元是用来承载比特的容器
情况 | 每个码元代表多少比特 | 举例说明 |
---|---|---|
简单二进制通信 | 1 bit | 一个码元只有两种状态(0 或 1) |
QPSK(四相移键控) | 2 bits | 一个码元表示 00、01、10、11 |
这里说的码元,并不是固定死的,他是人为可以规定的,在今天的串口和未来几天关于蓝牙HC-05的讲解,都是将一个码元表示成 1 个比特,也就是说,最近我写的博客中,都是比特率=波特率。
2)通信接口
前文提到的USB转TTL电平模块,要简单说一下,USB是电脑的接口,TTL是单片机引脚的电平,但是电脑和单片机之间是没法进行交流的。
🧑💻【电脑】 —(USB)→ ❓ →(TX/RX)—【单片机】
中间得来个“翻译官”——这就是我们说的 USB转TTL模块!
关于通信接口,还有两个分别是RS232\RS485,这里我并没有研究太深,大家感兴趣的,自己研究就行。
3)复用功能、重映射
说实话这两个我是经常搞混,我给大家进行一个总结,希望大家不要重走我的苦
复用功能;也总说成复用引脚,他就是可以实现同一个引脚可以干很多事情,给大家举个例子,大家可以翻开“stm32f10x中文参考手册”的第118页、120页,在PA9这个引脚上,不仅可以是定时器1通道2还可以是USART1_Tx
如果出现了这个复用引脚,那么我们在配置GPIO结构体的时候,就要选择AF,例如:GPIO_Mode_AF_PP。大家能明白为什么要有复用推挽复用开漏的功能了吧?
接下来讲重映射:
重映射是将外设的某个功能换个引脚来使用。
你原本以为串口只能走 PA9/PA10,结果它说:“不,我还能走 PB6/PB7,只要你设置一下重映射就行!”
这样不就能解决引脚冲突,让资源分配更灵活了嘛。
REMAP=0是默认,REMAP=1是重映射到对应的引脚。一旦要有重映射我们就要在代码中配置一个复用时钟函数,如下图:
重映射中还有部分重映射、完全重映射,给大家总结好表格,大家自行阅读。
类型 | 说明 |
---|---|
默认映射 | 比如 USART1 默认映射在 PA9 / PA10 |
部分重映射 | 比如 TIM2 可以从 PA0/PA1 映射成 PA15/PB3(只改部分) |
完全重映射 | 所有引脚全部换一组,比如 TIM3 从 PA6/PA7/PC6 映射成 PC8/PC9/PB0 |
五 代码讲解
以上关于知识点就到此为止了,代码相关的知识便会很简单,usart.c代码
关于USART中UART模式的硬件代码配置如下,我是利用了中断,大家如果不想用中断也可以,只需将相应的代码删除即可~
PA9--Tx发送,在这里的发送可就用到了第四部分的复用功能哦,AF_PP,翻阅前文即可
PA10--Rx接收
usart_structure.USART_BaudRate = 115200;usart_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;usart_structure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;usart_structure.USART_Parity = USART_Parity_No;usart_structure.USART_StopBits = USART_StopBits_1;usart_structure.USART_WordLength = USART_WordLength_8b;
波特率、校验位、模式等等,这里就是异步通信的标准了,需要把他们都配齐才可以。
为什么这里中断是RXNE呢?首先我们需要了解一下整个过程:
在这里说一下数据是怎么写进去的,首先发送一个数据,也就是库函数中的void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);这个意思就是将数据发送给数据寄存器TDR中,一旦数据写TDR中,TXE的标志位就会被清零,表示“发送数据寄存器”正在用。随后TDR中的数据转移到移位寄存器中(shift register),此时,TDR空了,也就代表着TXE重新置位,告诉数据可以发下一个数据给TDR了。
此时来到移位寄存器,移位寄存器要发送数据,这里发送是通过Tx引脚一位一位 的发送,包括了整个字节,起始位、数据位、校验位、停止位,等待发送完毕即可
常用三个东西,TXE、TC、RXNE
发送数据,需要用这个,TDR空,则用TXE(TXE=1)
判断数据整个过程(字符串)是否发送完成,则用TC
当你的设备需要从外部接收数据(RDR),中断处理,则用RXNE
#include "usart.h"
#include "stm32f10x.h" // Device header
#include "stdio.h"//普通uart
void my_usart_Config(void)
{GPIO_InitTypeDef GPIO_structure;USART_InitTypeDef usart_structure;NVIC_InitTypeDef NVIC_structure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);//PA9--Tx,发送GPIO_structure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_structure.GPIO_Pin = GPIO_Pin_9;GPIO_structure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init( GPIOA, &GPIO_structure );//PA10--Rx,接收GPIO_structure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_structure.GPIO_Pin = GPIO_Pin_10;GPIO_structure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init( GPIOA, &GPIO_structure ); usart_structure.USART_BaudRate = 9600;usart_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;usart_structure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;usart_structure.USART_Parity = USART_Parity_No;usart_structure.USART_StopBits = USART_StopBits_1;usart_structure.USART_WordLength = USART_WordLength_8b;USART_Init(USART1, &usart_structure);USART_Cmd( USART1,ENABLE);USART_ITConfig( USART1,USART_IT_RXNE,ENABLE); //RXNE,接收数据寄存器不空NVIC_structure.NVIC_IRQChannel = USART1_IRQn;NVIC_structure.NVIC_IRQChannelCmd = ENABLE;NVIC_structure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_structure.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_structure);}//发送寄存器TDR,移位寄存器shift register
//发送一个字节ascii码的值
void My_Usart_Send_Byte(USART_TypeDef* USARTx, uint16_t Data)
{USART_SendData( USARTx, Data);//写到TDR中while( USART_GetFlagStatus( USARTx, USART_FLAG_TXE) == RESET);//txe,发送数据的寄存器空了,移位寄存器已经空了
}//发送字符串
void My_Usart_Send_String(USART_TypeDef* USARTx, unsigned char *str)
{uint16_t i =0;do{My_Usart_Send_Byte( USARTx, *(str + i));i++;}while(*(str + i) != '\0');while( USART_GetFlagStatus( USARTx, USART_FLAG_TC) == RESET);//tc,数据已经彻底全部发送完成了}//发送汉字
int putc(int ch, FILE *p)
{USART_SendData( USART1, (u8)ch);while( USART_GetFlagStatus( USART1, USART_FLAG_TXE) == RESET);return ch;}
相关文章:

STM32 串口通信①:USART 全面理解 + 代码详解
一 前言 本篇文章并不会系统的从零开始讲起,适合大家对USART有一定的学习,再看本篇文章会有一定的收获,祝大家在本文中,吸收到新的知识。 二 通信方式 1)按数据传输的方式分(这就是“串行 vs 并行”&…...

【Java Web】速通CSS
参考笔记:JavaWeb 速通CSS_java css-CSDN博客 目录 一、CSS入门 1. 基本介绍 2. 作用 二、CSS的3种引入方式 1. 行内式 1.1 示例代码 1.2 存在问题 2. 写在head标签的style子标签中 2.1 示例代码 2.2 存在问题 3.以外部文件的形式引入(开发中推荐使用)⭐⭐⭐ 3.1 说明 3…...
List 源码翻译
List 源码翻译-jdk1.8 翻译来自 AI 大模型。 全部源码翻译下载 /** 版权所有 (c) 1997, 2014, Oracle 和/或其附属公司。保留所有权利。* ORACLE 专有/机密。使用受许可条款约束。*********************/package java.util;import java.util.function.UnaryOperator;/*** 有序…...

NHANES指标推荐:ALI
文章题目:A cross-sectional study examining the relationship between the advanced lung cancer inflammation index and prostate cancer 中文标题:一项检查晚期肺癌炎症指数与前列腺癌之间关系的横断面研究 发表杂志:Journal of Health…...
ChatGPT与认知科学:人机协同的未来图景
目录 导论:当机器开始“思考”,我们如何理解智能的未来? 第一部分:ChatGPT的技术解密与认知科学基础 第一章:ChatGPT的“芯”事:深入浅出聊技术,洞察认知新启示 1.1 开篇聊两句:…...
数智管理学(十二)
第四节 人工智能参与管理决策的角色 在当今数智化时代,人工智能(AI)作为一项颠覆性技术,正以前所未有的深度和广度融入企业管理领域,尤其是在决策环节发挥着日益关键的作用。随着大数据的爆炸式增长、算法的不断优化以…...

UE5 Mat HLSL - Load
特性Load()Sample()输入类型整数索引(int2/int3)浮点 UV 采样器状态(SamplerState)数据获取精确读取指定位置的原始数据基于 UV 插值和过滤后的数据典型用途精确计算、非过滤访问(如物理模拟)纹理贴图渲染…...

【Unity笔记】Unity WASD+QE 控制角色移动与转向(含 Shift 加速)实现教程
摘要: 在 Unity 游戏开发中,键盘控制角色的移动与转向是基础功能之一。本文详细讲解如何使用 C# 实现基于 WASD 移动、QE 转向 与 Shift 加速奔跑 的角色控制器,适用于第一人称、第三人称、自由漫游等场景。通过直观的 Transform 控制方法与可…...

HTML5 列表、表格与媒体元素、页面结构分析
1. 列表 无序列表 有序列表 定义列表 列表对比 2. 表格 跨列 跨行 跨行和跨列 3. HTML5的媒体元素 视频元素 注意:autoplay现在很多浏览器不支持了! 音频元素 4. 页面结构分析 5. 总结...
Spring Boot 如何实现定时任务
Spring Boot 如何实现定时任务 在现代的微服务架构中,定时任务是一个常见的需求。无论是数据定时同步、定时清理缓存,还是定时发送通知,Spring Boot 提供了非常强大且灵活的定时任务支持。本文将详细介绍如何在 Spring Boot 中实现定时任务&…...
免费开源 PDF 阅读器 自带虚拟打印机功能 多格式兼容
各位办公小能手们,今天咱来聊聊一款超厉害的PDF工具——PDFLite! 这PDFLite啊,那可是轻量级、免费又开源的好东西。它能干啥呢?主要就是能读PDF文件,还能转换文件格式,做基础的文档管理。下面咱就说说它的…...

换宽带ip地址会变吗?同一个宽带如何切换ip地址
在当今互联网时代,IP地址作为网络设备的"身份证",其重要性不言而喻。许多用户在使用宽带时都会遇到这样的疑问:换宽带IP地址会变吗?同一个宽带如何切换IP地址?本文将深入探讨这一问题,帮助读者全…...

第100+41步 ChatGPT学习:R语言实现误判病例分析
本期是《第33步 机器学习分类实战:误判病例分析》的R版本。 尝试使用Deepseek-R1来试试写代码,效果还不错。 下面上R语言代码,以Xgboost为例: # 加载必要的库 library(caret) library(pROC) library(ggplot2) library(xgboost)…...

贝锐蒲公英工业路由器R300A海外版:支持多国4G频段,全球组网
为更好地满足全球部署和企业出海项目的多样化需求,贝锐蒲公英异地组网工业路由器R300A海外版全新上市,并已正式上架速卖通!无论是跨国分支机构协同办公,还是海外工厂设备远程运维,R300A海外版都能为企业提供灵活、高性…...
字符串索引、幻读的解决方法
1. 给字符串加索引 1.1. 前缀索引vs完整索引 假设有一个支持邮箱登录的系统,用户表定义如下: CREATE TABLE SUser(ID BIGINT UNSIGNED PRIMARY KEY,email VARCHAR(64),... ) ENGINEInnoDB; 为了根据邮箱查询用户信息,常用的查询语句如下&…...

[特殊字符] 超强 Web React版 PDF 阅读器!支持分页、缩放、旋转、全屏、懒加载、缩略图!
在现代 Web 项目中,PDF 浏览是一个常见需求:从政务公文到合同协议,PDF 文件无处不在。但很多方案要么体验不佳,要么集成复杂。今天,我给大家带来一个开箱即用、功能全面的 PDF 预览组件 —— [PDFView](https://www.np…...

wireshark分析国标rtp ps流
1.将抓到的tcp或者udp视频流使用decode as 转为rtp包 2.电话->RTP->RTP播放器 选择Export 里面的Payload 就可以导出原始PS流...
jetpack compose 界面刷新的几种方式 如何避免无效的界面刷新
界面刷新的几种方式 在 Jetpack Compose 中,界面刷新主要依赖于数据的响应式变化。以下是几种常见的界面刷新方式及其原理: 1. 使用 MutableState(基础方式) 通过 mutableStateOf 创建可观察的状态,状态变化时会触发…...

【STM32+LAN9252+HAL库】EtherCAT从站搭建 保姆级教程
目录 一、生成协议栈及XML文件 二、使用stm32CuboMX配置外设 三、协议栈移植 鉴于本人对EtherCAT的掌握程度十分有限,这篇文章仅作为我搭建基础从站的过程记录不做更多讲解。本文内容主要为SPI模式的基础搭建,更多深入的学习资料和细节,大家…...

【harbor】--基础使用
推送 不同的管理工具都有说明 以docker为例 # 第一步--打标签 docker tag SOURCE_IMAGE[:TAG] 192.168.121.201:801/haohao_fist/REPOSITORY[:TAG] # 第二步--推送 docker push 192.168.121.201:801/haohao_fist/REPOSITORY[:TAG]默认push推送为https push会失败 解决办法…...

JAVA学习 DAY1 初识JAVA
本系列可作为JAVA学习系列的笔记,文中提到的一些练习的代码,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。 点赞关注不迷路!您的点赞、关注和收藏是对小编最大的支持和鼓励! 系列文章目录…...
*JavaScript中的Symbol类型:唯一标识符的艺术
JavaScript中的Symbol类型:唯一标识符的艺术 在JavaScript的世界中,数据类型一直是开发者关注的焦点。从基本的Number、String到后来的Symbol,每一种类型的引入都为语言本身注入了新的活力。而今天我们要聊的主角——Symbol,是ES…...

Vue能启动但访问空白?并报”export ‘default’ (imported as ‘Vue’) was not found in ‘vue’
场景 如图,vue项目的node_modules下载顺利,启动也顺利,但是访问却为空白页面 虽然页面是空白,但是通过浏览器控制台可以看出并非简单的空白,确实有不兼容问题在里面 分析问题 从上图浏览器控制台可以看出,…...

Electron-vite【实战】MD 编辑器 -- 系统菜单(含菜单封装,新建文件,打开文件,打开文件夹,保存文件,退出系统)
最终效果 整体架构 src/main/index.ts import { createMenu } from ./menu在 const mainWindow 后 // 加载菜单createMenu(mainWindow)src/main/menu.ts import { BrowserWindow, Menu, MenuItem, MenuItemConstructorOptions, dialog, shell } from electron import fs from…...
如何将 PDF 文件中的文本提取为 YAML(教程)
这篇博客文章将向你展示如何将 PDF 转换为 YAML,通过提取带有结构标签的标记内容来实现。 什么是结构化 PDF? 一些 PDF 文件包含结构化内容,也称为带标签(tagged)或标记内容(marked content)&…...

【Docker系列】Docker 容器内安装`ps`命令
博客目录 一、为什么需要在 Docker 容器中安装ps命令二、不同 Linux 发行版的安装方法1. Alpine Linux 镜像的安装方法2. Debian/Ubuntu 镜像的安装方法3. CentOS/RHEL 镜像的安装方法 三、验证安装与基本使用四、永久解决方案:修改 Dockerfile1. Alpine 基础镜像的…...
Netty 实战篇:为 Netty RPC 框架增加超时控制与重试机制,防止系统雪崩
本文介绍如何在自研 Netty RPC 框架中实现超时控制与重试机制。合理的超时策略可以避免调用卡死,重试机制可以提升调用成功率,在高可用系统中不可或缺。 一、为什么要有超时和重试? RPC 是跨进程调用,失败是常态。常见问题包括&a…...
PDFGear——完全免费且功能强大的PDF处理软件
关键词 :PDFGear、免费、跨平台、多功能、OCR 概要 :PDFGear是一款完全免费且功能强大的PDF处理软件,支持Windows、macOS、iOS和Android等多平台使用。它集PDF阅读、编辑、格式转换、OCR识别及AI智能助手于一体,满足用户多样化文档…...

华为OD机试真题——生成哈夫曼树(2025A卷:100分)Java/python/JavaScript/C/C++/GO六种最佳实现
2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 本文收录于专栏:《2025华为OD真题目录+全流程解析/备考攻略/经验分享》 华为OD机试真题《生成…...

大厂前端研发岗位设计的30道Webpack面试题及解析
文章目录 一、基础核心二、配置进阶三、性能优化四、Loader原理五、Plugin机制六、高级应用七、工程化实战八、原理深挖九、异常处理十、综合场景一、基础核心 Webpack的核心概念是什么? 解析:入口(entry)、输出(output)、加载器(loader)、插件(plugins)、模式(mode)。Loader…...