UART通信协议基础:RS232/RS485标准、波特率、数据位、停止位、奇偶校验
做嵌入式开发这些年,我调试过不少设备。从简单的温湿度传感器,到复杂的工业PLC,它们之间通信最常用的底层协议,就是UART。说白了,UART就是串口通信的物理层和协议层基础。你想想看,树莓派的GPIO引脚里,就藏着UART接口。搞懂它,你才能跟外面的工业设备“对上话”。
1.1 什么是UART?
UART的全称是Universal Asynchronous Receiver/Transmitter,通用异步收发器。它负责把数据“打包”成串行比特流,一根线发,一根线收。
我习惯把UART比作两个人打电话。一个人说(TX),一个人听(RX)。但有个关键点——它没有时钟线。所以收发双方必须提前约定好“语速”和“句子结构”。这个“语速”就是波特率,“句子结构”就是数据位、停止位和奇偶校验。
核心要点:UART是异步通信,没有时钟同步线。全靠双方提前约定参数,才能正确解析数据。
1.2 RS232与RS485标准
UART定义了数据怎么打包。但信号怎么在线上传输,那是RS232和RS485的事。这两个标准,我在项目里都踩过坑。
RS232:点对点,简单直接
RS232是最早的串口标准。它用-3V~-15V表示逻辑“1”,+3V~+15V表示逻辑“0”。电压范围大,抗干扰能力还行。但有个致命缺点——传输距离短,一般不超过15米。而且只能点对点通信,一台设备只能跟另一台设备连。
我记得刚入行时,调试一个老款条码扫描枪,用的就是RS232。线长超过10米,数据就开始丢包。后来换成RS485,问题才解决。
| 特性 | RS232 | RS485 |
|---|---|---|
| 传输方式 | 单端(不平衡) | 差分(平衡) |
| 最大距离 | 约15米 | 约1200米 |
| 节点数量 | 1对1 | 最多256个节点 |
| 信号电平 | ±3V~±15V | ±1.5V~±6V(差分) |
| 抗干扰能力 | 较弱 | 强(共模抑制) |
| 典型应用 | 调试口、短距设备 | 工业总线、远距传感器 |
RS485:差分信号,远距离抗干扰
RS485用两根线(A和B)传输差分信号。两根线上的电压差决定逻辑值。这种设计天然抑制共模干扰。所以RS485能传1200米,还能挂256个设备。
我曾经在一个工厂里部署温湿度采集网络。现场电机一启动,RS232就乱码。换成RS485后,数据稳如老狗。嗯,工业环境,首选RS485。
我的建议:树莓派原生UART是3.3V TTL电平。要接RS232设备,需要MAX3232电平转换芯片。要接RS485设备,需要MAX485或SP3485芯片。别直接怼,会烧引脚。
1.3 波特率:通信的“语速”
波特率就是每秒传输的符号数。单位是bps(bits per second)。常见的波特率有:9600、19200、38400、115200。
为什么是这些数字?因为它们都是16MHz晶振分频出来的整数倍。工业设备最常用的是9600和115200。9600慢但稳定,115200快但容易受干扰。
我调试一个老款PLC时,手册写的是“19200bps”。我设成19200,死活不通。后来用示波器一看,实际是19200的变种——19200.0。树莓派的时钟精度不够,差了一点点。最后换成9600,稳了。
避坑指南:收发双方的波特率误差必须小于±2%。树莓派的板载晶振精度一般,长时间运行或高温下可能漂移。我曾经遇到过设备运行4小时后突然乱码,就是波特率漂了。加个定时重同步机制能解决。
1.4 数据位、停止位、奇偶校验
这些参数决定了“句子结构”。我习惯把它们放在一起讲,因为它们是同一个数据帧里的三个字段。
数据位:一帧里装多少数据
常见的有7位和8位。8位能表示0~255,正好一个字节。7位只能表示0~127,适合ASCII字符传输。工业设备几乎都用8位。
停止位:帧结束的标志
停止位是1位、1.5位或2位的高电平。它告诉接收方“这帧结束了”。1位停止位最常见。如果线路干扰大,可以设成2位,牺牲一点速度换稳定性。
奇偶校验:简单的错误检测
奇偶校验分三种:无校验(N)、奇校验(O)、偶校验(E)。
- 无校验:不校验,速度快。工业设备默认选项。
- 奇校验:数据位+校验位里“1”的个数为奇数。
- 偶校验:数据位+校验位里“1”的个数为偶数。
奇偶校验只能检测奇数个比特错误。如果两个比特同时翻转,它查不出来。所以工业上更常用CRC校验。但奇偶校验简单,硬件直接支持,很多老设备还在用。
| 参数 | 常见值 | 说明 |
|---|---|---|
| 数据位 | 7, 8 | 8位最常用,7位用于ASCII |
| 停止位 | 1, 1.5, 2 | 1位默认,干扰大时用2位 |
| 奇偶校验 | N, O, E | N最常用,O/E用于老设备 |
1.5 完整的UART数据帧
把上面这些拼起来,就是一帧完整的UART数据:
起始位(1位) + 数据位(5~9位) + 奇偶校验位(0或1位) + 停止位(1~2位)
举个例子:8N1(8数据位、无校验、1停止位)
起始位(0) + 8位数据 + 停止位(1)
发送一个字节0x55(二进制01010101),波形是这样的:
空闲(1) → 起始(0) → 1 → 0 → 1 → 0 → 1 → 0 → 1 → 0 → 停止(1) → 空闲(1)
注意:数据位是LSB(最低有效位)先发。所以0x55的二进制01010101,先发最低位1,再发0,依次类推。
小技巧:用示波器看UART波形时,先找起始位(从高电平跳变到低电平)。然后数8个数据位,再找停止位(高电平)。这样能快速判断参数对不对。
1.6 知识结构总览
下面这张图,把UART通信协议的核心知识点串起来了。你可以把它当作本章的“地图”。
1.7 树莓派上的UART引脚
树莓派40针GPIO里,UART引脚是固定的:
- TX(发送):GPIO14(物理引脚8)
- RX(接收):GPIO15(物理引脚10)
- GND:任意GND引脚(物理引脚6、9、14等)
注意:树莓派3B+和4B的UART默认是蓝牙用的。要把它映射到GPIO14/15,需要配置config.txt。这个我们后面章节会细讲。
警告:树莓派的UART是3.3V TTL电平。绝对不能直接接RS232的±12V信号,会烧毁GPIO。必须用电平转换芯片。RS485也需要转换芯片。别问我怎么知道的——我烧过一块树莓派3B+。
1.8 本章小结
UART通信协议,说白了就是三件事:物理层标准(RS232/RS485)、通信参数(波特率/数据位/停止位/奇偶校验)、帧结构(起始位+数据+校验+停止)。