3. UART 数据帧格式详解:起始位、数据位、奇偶校验位、停止位

UART 通信,说白了就是两个人约定好一套“说话”的规矩。谁先开口,说几个字,要不要带个校验,说完怎么收尾——这些都得提前定死。我刚开始搞嵌入式那会儿,总觉得这玩意儿简单,结果被一个校验位坑了一整天。嗯,咱们今天就把这个帧格式彻底掰开揉碎。

核心要点:一个完整的 UART 数据帧 = 起始位 + 数据位 + 奇偶校验位(可选) + 停止位。缺一个,通信就乱套。

3.1 起始位:通信的“发令枪”

起始位就干一件事:告诉接收方“我要开始传数据了”。

  • 电平状态:空闲时总线是高电平,起始位拉低一个位时间。
  • 为什么是低电平?因为空闲是高,突然变低就是一个明显的跳变。接收方检测到这个下降沿,就知道要开始采样了。
  • 长度:固定为 1 位,不能配成别的。

我记得有一次调试一块老旧的工业控制板,示波器一看,起始位居然有毛刺。接收方误触发了好几次,数据全错。后来加了个简单的去抖滤波,问题就解决了。所以,起始位的信号质量,直接影响整个通信的稳定性。

3.2 数据位:真正的“干货”

数据位就是你要传的实际信息。UART 支持 5、6、7、8 位,最常见的是 8 位。

数据位长度 典型应用场景 备注
5 位 老式电传打字机、某些工业协议 现在很少见了
6 位 某些特殊字符集 不常用
7 位 ASCII 码传输(0-127) 早期 Modbus 协议常用
8 位 绝大多数现代应用 一个字节,最通用

我个人习惯,只要不是跟古董设备对接,一律用 8 位数据位。为什么?因为一个字节刚好 8 位,跟内存、寄存器、协议栈都天然对齐。你用 7 位,还得自己拼凑,麻烦不说,还容易出错。

小技巧:如果你不确定对方用多少位数据位,先试试 8 位。如果通信失败,再查手册。大部分现代设备都默认 8 位。

3.3 奇偶校验位:数据的“指纹”

奇偶校验位是用来做简单错误检测的。它分好几种,别搞混了。

  • 无校验(None):不发送校验位。帧长度最短,效率最高。
  • 奇校验(Odd):数据位 + 校验位里“1”的个数为奇数。
  • 偶校验(Even):数据位 + 校验位里“1”的个数为偶数。
  • 标记校验(Mark):校验位固定为 1。说白了就是占个位置,不干活。
  • 空格校验(Space):校验位固定为 0。同上,占位用。

你想想看,标记和空格校验有什么用?其实它们不是用来检错的,而是为了凑帧长度。有些老协议要求帧必须是某个固定长度,就用这两种方式填充。我曾在项目中遇到过,一个德国产的传感器,手册上写的是“Mark parity”,我当时没注意,配成了偶校验,结果死活读不到数据。后来用逻辑分析仪抓了一下,才发现校验位一直是高电平。嗯,从那以后,我养成了先看波形再配参数的习惯。

避坑指南:我曾经在一条总线上混接了奇校验和偶校验的设备,结果两边都认为自己是对的,数据全乱套。记住:通信双方必须使用完全相同的校验方式,否则就是鸡同鸭讲。

3.4 停止位:通信的“句号”

停止位表示这一帧结束了。它把总线拉回高电平,保持至少一个位时间。

停止位长度 使用场景 说明
1 位 标准配置,绝大多数情况 效率最高
1.5 位 某些老式设备、特殊协议 很少见,我做了十年只碰到过两次
2 位 低速通信、抗干扰要求高的场景 给接收方更多时间处理

为什么会有 1.5 位?说白了就是历史遗留问题。早期有些 UART 芯片的时钟精度不够,多给半个位的时间让接收方稳定采样。现在芯片精度高了,1.5 位基本绝迹。我个人习惯,能用 1 位就不用 2 位,除非通信距离特别长或者干扰特别大。

3.5 完整帧结构图

下面这张图,把整个帧结构串起来。你一看就明白。

UART 完整数据帧结构 空闲 起始 数据位(5-8 位) 校验 停止 空闲 关键说明: 1. 空闲时总线为高电平,起始位拉低产生下降沿,触发接收。 2. 数据位 LSB 先发(最低有效位在前),顺序不能搞反。 3. 校验位可选,奇/偶校验检错,标记/空格校验仅占位。 4. 停止位拉回高电平,至少保持 1 位时间,给接收方准备接收下一帧。

3.6 常见配置组合与调试要点

实际项目中,最常用的配置组合就几种。我列个表,你直接照着配就行。

应用场景 数据位 校验位 停止位 备注
标准调试串口 8 无 1 最常用,效率最高
Modbus RTU 8 偶校验 1 工业现场标准
老式 ASCII 终端 7 偶校验 1 历史遗留
强干扰环境 8 奇校验 2 牺牲效率换稳定

调试建议:如果你用示波器或逻辑分析仪抓波形,先看起始位的下降沿是否干净,再看停止位是否回到高电平。这两点没问题,帧结构基本就对了。剩下的就是波特率对不对。

好了,UART 数据帧格式就这些。起始位、数据位、校验位、停止位,四个部分各司其职。你只要记住:收发双方必须完全一致,一个参数配错,通信就罢工。我当年被校验位坑过,希望你不用再踩这个坑。