4. UART硬件原理:串口电平标准、波特率与帧格式、流控机制
各位同学,今天我们来聊聊UART的硬件基础。说实话,很多做嵌入式开发的朋友,写驱动时最头疼的就是硬件细节没搞透。我见过太多人拿着TTL电平的模块直接怼到RS232接口上,结果冒烟了还一脸懵。咱们今天就把这些坑填上。
4.1 串口电平标准:TTL vs RS232
UART通信,说白了就是两根线——TX和RX,互相发高低电平。但问题来了:这个「高」和「低」到底是多少伏?
TTL电平(3.3V/5V系统):
- 逻辑1:2.0V ~ 5.5V(3.3V系统下就是3.3V)
- 逻辑0:0V ~ 0.8V
- 特点:电压低,功耗小,适合板内通信
RS232电平(串口标准):
- 逻辑1:-3V ~ -15V(负电压!)
- 逻辑0:+3V ~ +15V(正电压)
- 特点:电压摆幅大,抗干扰强,能传十几米
核心区别:TTL是正逻辑(高=1,低=0),RS232是负逻辑(高=负电压,低=正电压)。两者不能直连,必须用电平转换芯片,比如MAX3232。
我个人习惯在PX4飞控板上,所有UART接口默认都是3.3V TTL电平。如果你要接RS232设备,比如某些老式GPS模块,记得加电平转换。我曾经有一次调试,忘了加转换芯片,结果飞控的UART口直接烧了——嗯,从那以后我每次画板子都会再三确认电平匹配。
4.2 波特率:通信的节拍
波特率,就是每秒传输的符号数。对于UART来说,一个符号就是一个bit。所以9600波特率,就是每秒传9600个bit。
常见的波特率有:
| 波特率 | 每bit时长 | 典型应用 |
|---|---|---|
| 9600 | 104.17 μs | GPS模块、旧设备 |
| 115200 | 8.68 μs | PX4默认控制台 |
| 921600 | 1.09 μs | 高速数传、日志下载 |
你想想看,为什么要有这么多波特率?说白了就是速度和稳定性的权衡。波特率越高,每bit时间越短,对时钟精度要求就越高。我在PX4上调试时,遇到过GPS模块在115200下工作正常,但换到921600就丢包——后来发现是晶振偏差太大,导致采样点偏移了。
避坑指南:我曾经在STM32上配置UART波特率,直接用公式算出来是115200,但实际示波器一看差了2%。原因是系统时钟不是整数倍分频。建议用逻辑分析仪实测一下,别太相信计算值。
4.3 帧格式:起始位、数据位、校验位、停止位
UART的帧结构,说白了就是一次传输一个字节的「包装」方式。标准格式如下:
起始位(1bit) + 数据位(5~9bit) + 校验位(0/1bit) + 停止位(1/1.5/2bit)
举个例子,最常用的8N1格式:
- 1位起始位(低电平)
- 8位数据位(LSB先发)
- 无校验位
- 1位停止位(高电平)
为什么要有起始位和停止位?因为UART是异步通信,没有时钟线。接收端靠检测起始位的下降沿来同步时钟。停止位则是给接收端一个缓冲时间,处理完当前字节再收下一个。
校验位这块,我建议新手直接用无校验(N)。奇偶校验(Even/Odd)在噪声环境下有点用,但现代通信都有CRC校验,UART的奇偶校验其实意义不大。我在PX4的MAVLink协议里,从来不用UART硬件校验,因为协议层已经有更可靠的校验了。
注意:数据位可以是5、6、7、8、9位。但PX4驱动里几乎只用8位。如果你遇到7位数据位的设备,多半是老古董了。我曾经调试一个工业传感器,它用7E1格式(7数据位+偶校验+1停止位),折腾了半天才发现是帧格式不匹配。
4.4 流控机制:硬件流控 vs 软件流控
流控,说白了就是「你慢点发,我快吃不消了」。UART通信时,如果发送端一直发,接收端来不及处理,数据就会丢失。这时候就需要流控。
硬件流控(RTS/CTS):
- RTS(Request To Send):发送请求
- CTS(Clear To Send):允许发送
- 需要额外两根线,共4线(TX、RX、RTS、CTS)
软件流控(XON/XOFF):
- 接收端发0x13(XOFF)让发送端暂停
- 接收端发0x11(XON)让发送端继续
- 不需要额外线,但会占用数据通道
我个人在PX4开发中,几乎只用硬件流控。为什么?因为软件流控有个致命问题:如果数据流里恰好出现了0x13或0x11,就会误触发流控。我在调试一个数传模块时,就因为这个原因,数据老是莫名其妙中断——查了两天才发现是二进制数据里包含了XOFF字符。
我的建议:在PX4飞控上,如果通信速率超过115200,或者数据量较大(比如日志下载),一定要用硬件流控。否则丢包率会让你怀疑人生。
4.5 知识体系总览
下面这张图,我把本章的核心逻辑串起来了:
这张图把UART的四个核心要素串起来了。你写驱动时,脑子里要有这个结构:先确认电平标准,再配波特率,然后设帧格式,最后决定要不要流控。少一步,通信就可能出问题。
好了,这一章的内容就到这里。记住,UART看似简单,但硬件细节决定成败。下次写驱动前,先拿示波器看看波形,比什么都管用。