串口通信基础:RS232/RS485/TTL电平标准、协议帧格式与波特率流控
做嵌入式Linux开发,调试串口可以说是我们和硬件打交道的第一扇门。我刚开始接触这块时,总觉得串口通信就是两根线一接、数据就跑了,结果第一次调板子就栽了跟头——电平不匹配,烧了接口芯片。嗯,从那以后我再也不敢小看这些基础概念了。
电平标准:RS232、RS485与TTL
说白了,串口通信的本质就是通过电压高低来传递0和1。但不同标准对"高"和"低"的定义完全不同,混用就会出问题。
| 标准 | 逻辑1(高电平) | 逻辑0(低电平) | 典型电压范围 | 通信距离 |
|---|---|---|---|---|
| TTL | 2.0V ~ 5.0V | 0V ~ 0.8V | 0 ~ 5V / 0 ~ 3.3V | <1米 |
| RS232 | -3V ~ -15V | +3V ~ +15V | ±12V 典型 | <15米 |
| RS485 | A-B > +200mV | A-B < -200mV | 差分 ±6V | <1200米 |
⚠️ 常见坑点: 我曾经在项目里直接用TTL电平的调试线去连RS232接口的工控机,结果串口芯片冒烟了。记住:TTL和RS232之间必须加电平转换芯片(如MAX232),不能直连。
RS485用的是差分信号,抗干扰能力强,适合工业现场长距离通信。我调试过的一个光伏逆变器项目,现场走线超过500米,用的就是RS485,配合双绞线,数据一点没丢。
串口协议帧格式
串口通信的帧结构其实很简单,但每个位都有讲究。你想想看,收发双方没有独立的时钟线,全靠约定好的时序来同步,所以帧格式必须严格对齐。
标准UART帧结构(8N1为例):
起始位(1bit) + 数据位(8bit) + 校验位(0/1bit) + 停止位(1/1.5/2bit)
起始位(1bit) + 数据位(8bit) + 校验位(0/1bit) + 停止位(1/1.5/2bit)
- 起始位: 固定为低电平,告诉接收端"我要开始发数据了"
- 数据位: 5~9位可选,常用8位。LSB先发(最低有效位在前)
- 校验位: 可选无校验、奇校验、偶校验。我个人习惯在调试阶段用无校验,减少干扰因素
- 停止位: 固定为高电平,给接收端时间处理收到的字节
我记得有一次调试GPS模块,数据总是偶尔错位。抓波形一看,原来是模块配置的是7位数据位+偶校验,而我这边默认配成了8N1。帧格式不匹配,数据自然对不上。
波特率与流控
波特率就是每秒传输的符号数,单位是bps。常用的有9600、115200、921600等。收发双方的波特率必须一致,误差一般不能超过±2%。
| 波特率 | 位时间 | 1字节传输时间(8N1) | 适用场景 |
|---|---|---|---|
| 9600 | 104.2μs | 约1.04ms | 长距离、低速设备 |
| 115200 | 8.68μs | 约86.8μs | 调试串口、短距离通信 |
| 921600 | 1.09μs | 约10.9μs | 高速数据采集、Bootloader下载 |
💡 经验之谈: 嵌入式Linux的调试串口,我建议用115200。9600太慢,刷内核log时等得着急;921600虽然快,但线缆稍长就容易丢数据。115200是个平衡点。
流控分为硬件流控(RTS/CTS)和软件流控(XON/XOFF)。说实话,调试串口我基本不用流控——多两根线就多两个故障点。但如果是接Modem或远距离通信,硬件流控能有效防止缓冲区溢出。
知识结构总览
下面这张图把串口通信的核心要素串起来了,你可以对照着理解整个通信链路。
调试串口配置速查(Linux下常用):
# 查看当前串口参数
stty -F /dev/ttyS0 -a
# 设置115200 8N1 无流控
stty -F /dev/ttyS0 115200 cs8 -cstopb -parenb -crtscts
# 用minicom连接调试串口
minicom -D /dev/ttyS0 -b 115200
我个人习惯在调试新板子时,先用示波器抓一下TX脚的波形,确认电平幅值和波特率对不对。你想想看,如果硬件上电平就不对,软件配得再花哨也是白搭。
好了,串口通信的基础就这些。记住三个核心点:电平要匹配、帧格式要对齐、波特率要一致。把这三点吃透了,串口调试就成功了一大半。