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

嵌入式:深刻理解UART与USART串口通信的波特率与帧格式

前言

文章合集:

嵌入式系列https://blog.csdn.net/2401_88433210/category_13196870.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=13196870&sharerefer=PC&sharesource=2401_88433210&sharefrom=from_link

文章以STM32F103ZET6芯片为例来介绍

建议先看一下这一篇博客了解UART与USART串口通信的特点

嵌入式:深刻理解UART与USART串口通信的特点-CSDN博客本文以STM32F103ZET6芯片为例,介绍了UART(通用异步收发器)的基本概念和工作原理。UART采用串行异步通信方式,通过Tx(发送)和Rx(接收)两根数据线实现全双工通信,通信双方需交叉连接并共地。文章对比了串行与并行通信的优缺点,解释了同步与异步通信的区别,并强调UART作为MCU片上外设的重要性。此外,还区分了UART与功能更强大的USART(支持同步模式),说明USART在忽略同步功能时等同于UART。最后指出通信双方必须遵守波特率和帧格式等约定规则才能实现有效数据传输。https://blog.csdn.net/2401_88433210/article/details/163635212?spm=1011.2415.3001.10575&sharefrom=mp_manage_link

一、MCU 和 USART 设备通信的宏观过程和问题

如下图所示,使用 USART 进行通信的设备之间,用 Tx 和 Rx 交叉相连,意思就是一端发送、一端接收。 此处是 MCU 内部的 USART 模块和外部的 USART 设备之间进行通信。

宏观数据传输流程如下:

  1. 发送端(Tx)发送二进制数据‘1’时,输出高电平;
  2. 接收端(Rx)读取到高电平时,代表得到二进制数据‘1’;
  3. 发送端(Tx)发送二进制数据‘0’时,输出低电平;
  4. 接收端(Rx)读取到低电平时,代表得到二进制数据‘0’;
  5. 数据会按顺序拆分成一个个的数据位,并依次进行发送和接收。

示例 (以 MCU 端发送为例)

假定 MCU 要传输 1 个字节的数据 0x55,二进制序列为:"0101 0101"

  1. 发送端,依次输出以下电平序列:高、低、高、低、高、低、高、低
  2. 接收端,依次读取到电平序列:高、低、高、低、高、低、高、低,就代表接收到了二进制数:"0101 0101"

但是上述的通信过程,看似可行,实则不行,主要有以下 2 个问题:

  • 通信双方发送和接收数据快慢的问题
  • 接收端怎么知道发送端什么时间开始或者结束数据发送的?一次计划携带多少数据?

“波特率”“帧格式”就是为了解决这两个问题。

二、波特率与比特率

关于对波特率与比特率的理解,详见下面一篇博文

嵌入式:深刻理解比特率与波特率-CSDN博客【比特率与波特率区别摘要】比特率(bit/s)衡量每秒传输的二进制位数,反映有效信息传输速度(如千兆宽带1000Mbit/s=125MB/s);波特率(Baud)表示每秒传输的码元数量,一个码元可携带多比特信息。两者关系为:比特率=波特率×每码元比特数(例:4色球系统波特率1Baud时,比特率为2bps)。注意单位换算差异(1Kbit=1000bit vs 1KB=1024B)。https://blog.csdn.net/2401_88433210/article/details/163636836?spm=1011.2415.3001.10575&sharefrom=mp_manage_link

三、USART 速度与波特率

结合之前所讲,USART 在串行通信的过程中,速度由波特率 (Baud Rate) 决定的,USART 是硬件电路,所以速度问题重点应该在表示电气过程中的速率上面。后面在使用 USART 的过程中,需要我们提前设置好通信双方的波特率,进而让双方进行串口通信。

单片机的 USART,使用的是高低电平两种状态传递的通信方式,属于 2 进制码元,也就是波特率 = 比特率,所以后面我们能见到很多工具在设置波特率的时候,单位用 b/s 也不要觉得奇怪,能理解即可。

为了进一步理解波特率和速度的关系,我们举一个极度极端的例子:

在比特率 = 波特率的场景中,不考虑什么帧格式,1S 内,如果全部都是低电平,波特率是 10,那么就是传递 10 个 0,但是如果波特率是 20,就会被理解成为 20 个 0。

结论:

  • 一般而言,波特率设置的越高,单位时间内传递的信息量未来会越大,换句话说,波特率越高传输速度越快
  • 波特率其实是一个个数单位,只不过是单位时间的个数 (速度单位)

波特率背后的潜在含义:单个信号在传输的过程中,会持续多长时间!

比如,有一个波特率为 10 的信号:

那么波特率会决定什么呢?

  • 除之前的速度问题
  • 决定了前面讲的发送高低电平的持续时长

❓ 那么,未来给 USART 设置波特率,我们另一个朴素的理解就是:对于发送方,你打算多长时间发一个数据,持续发多长时间。对于接收方,你就是打算多长时间收一个数据,持续收多长时间,这里的 "一个数据",就理解成为 1bit

USART 波特率

  • STM32 中,USART 一般的常用波特率是 9600 Bd 或者 115200Bd
  • 通信双方发送和接收数据快慢的问题,可以由通信双方设置相同的波特率来解决

四、 USART 帧格式

通过设置通信双方的波特率,我们已经解决了通信速度的问题。可是,对应接收方,它怎么知道数据开始发了?它怎么知道有多少个数据?它怎么知道数据什么时候传递完毕了?这就需要通信双方继续约定通信格式了,这个格式我们叫做‑帧格式。

❓ 注意:

  • 帧格式是人约定出来的,相当于人让通信设备使用相同的规则通信
  • 这个约定的通信格式,也可以叫做协议
  • 不过,在单片机通信领域,更喜欢叫做帧格式

USART 是异步通信模式,有了双方已知的数据帧格式,这样接收端才能正确解析数据。如下图所示,就是UART 的通信帧格式。

组成部分状态 / 电平作用
空闲状态 (Idle State)高电平(逻辑 '1')当没有数据传输时,通信线保持高电平。
起始位 (Start Bit)低电平(逻辑 '0')持续一个位周期(bit period),通知接收端数据传输开始同步时钟。
数据位 (Data Bits)可变实际传输的数据,通常为 5 到 9 位,最常见的是 8 位数据。低有效位 (LSB) 开头先传输。
奇偶校验位 (Parity Bit)可选用于错误检测。如果启用,它位于数据位和停止位之间。校验(Odd Parity)或偶校验(Even Parity),用于确保传输的个数为奇数或偶数。
停止位 (Stop Bit)高电平(逻辑 '1')持续 1、1.5 或 2 个位周期,标志数据帧的结束,并使接收准备接收下一个起始位。

❓ 注意:

  • 其中,空闲,起始位,停止位,都是必须要有的。
  • 数据帧的本质是约定,上述表格中最重要的是:数据帧由哪些部分组成的约定,就是绿色字体部分。而数据位和校验位虽然可变或者可选,但是可以完全不用担心,因为未来设置数据帧格式的时候,通信双方都要设置相同的格式,通信双方完全可以自由准确的识别。

当然,STM32F103 官方手册中数据位通常是:

其中工作中,用的最多的是 8 位数据位,1 位校验。

1. 空闲状态(Idle State)

在没有数据传输时,串口线路应保持逻辑高电平 (其实叫做逻辑 1),也就是空闲状态,如通信帧格式中 ① 标识区域所示。

❓ 为什么?

  • 串行通信,甚至单片机通信,在没有信号的时候,默认很多都是处于高电平。
  • 而未来 USART 需要用拉低电平表示起始,所以 USART 这里默认也是高电平,或者说,默认是高电平,所以起始位就只能用拉低电平来表示了。

2. 起始位(Start Bit)

起始位的下降沿(1‑>0)是从空闲状态进入新帧的标志。起始位(逻辑低电平 (0))持续 1 个比特位时间(具体长度,由波特率决定),起始位用于告知接收端一个新数据帧的开始,这是接收端进行比特位同步的关键信号!如通信帧格式中 ② 标识区域所示。

3. 数据位(Data Bits)

STM32 中,数据位个数通常可选 8 位或者 9 位,最常见的是 8 位(一个字节),承载实际要传输的信息内容,逻辑高 (1) 或逻辑低 ( 0 ) 代表数据位本身。

USART 中,数据 LSB(Least Significant Bit:最低有效位)最先发送,然后是次低位,依此类推,最后发送 MSB( Most Significant Bit:最高有效位)。如通信帧格式中 ③ 标识区域所示。

❓ 注意:

什么是 LSB?

LSB是 Least Significant Bit 的缩写,意为最低有效位。

  • 定义:在一个二进制数中,LSB 是位于最右边的那个位,具有最小的位权
  • 示例:在二进制数 1011 中,最右边的 1 就是 LSB。
  • 1 × 2³ + 0 × 2² + 1 × 2¹ + 1 × 2⁰
  • 也就是要发送 1011,发送顺序是 1 1 0 1,先发送低有效位,再发高有效位
  • 在 USART 中的应用:在大多数异步串行通信(如 USART、RS‑232)中,数据通常是从 LSB 开始先传输(LSB first)。这是为了让接收设备能够更快地开始处理数据,而不需要等待整个字节接收完毕。

什么是 MSB?

MSB是 Most Significant Bit 的缩写,意为最高有效位。

  • 定义:在一个二进制数中,MSB 是位于最左边的那个位,具有最大的位权。
  • 示例:在二进制数 1011 中,最左边的 1 就是 MSB。
  • 1 × 2³ + 0 × 2² + 1 × 2¹ + 1 × 2⁰
  • 也就是要发送 1011,发送顺序是 1 0 1 1,先发送高有效位,再发低有效位
  • 在 USART 中的应用:少数通信协议或系统可能配置为 MSB‑first 传输,但不如 LSB‑first 常见。

4. 校验位(Parity Bit)

校验位如通信帧格式中 ④ 标识区域所示。校验位是简单的错误检测机制,用于检测传输过程中特定数量的比特是否发生了翻转错误,可配置的校验类型如下:

  • 无校验(None):不发送校验位,即无校验。
  • 奇校验(Odd):设置校验位使得数据位和校验位中 1 的总个数为奇数。
  • 偶校验(Even):设置校验位使得数据位和校验位中 1 的总个数为偶数。

示例(8 位数据):

  1. 奇校验示例:
  • 假定数据为 “11110000”,那么校验位需要设置为 1,变成 11110000 1,这样就有奇数个‘1’(5 个‘1’)。
  • 假定数据为 “11111110”,那么校验位需要设置为 0,变成 11111110 0,这样还是奇数个‘1’(7 个‘1’)。

奇校验 (Odd Parity) 的核心目的就是确保包括数据位和校验位在内的整个数据包中,二进制 '1' 的总数是奇数个。

  1. 偶校验示例:
  • 假定数据为 “11110000”,那么校验位需要设置为 0,变成 11110000 0,这样就有偶数个‘1’(4 个‘1’)。
  • 假定数据为 “11111110”,那么校验位需要设置为 1,变成 11111110 1,这样就有偶数个‘1’(8 个‘1’)。

偶校验 (Even Parity) 的核心目的就是确保包括数据位和校验位在内的整个数据包中,二进制 '1' 的总数是偶数个。

⚠注意:

  • 无论是奇校验,还是偶校验,都只能检测奇数个比特位翻转错误(如:1 位、3 位翻转…),无法检测偶数个比特翻转错误,也无法纠正错误。
  • 奇偶校验,只能从概率上甄别出部分比特位翻转等错误问题

说明: 想象我们用偶校验规则:一袋苹果必须是偶数个。

场景一:1 个错误(奇数个错误)

  1. 发送方装了 6 个完好的苹果(偶数)。
  2. 路上有 1 个苹果坏了。
  3. 接收方数到 5 个完好的苹果(奇数)。
  4. 接收方惊呼:“不对!应该都是好的偶数个,出错了!”(错误被发现)

场景二:2 个错误(偶数个错误)

  1. 发送方装了 6 个完好的苹果(偶数)。
  2. 路上同时有 2 个苹果坏了。
  3. 接收方数到 4 个完好的苹果(偶数)。
  4. 接收方满意地说:“没错!是偶数个好的!一切正常。”(错误没被发现)

想象我们用奇校验规则:一袋完好的苹果必须是奇数个。

场景一:1 个错误(奇数个错误)

  1. 发送方装了 5 个完好的苹果(奇数)。
  2. 路上有 1 个苹果坏了。
  3. 接收方数到 4 个完好的苹果(偶数)。
  4. 接收方惊呼:“不对!应该是奇数个好的,出错了!”(错误被发现)

场景二:2 个错误(偶数个错误)

  1. 发送方装了 5 个完好的苹果(奇数)。
  2. 路上同时有 2 个苹果坏了。
  3. 接收方数到 3 个完好的苹果(奇数)。
  4. 接收方满意地说:“没错!是奇数个好的!一切正常。”(错误没被发现)

5. 停止位(Stop Bits)

停止位表示帧的结束,固定为逻辑高电平 (1),可以配置为 1 位、1.5 位、2 位,停止位结束后会回到空闲状态。如通信帧格式中 ⑤ 标识区域所示。

注意:

  • 这里说的 1 位、1.5 位、2 位是指逻辑高电平(1)需要保持的时间长度,具体多长和波特率有关。

问题 1:有没有有可能在串口通信的时候,把起始位当做数据位?

不可能,因为串口通信的时候,起始位,数据位,校验位有多少个都是双方约定好格式,比如通信双方约定:拉高的起始位,8 位数据位,1 位校验位,刚开始遇到的第一个拉低位,就一定会被接收方判断成为起始位。

问题 2:有没有有可能在串口通信的时候,把数据位当成结束位?为什么?

不可能,因为串口通信的时候,起始位,数据位,校验位有多少个都是双方约定好格式,比如通信双方约定: 1 位拉低的起始位,8 位数据位,1 位校验位,1+8+1=10,如果在没有收到这 10 个 bit 信息的时候,是不会有判断结束位逻辑的,也就不会把数据位当成结束位。

问题 3:有没有有可能在串口通信的时候,把结束位当成数据位的一部分?为什么?

不可能,因为串口通信的时候,起始位,数据位,校验位有多少个都是双方约定好格式,比如通信双方约定: 1 位拉低的起始位,8 位数据位,1 位校验位,1+8+1=10,也就是固定大小的 10 个比特位只要收完,有效数据传输就完成了,再收到高电平,就判定数据帧结束了,不会把结束位当做数据位。

问题 4: 为什么结束位需要拉高?

起始位需要拉低电平,表征起始位。

如果当前帧传递完毕,没有结束位,即没有强制拉高电平,此时 tx 输出的电平就取决于当前帧的最后一位,这个高低电平都有可能。

那么传递下一帧,它的起始位就不能 100% 有一个拉低的动作,会影响下一帧的正确开始。

如果当前帧传递完毕,必须有结束位,即强制拉高电平,就保证了在下一帧的起始位到来之前,线路上至少有 1 个(或 1.5/2 个)比特周期的高电平,方便下一帧拉低。

当然,停止位之后,如果没有发送下一帧数据,线路就会维持高电平,恢复默认状态。

✨ 让一切具有确定性,是 USART 追求的。

细节:

  • 每一帧格式起始位,数据位,校验位 (可选),停止位,都必须要有,尤其是起始和结束。
  • 发送 5 个 8 位数据时,会形成 5 个独立的数据帧(Frame)。每一帧都必须包含自己的起始位、数据位和停止位。

因此,发送 5 个 8 位数据,确实会有 5 个停止位。 整个传输过程是这样的:

  • 发送第 1 个数据字节:[起始位] [8 个数据位] [停止位]
  • 发送第 2 个数据字节:[起始位] [8 个数据位] [停止位]
  • 发送第 3 个数据字节:[起始位] [8 个数据位] [停止位]
  • 发送第 4 个数据字节:[起始位] [8 个数据位] [停止位]
  • 发送第 5 个数据字节:[起始位] [8 个数据位] [停止位]

如果把停止位看作是每一帧数据的 “结束标志” 或 “句号”,那么每发送一个数据,都需要画上一个句号,以便接收端知道这一帧结束了,准备接收下一帧的起始位。

它是 UART 通信中最核心的参数之一,直接决定了通信双方能否正确解读数据。波特率的单位为 bps(baud per second),例如:9600 波特率表示每秒传输 9600 个信号单元。

五、USART 帧格式与波特率

有了 USART 帧格式和波特率的理解,那么我们来算一笔账:

示例 1

  • 假定波特率为 9600 Bd,在 USART 中,波特率 = 比特率。
  • 假定帧结构:1 起始位 + 8 数据位 + 无校验位 + 1 停止位 = 10 位。
  • 理论每秒传输字节 (即字节传输速率)= 9600bps / 10bits/byte = 960 字节 / 秒

示例 2

  • 假定波特率为 115200 Bd,在 USART 中,波特率 = 比特率。
  • 假定帧结构:1 起始位 + 8 数据位 + 无校验位 + 1 停止位 = 10 位。
  • 理论每秒传输字节 (即字节传输速率)= 115200bps / 10bits/byte = 11520 字节 / 秒
  • 通过上面的计算,主要是让大家对 USART 的速度有一个量化的认识,也能直观看到,波特率对于 USART 传输速度的影响。
http://www.cnnetsun.cn/news/4180049.html

相关文章:

  • 改一个叶子要重渲染 1 万次,Signals 只跑 1 次:细粒度响应式的实测复盘
  • 大学生用 AI 学编程的正确姿势:从问答案到做验证
  • 2026年5款AI写网文剧本工具实测横评:谁才是终极消痕助手?
  • Multimodal-Sentiment-Analysis 完整指南:BERT+ResNet50 五种融合方法,多模态情感分析快速上手
  • 真理不需要验证:KTS理论对西方学术范式动机污染的彻底诊断
  • 探秘 Python 枚举类型:从基础到实战的深度指南
  • Cursor版GitHub上线后再升级,/goal转正、子Agent独立,重塑软件工程生产线!
  • 【AI大模型进阶】写一个“法律条文检索助手”,体验RAG实战威力
  • 拓扑排序详解(Topological Sort)
  • 无锡芯健细胞:免疫细胞存储适配人群全解析
  • 雨晨 Windows 11 IoT 企业版 26H1 轻装 28120.2760
  • 工信部三级智能制造评审通关背后:一天,一个项目组,一家灯饰厂
  • 德系车维修质保体系的技术支撑分析:从配件追溯到施工标准化
  • python的运筹学工业场景模拟第九十二篇:金属型材下料,多种型材原料,多规格零件,整数规划,最小原料消耗,统计边角料。
  • 大厂Java面试实录:从Java SE到微服务,电商场景下的技术拷问与谢飞机翻车合集
  • 科颜氏白泥同源配方OEM代工厂揭秘:比价输在起跑线的老板,都忽略了泥膜料体的这三道隐形门槛
  • 福意联血液运输冷藏箱的优势特点详解
  • 关于“真理硬度”与KTS体系绝对自明性的系统性陈述
  • 让大模型思考,让小模型执行:在 Elastic Workflows 中拆分 LLM 成本
  • 技术面试黄金技巧:从STAR法则到薪资谈判
  • Java面试:从八股文到实战的演变与准备策略
  • Ceres损失函数选型指南:从原理到实战的鲁棒优化策略
  • 齿轮参数化设计:从建模到校核的工程实践指南
  • CANdelaStudio入门指南:从零创建汽车诊断数据库
  • Gradle配置全解析:从核心文件到性能优化与实战避坑指南
  • VSCode调试中No such file or directory错误:彻底解决相对路径与工作目录问题
  • Python类型注解与typing模块实战指南:从基础到工程化应用
  • Linux系统安装Qt5:三种方法详解与配置实战指南
  • IntelliJ IDEA自定义背景全攻略:用Background Image Plus插件打造高效护眼开发环境
  • 电商支付与结算系统架构实战:从网关设计到微服务中台演进