第二讲:串口通信协议——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,嗯,稳如老狗。
二、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。很多新手在这里搞反,结果数据全错。
三、波特率计算:别让时钟误差毁了你的通信
波特率,说白了就是每秒传输多少位。比如9600bps,就是每秒传9600个bit。
但问题来了:UART是异步通信,没有时钟线。接收端怎么知道什么时候采样?
答案是:接收端用自己的时钟,在每位数据的中间采样。这就要求双方的时钟频率误差足够小,否则采样点会偏移,导致误码。
波特率计算公式很简单:
波特率 = 系统时钟频率 / (16 × 分频系数)
以STM32为例,系统时钟72MHz,如果分频系数设为468.75,那么:
波特率 = 72,000,000 / (16 × 468.75) = 9600
但分频系数必须是整数,所以实际波特率会有误差。误差超过2%,通信就可能不稳定。
我给大家列个常用波特率表:
| 波特率(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,接收方就以为要暂停,结果通信卡死。
五、知识体系总览
这一讲的内容比较多,我画了一张图帮大家理清思路:
嗯,这一讲的内容就到这里。串口通信看似基础,但真正用好、用对,需要你对物理层、帧格式、波特率和流控制都有深入理解。下次调试地面站遇到串口问题,不妨从这四个方面逐一排查,大概率能找到症结所在。
公众号:蓝海资料掘金营,微信deep3321