一、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 和主控通信,愣是跑了好几年没出过问题。
1.2 异步串行通信原理
UART 是异步的,也是串行的。咱们拆开来看。
串行: 数据像一列火车,在一条线上一个比特一个比特地顺序发送。并行通信是一次发 8 位或 16 位,速度快但线多、成本高、抗干扰差。串行正好相反,线少、距离远、成本低。
异步: 收发双方没有独立的时钟线。那怎么同步?靠的是双方约定好的“波特率”和帧格式。发送方按这个节奏发,接收方按这个节奏收。就像两个人约好 10 点见面,各自看自己的表,只要表都准,就能碰上。
我画了一张图,帮你理解这个“串行”和“异步”的概念。
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 位停止位用于慢速设备,给它们多点时间处理。 |
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 了,接收方采到的数据全是错的。
下面这个表格,帮你快速选择波特率。
| 波特率 (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 是异步串行通信,没有时钟线,靠约定好的波特率同步。
- 一帧数据 = 起始位 + 数据位 + 校验位 + 停止位。
- 波特率是通信的节拍,误差必须控制住。