第二讲:串口通信协议——RS232/RS485物理层特性、UART帧格式、波特率计算、流控制机制

各位工程师朋友,大家好。今天我们聊聊串口通信协议。

串口这东西,说简单也简单,说复杂也复杂。我做了十几年地面站开发,调试过上百种飞控和数传模块,可以说串口是我打交道最多的接口,没有之一。你想想看,从最早的APM到现在的Pixhawk,从大疆的CAN协议到各种自定义的MAVLink扩展,底层几乎都离不开串口。

这一讲,我们重点拆解四个核心知识点:RS232/RS485的物理层差异、UART帧格式、波特率计算、以及流控制机制。嗯,都是干货,咱们一个一个来。

一、RS232 vs RS485:物理层的那些事儿

先问大家一个问题:为什么地面站和飞控之间,有的用RS232,有的用RS485?

其实说白了,就是传输距离和抗干扰能力的取舍。

1. RS232:简单但娇气

RS232是单端信号,用-15V~-3V表示逻辑1,+3V~+15V表示逻辑0。电压摆幅大,好处是抗噪声能力还行,坏处是——距离一长就完蛋。

我个人习惯,RS232在3米以内用着最踏实。超过5米,波形就开始变形了。我在项目中遇到过一件事:有个客户非要把地面站放在距离飞控15米远的控制室里,用RS232直连,结果数据全是乱码。后来换成RS485,问题立刻解决。

关键参数对比:
  • RS232:单端传输,最大距离约15米,速率最高115200bps(实际20kbps以上就不太稳了)
  • RS485:差分传输,最大距离1200米,速率最高10Mbps(距离越短速率越高)

2. RS485:差分信号才是王道

RS485用两根线(A和B)传输差分信号。A比B高200mV以上表示逻辑1,反之表示逻辑0。这种差分结构天生抗共模干扰,所以才能传那么远。

你想想看,无人机地面站经常在野外作业,电机、电调、GPS、数传模块全挤在一起,电磁环境那叫一个恶劣。RS232在这种环境下,分分钟被干扰得怀疑人生。而RS485,嗯,稳如老狗。

我的经验: 地面站和飞控之间,如果距离超过5米,或者现场有强电磁干扰,优先选RS485。如果只是调试台上几根杜邦线连着,RS232完全够用。

二、UART帧格式:一个字节的旅行

UART(通用异步收发器)是串口通信的核心。它怎么把一个字节发出去的?我们拆开看看。

一个完整的UART帧包含以下部分:

  • 起始位(1位):拉低电平,告诉接收端“我要开始发了”
  • 数据位(5~9位):实际传输的数据,通常是8位
  • 校验位(0或1位):可选奇校验或偶校验
  • 停止位(1、1.5或2位):拉高电平,表示帧结束

举个例子,最常见的配置是8N1:8位数据、无校验、1位停止位。加上1位起始位,总共10位传输一个字节。

帧格式示意图:
起始位 | 数据位(LSB→MSB) | 校验位(可选) | 停止位
  0    | 1 0 1 0 1 0 1 0 |     无       |   1

这里有个坑,我提醒一下:数据位是LSB先发。也就是说,如果你要发0x55(二进制01010101),先发的是最低位1,再发0,再发1……最后发最高位0。很多新手在这里搞反,结果数据全错。

注意: 地面站和飞控的串口配置必须完全一致。我曾经遇到过,飞控用8N1,地面站用8E1(偶校验),结果通信时好时坏,查了整整一天才发现是校验位不匹配。

三、波特率计算:别让时钟误差毁了你的通信

波特率,说白了就是每秒传输多少位。比如9600bps,就是每秒传9600个bit。

但问题来了:UART是异步通信,没有时钟线。接收端怎么知道什么时候采样?

答案是:接收端用自己的时钟,在每位数据的中间采样。这就要求双方的时钟频率误差足够小,否则采样点会偏移,导致误码。

波特率计算公式很简单:

波特率 = 系统时钟频率 / (16 × 分频系数)

以STM32为例,系统时钟72MHz,如果分频系数设为468.75,那么:

波特率 = 72,000,000 / (16 × 468.75) = 9600

但分频系数必须是整数,所以实际波特率会有误差。误差超过2%,通信就可能不稳定。

我的建议: 地面站常用的波特率是57600和115200。这两个值在大多数MCU上都能精确分频。9600虽然稳定,但传输速度太慢,传一张高分辨率航拍图得等半天。

我给大家列个常用波特率表:

波特率(bps) 每字节传输时间(8N1) 适用场景
9600 约1.04ms 长距离、低速率传感器
19200 约0.52ms GPS模块、数传电台
57600 约0.17ms 飞控与地面站通信(推荐)
115200 约0.087ms 高速数传、日志下载
921600 约0.011ms 短距离高速调试

四、流控制机制:别让数据撑爆缓冲区

流控制,说白了就是让发送方知道接收方能不能处理得过来。地面站和飞控之间,数据量一大,这个问题就凸显了。

流控制分两种:

1. 硬件流控制(RTS/CTS)

用两根额外的线:RTS(请求发送)和CTS(清除发送)。接收方缓冲区快满时,拉低CTS,发送方看到CTS为低,就暂停发送。

我在项目中遇到过:用115200波特率传日志文件,飞控的缓冲区只有256字节,地面站这边疯狂发,飞控那边疯狂丢包。后来加上硬件流控制,问题解决。

硬件流控制接线:
地面站 TX  → 飞控 RX
地面站 RX  → 飞控 TX
地面站 RTS → 飞控 CTS
地面站 CTS → 飞控 RTS
GND       → GND

2. 软件流控制(XON/XOFF)

不用额外线,靠发送特殊字符来控制。接收方发0x13(XOFF)让发送方暂停,发0x11(XON)让发送方继续。

但说实话,我不推荐在地面站场景用软件流控制。为什么?因为XON/XOFF字符可能和数据内容冲突。万一你的数据里正好有0x13,接收方就以为要暂停,结果通信卡死。

避坑指南: 我曾经在一个项目中,飞控的遥测数据里偶尔会出现0x13这个字节,结果地面站收到后自动暂停发送,导致链路中断。查了三天才发现是软件流控制惹的祸。从那以后,我所有地面站项目都只用硬件流控制,或者干脆不用流控制,靠协议层的应答机制来保证可靠传输。

五、知识体系总览

这一讲的内容比较多,我画了一张图帮大家理清思路:

串口通信协议知识体系 物理层特性 RS232:单端信号,±3V~±15V 距离≤15米,速率≤115200bps RS485:差分信号,A-B电压差 距离≤1200米,速率≤10Mbps 抗共模干扰,适合野外作业 UART帧格式 起始位(1位) + 数据位(5~9位) 校验位(0/1位) + 停止位(1/1.5/2位) 常见配置:8N1(8位+无校验+1停止) LSB先发,MSB后发 收发双方配置必须一致 波特率计算 公式:波特率 = 时钟 / (16 × 分频系数) 分频系数需为整数,误差≤2% 常用:9600/57600/115200 地面站推荐:57600或115200 高速调试可用921600 流控制机制 硬件流控制:RTS/CTS信号线 接收方拉低CTS暂停发送 软件流控制:XON(0x11)/XOFF(0x13) ⚠ 可能和数据内容冲突 地面站推荐:硬件流控制或协议层应答 核心原则:物理层选对、帧格式配准、波特率算准、流控制用对

嗯,这一讲的内容就到这里。串口通信看似基础,但真正用好、用对,需要你对物理层、帧格式、波特率和流控制都有深入理解。下次调试地面站遇到串口问题,不妨从这四个方面逐一排查,大概率能找到症结所在。


公众号:蓝海资料掘金营,微信deep3321