一、UART 基础与协议概述

各位同学,咱们这门课叫《UART通信协议封装与RS485组网调试助手实战》。第一节课,得先把地基打牢。UART 这东西,说白了就是串口通信的祖宗。你想想看,从当年的鼠标、Modem,到现在的单片机调试、传感器读取,到处都有它的影子。我刚开始做嵌入式那会儿,第一个调通的通信协议就是 UART,当时看着示波器上跳动的波形,那种感觉,嗯,至今还记得。

1.1 UART 的历史与地位

UART,全称 Universal Asynchronous Receiver/Transmitter,通用异步收发器。这玩意儿诞生于上世纪 60 年代,最初是作为计算机与电传打字机之间的桥梁。后来随着 PC 的普及,它成了标准配置,就是主板上那个 9 针的 DB9 串口。

虽然现在 USB 几乎取代了它在家用电脑上的位置,但在工业、嵌入式领域,UART 依然是王者。为什么?因为它简单、可靠、成本极低。一个单片机,两根线(TX、RX),就能和传感器、GPS 模块、蓝牙模块通信。我在项目中遇到过最极端的情况,一个 8 脚的小芯片,靠 UART 和主控通信,愣是跑了好几年没出过问题。

核心地位: UART 是嵌入式系统中最基础、最通用的“对话”方式。几乎所有 MCU 都内置了 UART 外设,它是你学习其他复杂协议(如 SPI、I2C、CAN)的基石。

1.2 异步串行通信原理

UART 是异步的,也是串行的。咱们拆开来看。

串行: 数据像一列火车,在一条线上一个比特一个比特地顺序发送。并行通信是一次发 8 位或 16 位,速度快但线多、成本高、抗干扰差。串行正好相反,线少、距离远、成本低。

异步: 收发双方没有独立的时钟线。那怎么同步?靠的是双方约定好的“波特率”和帧格式。发送方按这个节奏发,接收方按这个节奏收。就像两个人约好 10 点见面,各自看自己的表,只要表都准,就能碰上。

我画了一张图,帮你理解这个“串行”和“异步”的概念。

UART 异步串行通信示意图 发送端 (TX) 接收端 (RX) 数据线 (TX → RX) 无独立时钟线 (异步) 数据帧结构 (串行发送) 起始位 数据位 (5~8 bit) 校验位 停止位

1.3 帧格式详解:起始位 / 数据位 / 校验位 / 停止位

UART 的一帧数据,就像一封信。有开头、有正文、有校验、有结尾。咱们一个一个说。

字段 长度 作用 我的一点经验
起始位 1 bit 通知接收方“数据要来了”。将总线从空闲的高电平拉低。 这是同步的起点,绝对不能丢。我曾经因为线太长,起始位被干扰,整包数据全废了。
数据位 5~8 bit 真正的数据内容。通常为 8 位(一个字节)。 我习惯用 8 位,兼容性最好。5 位和 6 位基本只在老古董设备上见到。
校验位 0 或 1 bit 简单的错误检测。可选:无校验(N)、奇校验(O)、偶校验(E)。 短距离通信我一般不用校验,省一个 bit。长线或干扰大的环境,必须加。
停止位 1, 1.5 或 2 bit 表示帧结束。总线恢复为高电平。 1 位停止位最常用。2 位停止位用于慢速设备,给它们多点时间处理。
小提示: 最常见的配置是 8N1,即 8 位数据位、无校验、1 位停止位。你遇到的大部分设备,默认都是这个配置。

1.4 波特率概念

波特率,就是每秒传输的符号数。在 UART 里,一个符号就是一个 bit。所以波特率 = 比特率。

常见的波特率有:9600、19200、38400、115200。115200 意味着每秒传输 115200 个 bit。算一下,如果帧格式是 8N1,一帧总共 10 bit(1 起始 + 8 数据 + 1 停止),那么每秒能传 11520 个字节。

收发双方的波特率必须一致,误差不能太大。一般要求误差在 ±2% 以内。为什么?

我举个例子。假设发送方以 9600 波特率发数据,每个 bit 持续约 104.17 微秒。如果接收方误以为波特率是 9800,每个 bit 只采 102.04 微秒。发 10 个 bit 后,累积误差就超过一个 bit 了,接收方采到的数据全是错的。

避坑指南: 我曾经在一个项目里,用了内部 RC 振荡器的单片机做 UART 通信。RC 振荡器精度只有 ±5%,波特率误差直接超标。结果 10 包数据里能错 3 包。后来换了外部晶振,问题才解决。所以,波特率精度是 UART 通信的命门,尤其是高速率(如 115200 以上)时,必须用高精度时钟源。

下面这个表格,帮你快速选择波特率。

波特率 (bps) 每 bit 时长 (μs) 适用场景 推荐时钟精度
9600 104.17 长距离、抗干扰要求高 ±2%
38400 26.04 通用传感器、模块 ±1%
115200 8.68 调试、高速数据传输 ±0.5%
921600 1.09 片内或极短距离 ±0.1% (建议外部晶振)

1.5 总结一下

这一章,咱们把 UART 的根儿刨清楚了。

  • UART 是异步串行通信,没有时钟线,靠约定好的波特率同步。
  • 一帧数据 = 起始位 + 数据位 + 校验位 + 停止位。
  • 波特率是通信的节拍,误差必须控制住。