STM32 串口通信①:USART 全面理解 + 代码详解

article/2025/6/25 0:48:28

一 前言

本篇文章并不会系统的从零开始讲起,适合大家对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;}

http://www.hkcw.cn/article/ifgbdNLKeK.shtml

相关文章

基于图神经网络的自然语言处理:融合LangGraph与大型概念模型的情感分析实践

在企业数字化转型进程中,非结构化文本数据的处理与分析已成为核心技术挑战。传统自然语言处理方法在处理客户反馈、社交媒体内容和内部文档等复杂数据集时,往往难以有效捕获文本间的深层语义关联和结构化关系。大型概念模型(Large Concept Mo…

极地导航的难点及应对措施(上)

在之前的博文《南北极导航选用什么投影?》和何老师的博文《高纬度、跨极区导航技术》中简单说了说南北极导航的投影设置问题。 本文主要说一说南北极导航中实际工作的难点问题以及应对措施。下图是南北极的位置图,从图中可以看出,南极是大陆…

Centos系统搭建主备DNS服务

目录 一、主DNS服务器配置 1.安装 BIND 软件包 2.配置主配置文件 3.创建正向区域文件 4.创建区域数据文件 5.检查配置语法并重启服务 二、从DNS服务配置 1.安装 BIND 软件包 2.配置主配置文件 3.创建缓存目录 4.启动并设置开机自启 一、主DNS服务器配置 1.安装 BIN…

【图像处理入门】3. 几何变换基础:从平移旋转到插值魔法

摘要 掌握图像的几何变换相当于学会「图像的空间魔法」。本文将带你理解平移/旋转/缩放的数学原理,掌握OpenCV中warpAffine和getAffineTransform的核心用法,对比最近邻、双线性等插值算法的优劣。通过图像翻转、镜像、透视变换实战,学会用变…

TomatoSCI分析日记:数据分析为什么用csv不用excel

其实并不是多余,虽然看到的内容是一样的,但是相比excel文件,csv文件没这么多繁文缛节,效率更高。 1.csv更干净 csv本质是纯文本,只有你看到的数据,没有花里胡哨的单元格格式、颜色、批注等隐藏信息&#…

【鱼皮-用户中心】笔记

任务:完整了解做项目的思路,接触一些企业及的开发技术 title 企业做项目流程需求分析技术选型 计划一一、前端初始化1. **下载node.js**2. **安装yarn**3. **初始化 Ant Design Pro 脚⼿架(关于更多可进入官网了解)**4. **开启Umi…

基于 Chrome 浏览器扩展的Chroma简易图形化界面

简介 ChromaDB Manager 是基于 Chrome 浏览器扩展的一款 ChromaDB(一个流行的向量数据库)的数据查询工具。提供了一个用户友好的界面,可以直接从浏览器连接到本地 ChromaDB 实例、查看集合信息和分片数据。本工具特别适合开发人员快速查看和…

[ElasticSearch] ElasticSearch的初识与基本操作

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…

Kafka 如何保证不重复消费

在消息队列的使用场景中,避免消息重复消费是保障数据准确性和业务逻辑正确性的关键。对于 Kafka 而言,保证不重复消费并非单一机制就能实现,而是需要从生产者、消费者以及业务层等多个维度协同配合。接下来,我们将结合图文详细解析…

【快速解决】数据库快速导出成sql文件

1、cmd直接打开 输入命令 mysqldump -u用户名 -p密码 数据库名 > 导出文件名.sql修改成自己mysql的用户名和密码,和要导出的数据库名称,给导出的文件起一个名字。 如图所示 这样就成功了。

OldRoll复古胶片相机:穿越时光,定格经典

在数字摄影盛行的今天,复古胶片相机的独特魅力依然吸引着无数摄影爱好者。OldRoll复古胶片相机这款软件,以其独特的复古风格和丰富的胶片滤镜效果,让用户仿佛穿越回了那个胶片摄影的黄金时代。它不仅模拟了胶片相机的操作界面,还提…

利用Dify创建一个公司产品知识问答

1、创建知识库 打开dify,创建知识库。 选择创建一个空知识库,对知识库进行命名,或者直接导入已有文本,拖曳或选择文件进入下一步,会自动命名知识库。 创新空知识库后,点击添加文件,再导入已有文…

redis核心知识点

Redis是一种基于内存的数据库,对数据的读写操作都是在内存中完成,因此读写速度非常快,常用于缓存,消息队列、分布式锁等场景。 Redis 提供了多种数据类型来支持不同的业务场景,比如 String(字符串)、Hash(哈希)、 Lis…

黄金价格查询接口如何用C#进行调用?

一、什么是黄金价格查询接口? 提供当日实时黄金行情数据,如上交所,银行账户黄金,国际金价、金店价格等,获取最低价、最高价、卖价、昨日收盘价、开盘价、涨跌值、最新价格、时间、买价、涨跌幅等行情。 二、科技赋能…

JVM 核心组件深度解析:堆、方法区、执行引擎与本地方法接口

一、JVM 堆内存:对象的生存与消亡之地 作为 Java 虚拟机中最大的内存区域,堆内存是所有对象实例的 “出生地” 与 “安息所”。从程序运行的角度看,所有通过new关键字创建的对象都在堆中分配内存,其生命周期完全由垃圾回收机制&am…

每日Prompt:隐形人

提示词 黑色棒球帽,白色抹胸、粉色低腰短裙、白色襪子,黑色鞋子,粉紅色背包,衣服悬浮在空中呈现动态姿势,虚幻引擎渲染风格,高清晰游戏CG质感,户外山林背景,画面聚焦在漂浮的衣服上…

Ubuntu22.04通过命令行安装qt5

环境: VMware17Pro ubuntu-22.04.5-desktop-amd64.iso 步骤: 安装好虚拟机进入shell,或通过ssh登录,确保虚拟机能上外网,执行命令: sudo apt update sudo apt install build-essential sudo snap in…

【Java基础05】面向对象01

文章目录 1. 设计对象并使用1.1 类与对象1.2 封装1.2.1 private关键字1.2.2 this关键字成员变量和局部变量的区别 1.2.3 构造方法1.2.4 标准JavaBean类 1.3 对象内存图 本文部分参考这篇博客 1. 设计对象并使用 1.1 类与对象 public class 类名{1、成员变量(代表属性,一般是名…

C58-字符串拼接函数strcat

一 C语言 strcat 函数简明总结 功能 将 src 字符串拼接到 dest 字符串末尾(覆盖 dest 的 \0,并在新末尾补 \0)。 原型 char *strcat(char *dest, const char *src);要点 目标空间必须足够大,否则导致缓冲区溢出(未…

G25-05-31Rust开源项目日报 Top10

根据Github Trendings的统计,今日(2025-05-31统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10TypeScript项目1Pake: 利用 Rust 轻松构建轻量级多端桌面应用 创建周期:491 天开发语言:Rust协议类型:MIT LicenseStar数量:2095…