串口通信基础: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)
  • 起始位: 固定为低电平,告诉接收端"我要开始发数据了"
  • 数据位: 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或远距离通信,硬件流控能有效防止缓冲区溢出。

知识结构总览

下面这张图把串口通信的核心要素串起来了,你可以对照着理解整个通信链路。

串口通信知识结构图 UART串口通信 电平标准 TTL RS232 RS485 帧格式 起始位 数据位 校验位 停止位 波特率与流控 波特率 流控 硬件/软件流控 调试要点 电平匹配 → 帧格式一致 → 波特率对齐 → 流控按需启用
调试串口配置速查(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脚的波形,确认电平幅值和波特率对不对。你想想看,如果硬件上电平就不对,软件配得再花哨也是白搭。

好了,串口通信的基础就这些。记住三个核心点:电平要匹配、帧格式要对齐、波特率要一致。把这三点吃透了,串口调试就成功了一大半。