STM32 USART 详解(二):从波特率同步到数据帧解析

目录

  • 前言
  • 一、串口通信中的速率协调问题
    • [1.1 为什么串口通信会"鸡同鸭讲"?](#1.1 为什么串口通信会“鸡同鸭讲”?)
  • 二、比特率:衡量信息传输速度的标尺
    • [2.1 比特率的定义与单位](#2.1 比特率的定义与单位)
    • [2.2 生活中的实例:千兆带宽的真相](#2.2 生活中的实例:千兆带宽的真相)
      • [2.2.1 详细的换算推导](#2.2.1 详细的换算推导)
  • 三、波特率:串口通信的"心跳"
    • [3.1 波特率 vs 比特率](#3.1 波特率 vs 比特率)
      • [3.1.1 "扔球游戏"通俗原理解析](#3.1.1 “扔球游戏”通俗原理解析)
    • [3.2 波特率在波形上的体现](#3.2 波特率在波形上的体现)
  • 四、如何确立通信握手
    • [4.1 历史遗留的标准数值](#4.1 历史遗留的标准数值)
    • [4.2 解决通信失败的关键:约定一致](#4.2 解决通信失败的关键:约定一致)
  • 五、帧格式约定
    • [5.1 为什么必须约定"帧格式"?](#5.1 为什么必须约定“帧格式”?)
    • [5.2 标准 USART 数据帧的解剖](#5.2 标准 USART 数据帧的解剖)
      • [5.2.1 传输顺序详解:LSB First 与 MSB First](#5.2.1 传输顺序详解:LSB First 与 MSB First)
        • [什么是 LSB?](#什么是 LSB?)
        • [什么是 MSB?](#什么是 MSB?)
        • [在 USART 中的实际应用](#在 USART 中的实际应用)
    • [5.3 传输过程的量化计算](#5.3 传输过程的量化计算)
  • 结语

🎬 云泽Q个人主页
🔥 专栏传送入口 : 《C语言》《数据结构》《C++》《Linux》《蓝桥杯系列》《笔试算法》《AI赋能》《STM32》《Python

⛺️遇见安然遇见你,不负代码不负卿~


前言

大家好啊,我是云泽Q,欢迎阅读我的文章,一名热爱计算机技术的在校大学生,喜欢在课余时间做一些计算机技术的总结性文章,希望我的文章能为你解答困惑~

一、串口通信中的速率协调问题

1.1 为什么串口通信会"鸡同鸭讲"?

在嵌入式开发中,我们经常会遇到一种看似玄学的问题:明明 MCU(微控制器)和外部串口设备之间的物理连线完全正确,TX 接 RX,RX 接 TX,地线 GND 也共用了,但就是无法正常通信,或者接收到的数据全是乱码。这就是双方虽然建立了连接通道,但如果双方在沟通的节奏上没有达成默契,信息就无法被正确理解。

这就引出了串口通信中最核心的一个概念:速率协调

想象一下这个场景:MCU 作为一个发送方,它的工作节奏非常快,每 1 秒就能发送 8 个高低电平信号;而接收端的串口设备却是一个"慢性子",它以为对方是每 2 秒才发送一个信号。结果就是,当 MCU 已经发完了 8 个数据时,接收端才刚刚读完第 4 个数据。这种收发步调的不一致,直接导致了数据的丢失和错乱。

要解决这个问题,我们必须引入一个能够量化"快慢"的标准。在 USART(通用同步异步收发器)通信中,这个标准就是波特率 。但在深入讲解波特率之前,为了避免概念混淆,我们需要先厘清另一个经常与之相伴的概念------比特率

二、比特率:衡量信息传输速度的标尺

2.1 比特率的定义与单位

所谓的比特率,指的是每秒钟传送的**比特位(bit)**的个数。它也被称为"传信率",侧重点在于衡量有效信息的传输速度。

  • 基本单位bit/sbps (bits per second)。
  • 常用倍数单位Kbit/sMbit/sGbit/s

这里有一个极其重要且容易被程序员搞混的细节:在描述比特率时,这里的 K、M、G 遵循的是十进制换算规则,而非计算机存储中习惯的二进制规则。

  • 十进制(通信领域) : 1 K = 1000 1\text{K} = 1000 1K=1000, 1 M = 1 , 000 , 000 ( 10 6 ) 1\text{M} = 1,000,000 (10^6) 1M=1,000,000(106), 1 G = 1 , 000 , 000 , 000 ( 10 9 ) 1\text{G} = 1,000,000,000 (10^9) 1G=1,000,000,000(109)。
  • 二进制(存储领域) : 1 K = 1024 ( 2 10 ) 1\text{K} = 1024 (2^{10}) 1K=1024(210), 1 M = 1024 × 1024 ( 2 20 ) 1\text{M} = 1024 \times 1024 (2^{20}) 1M=1024×1024(220)。

2.2 生活中的实例:千兆带宽的真相

为了让大家更直观地理解比特率,我们来看一个生活中最常见的例子------家里的宽带网络。

当你去办理宽带业务时,运营商会宣传这是"千兆带宽"。这里的"千兆",指的就是 1000 Mbit/s 。请注意,这里使用的是小写的 b (bit),而不是大写的 B (Byte)。

  • 小写 b (bit):比特位,信息的最小单位。
  • 大写 B (Byte):字节,1 Byte = 8 bits。

2.2.1 详细的换算推导

让我们通过一个具体的计算过程,来看看 1000M 带宽到底意味着什么。

  1. 理论峰值计算(十进制转十进制)

    1000 Mbit/s ÷ 8 = 125 MB/s 1000 \text{ Mbit/s} \div 8 = 125 \text{ MB/s} 1000 Mbit/s÷8=125 MB/s

    这里的 M 依然是 10 6 10^6 106。也就是说,理论上你的网卡每秒最大能吞吐 125 × 10 6 125 \times 10^6 125×106 个字节。

  2. 程序员视角的换算(转换为二进制单位)

    我们在操作系统中看到的文件大小通常是基于二进制的(即 MiB,虽然常显示为 MB)。

    • 首先将总比特数算出: 1000 × 10 6 bit 1000 \times 10^6 \text{ bit} 1000×106 bit
    • 转换为 Kbit (二进制): ( 1000 × 10 6 ) ÷ 1024 ≈ 976 , 562 Kbit (1000 \times 10^6) \div 1024 \approx 976,562 \text{ Kbit} (1000×106)÷1024≈976,562 Kbit
    • 转换为 Mbit (二进制): 976 , 562 ÷ 1024 ≈ 953 Mbit 976,562 \div 1024 \approx 953 \text{ Mbit} 976,562÷1024≈953 Mbit
    • 最后转换为 Byte (字节): 953 ÷ 8 ≈ 119 MB/s 953 \div 8 \approx 119 \text{ MB/s} 953÷8≈119 MB/s (此处指 MiB/s)

所以,当你拥有 1000M 带宽时,理论上的最高下载速度大约是 119 MB/s

  1. 实际下载时间估算
    假设你要下载一部大小为 2GB(即 2 × 1024 = 2048 MB 2 \times 1024 = 2048 \text{ MB} 2×1024=2048 MB)的电影。
    所需时间 = 2048 MB 119 MB/s ≈ 17.2 秒 \text{所需时间} = \frac{2048 \text{ MB}}{119 \text{ MB/s}} \approx 17.2 \text{ 秒} 所需时间=119 MB/s2048 MB≈17.2 秒
    当然,实际网络环境中很难一直跑满峰值,但这为我们提供了一个理论上的速度上限参考。

通过这个例子,我们要记住的核心点是:比特率描述的是物理层面上 0 和 1 的翻转速度,且其单位换算是基于 10 进制的。

三、波特率:串口通信的"心跳"

3.1 波特率 vs 比特率

网络上有些人会混用这两个词,但在严谨的通信技术中,它们是有区别的。

  • 波特率 :单位是 Baud(波特),指每秒传输的符号(Symbol)码元的数量。它反映的是信号变化的频率。
  • 比特率:单位是 bps,指每秒传输的**二进制位(bit)**的数量。

3.1.1 "扔球游戏"通俗原理解析

为了搞清楚这两者的关系,我们可以想象张三和李四在玩扔球游戏。

假设他们约定用不同颜色的球来代表不同的信息状态:

  • 蓝色球 = 00
  • 绿色球 = 01
  • 黄色球 = 10
  • 红色球 = 11

在这个系统中,一个球就是一个"符号"(Symbol)。因为一共有 4 种颜色,区分这 4 种状态需要 2 个比特位( 2 2 = 4 2^2=4 22=4)。

  • 如果张三每秒钟扔出 5 个球,那么波特率就是 5 Baud。
  • 但是,因为每个球携带了 2 bit 的信息,所以比特率 就是 5 × 2 = 10 bps 5 \times 2 = 10 \text{ bps} 5×2=10 bps。

再举一个例子:

结论 :只有当每个符号只携带 1 bit 信息时(比如只有高电平和低电平两种状态),波特率在数值上才等于比特率。而在我们常见的标准 UART/USART 串口通信中,通常就是一个电平变化代表一个 bit,所以在这种特定场景下,我们可以近似认为 波特率 ≈ \approx ≈ 比特率

注意:严格来说,"波特率"这个词中的"率"字其实是多余的,因为 Baud 本身就是速率单位。就像我们说"m/s"是速度,不会说"m/s率"一样。但由于历史习惯,已经习惯了叫"波特率",我们在技术交流中继续沿用即可。另外,千万不要把波特率简称为 BPS (Baud Per Second),这在学术上是不严谨的。

3.2 波特率在波形上的体现

回到我们的 MCU 串口通信。当我们设置波特率为 10 时,这意味着什么?

这意味着在 1 秒钟的时间内,信号线上会发生 10 次状态变化(或者说传输了 10 个码元)。

  • 时间周期计算 : 1 s ÷ 10 = 0.1 s = 100 ms 1\text{s} \div 10 = 0.1\text{s} = 100\text{ms} 1s÷10=0.1s=100ms。
  • 波形表现:每一个高低电平的持续时间就是 100ms。发送方发出一个高电平,必须稳稳地保持 100ms,然后才能翻转为低电平,再保持 100ms。

如果波特率提高到 115200,那么每个比特位的持续时间就缩短到了约 8.68 微秒( μ s \mu s μs)。这就对硬件的响应速度和抗干扰能力提出了更高的要求。

四、如何确立通信握手

4.1 历史遗留的标准数值

在 STM32 等 MCU 的 USART 外设配置中,你会发现波特率的可选值并不是随意的整数(如 1000、2000),而是诸如 9600115200 这样看起来有些奇怪的数字。

这完全是历史原因导致的。早期的通信设备和电传打字机受限于机械结构和时钟分频的限制,形成了一套约定俗成的标准序列。虽然现在的电子技术完全可以支持任意速率,但为了保证兼容性,这些经典数值被保留了下来。

  • 低速场景 :通常使用 9600 Baud。适用于距离较远、干扰较大或对实时性要求不高的传感器通信。
  • 高速场景 :通常使用 115200 Baud。适用于调试打印(printf)、高速数据采集等场景。

4.2 解决通信失败的关键:约定一致

现在我们可以回答最开始提出的问题了:如何解决的通信不同步问题?

答案非常简单:双方必须约定完全一致的波特率。

MCU 内部的 USART 外设是由你写代码控制的,外部设备的参数也是由你选型决定的。你有绝对的权力去统一双方的标准。

  • 正确做法 :将 MCU 的 USART 波特率配置为 115200,同时将串口设备(如 GPS 模块、蓝牙模块或电脑端的串口助手)也设置为 115200。此时,双方对于"1秒钟传多少个 0 和 1"有了共同的认知,通信就能正常进行。
  • 错误做法 :MCU 设为 115200,而接收端设为 9600。这就好比一个人语速极快,另一个人语速极慢,接收端会把发送端的多个比特误读为一个,或者漏掉大量数据,最终导致通信彻底失败。

五、帧格式约定

在解决了通信速度的同步问题后,我们紧接着要面对第二个核心挑战:如何确保发送的数据是完整的?换句话说,接收方怎么知道数据什么时候开始、有多少位、以及什么时候发送完毕?这就引出了我们接下来要深入探讨的"帧格式"。

5.1 为什么必须约定"帧格式"?

在异步串行通信(如 USART)中,由于没有像 SPI 或 I2C 那样的独立时钟线(Clock Line)来同步双方的节奏,我们必须依赖一种人为约定的规则。这种规则在单片机领域通常被称为数据帧格式 ,其本质就是一种协议

这个约定必须在设计硬件单元之前就已经确定下来。未来的硬件工程师在设计 USART 硬件电路时,必须严格遵照这个标准。只有当发送方和接收方都遵循同一套"语言规则"时,接收方才能正确解析出发送方发出的每一帧数据。

简单来说,波特率解决了"速度一致"的问题,而帧格式则解决了"内容解析"的问题。波特率决定了单位时间内能发送多少个数据帧,而帧格式决定了每个数据帧内部长什么样。

5.2 标准 USART 数据帧的解剖

一个标准的 USART 数据帧通常由以下几个部分组成,我们可以把它想象成寄信时的信封规范:

  1. 空闲状态 (Idle State)

    • 电平状态:高电平(逻辑 '1')。
    • 作用 :当没有数据传输时,通信线路默认保持高电平。这就像电话线没人说话时是静音的一样,是一个基准状态。
  2. 起始位 (Start Bit)

    • 电平状态:低电平(逻辑 '0')。
    • 持续时间:1 个位周期。
    • 核心作用 :这是通信的"发令枪"。发送方将线路从高电平拉低,通知接收端"我要开始传数据了"。接收端检测到这个下降沿后,就会启动内部的定时器,按照约定的波特率开始采样后续的信号。这也帮助接收端完成了时钟的初步同步。
  3. 数据位 (Data Bits)

    • 内容:实际传输的有效数据。
    • 长度 :通常为 5 到 9 位,最常见的是 8 位(即一个字节)。
    • 传输顺序LSB First(最低有效位优先) 。这意味着在二进制数中,最右边的那一位会最先被发送到线路上。例如要发送二进制 1011,线上的顺序会是 1 -> 1 -> 0 -> 1

5.2.1 传输顺序详解:LSB First 与 MSB First

上面数据位的相关细节再继续作补充:这 8 位(或 9 位)数据,到底是先发"头"还是先发"尾"?这就涉及到了 LSBMSB 的概念。

什么是 LSB?

LSBLeast Significant Bit 的缩写,意为最低有效位

  • 定义 :在一个二进制数中,LSB 是位于最右边 的那个位,它具有最小的位权(即 2 0 2^0 20)。
  • 示例解析
    以二进制数 1011 为例,其数值计算方式为:
    1 × 2 3 + 0 × 2 2 + 1 × 2 1 + 1 × 2 0 1 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 1 \times 2^0 1×23+0×22+1×21+1×20
    可以看到,最右边的那个 1 就是 LSB。
  • 发送顺序 :如果要发送 1011,按照 LSB 优先的原则,物理线路上的发送顺序应该是 1 -> 1 -> 0 -> 1 。也就是先发送低有效位,再发送高有效位
什么是 MSB?

MSBMost Significant Bit 的缩写,意为最高有效位

  • 定义 :在一个二进制数中,MSB 是位于最左边的那个位,它具有最大的位权。
  • 示例解析
    同样以二进制数 1011 为例,最左边的那个 1 就是 MSB。
  • 发送顺序 :如果要发送 1011,按照 MSB 优先的原则,物理线路上的发送顺序应该是 1 -> 0 -> 1 -> 1 。也就是先发送高有效位,再发送低有效位
在 USART 中的实际应用

在绝大多数异步串行通信标准(如 USARTRS-232 )中,数据通常默认采用 LSB First(低位先行) 的方式进行传输。

  • 为什么要 LSB First?
    这主要是为了让接收设备能够更快地开始处理数据。接收端不需要等待整个字节全部接收完毕就可以开始移位处理,这在早期的硬件设计中能提高效率。
  • 例外情况
    虽然 LSB First 是主流,但少数特定的通信协议或系统可能会配置为 MSB First 传输。不过,在标准的单片机 USART 开发中,我们遇到的绝大多数情况都是 LSB First。在编写代码或配置寄存器时,通常不需要刻意去改这个顺序,除非你有特殊的对接需求。。
  1. 校验位 (Parity Bit) ------ 可选

    • 位置:位于数据位之后,停止位之前。
    • 作用 :用于简单的错误检测。如果启用了校验,硬件会自动计算并添加这一位。
      • 奇校验 (Odd Parity) :确保数据位 + 校验位中"1"的总个数为奇数。例如数据 11110000(4个1),校验位需置 1,凑成5个1。
      • 偶校验 (Even Parity) :确保数据位 + 校验位中"1"的总个数为偶数。例如数据 11110000(4个1),校验位需置 0,保持4个1。
    • 注意:校验只能检测出奇数个比特翻转的错误,无法纠正错误,也无法检测出偶数个比特同时出错的情况。
  2. 停止位 (Stop Bit)

    • 电平状态:高电平(逻辑 '1')。
    • 持续时间:可配置为 1、1.5 或 2 个位周期。
    • 核心作用 :标志着一帧数据的结束。它将线路拉回高电平(空闲状态),给接收端一个缓冲时间,并为下一帧的起始位(下降沿)做准备。如果没有停止位,接收端可能无法区分两帧数据之间的界限。

5.3 传输过程的量化计算

理解了帧结构,我们就能算一笔账:到底一秒钟能传多少有效数据?

这里有一个关键概念:发送 N 个字节的数据,就会产生 N 个独立的帧。每一帧都必须包含完整的起始位、数据位和停止位。不能把起始位和停止位省略掉。

让我们通过两个经典波特率来计算一下实际传输速率(假设配置为:1位起始位 + 8位数据位 + 无校验 + 1位停止位 = 10位/帧):

  • 场景一:波特率 9600 bps

    • 每秒传输的总位数:9600 bits
    • 每帧占用位数:10 bits
    • 理论每秒传输字节数 : 9600 ÷ 10 = 960 9600 \div 10 = 960 9600÷10=960 字节/秒。
  • 场景二:波特率 115200 bps

    • 每秒传输的总位数:115200 bits
    • 每帧占用位数:10 bits
    • 理论每秒传输字节数 : 115200 ÷ 10 = 11520 115200 \div 10 = 11520 115200÷10=11520 字节/秒。

通过这个计算我们可以直观地看到,波特率越高,单位时间内传送的数据量(吞吐量)就越大。但也要注意,起始位和停止位占据了 20% 的带宽(2/10),这就是异步通信为了"握手"所付出的额外开销。


结语

相关推荐
白搞电子1 小时前
一颗LED灯+8位单片机+滚珠开关:做一个“一碰就亮”的发光盒
单片机·嵌入式硬件
嵌入式小宁1 小时前
C11 原子操作 `atomic_int` 通俗指南
linux·c语言·嵌入式硬件
深圳市恒锐丰科技杨生1 小时前
SA8346 4‑36V 单通道 H 桥电机驱动芯片|中高压直流有刷电机方案
嵌入式硬件·硬件工程
深圳市恒锐丰科技杨生1 小时前
SA8344 6.5‑25V 单通道 H 桥电机驱动芯片|消费类直流有刷电机方案
嵌入式硬件·硬件工程
那年窗外下的雪.2 小时前
STM32嵌入式学习 03:TIM2 定时器更新中断
stm32·单片机·学习
youshi66682 小时前
stm32-FLASH
stm32·单片机·嵌入式硬件
星游路11 小时前
14单片机:LCD12864
单片机·嵌入式硬件
兴通物联科技11 小时前
SMT PCB 微小 DataMatrix 码扫不动问题分析 兴通 XT8601B 600 万像素工业读码器落地实践
大数据·人工智能·单片机·嵌入式硬件·算法·计算机视觉
国科安芯14 小时前
轨道供电韧性:ASP4644四通道降压架构在低轨卫星平台电源管理中的适用性分析
运维·网络·数据库·嵌入式硬件·架构·状态模式·低轨卫星星座