UART协议基础:帧格式、波特率与数据完整性
UART,说白了就是串口。我入行那会儿,调试板子第一件事就是先把串口打通。它简单、可靠,直到今天,几乎所有MCU和传感器都还留着它。这一章,咱们把UART的帧格式、波特率、起始位、数据位、校验位、停止位这些基础概念彻底讲透。
UART帧格式:一次传输的完整结构
UART是异步通信,没有时钟线。收发双方靠什么同步?靠约定的帧格式。一帧数据,就像一列火车,有车头、车厢、车尾。
| 字段 | 位数 | 作用 |
|---|---|---|
| 起始位 | 1位 | 拉低电平,告诉接收方“准备接收” |
| 数据位 | 5~9位(常用8位) | 实际传输的数据 |
| 校验位 | 0或1位 | 可选,用于检错 |
| 停止位 | 1、1.5或2位 | 拉高电平,表示帧结束 |
我习惯把UART帧画成下面这张图,一目了然:
起始位与停止位:帧同步的关键
起始位是UART通信的“发令枪”。发送方把TX线从高电平拉低,保持一个位时间。接收方检测到这个下降沿,就知道“数据要来了”。
停止位则是“刹车”。发送方把TX线拉高,保持1位、1.5位或2位时间。接收方看到停止位,就知道这一帧结束了。
数据位:真正要传的东西
数据位可以是5、6、7、8位,甚至9位。最常见的是8位,刚好一个字节。为什么?因为ASCII码是7位,加上校验位或扩展字符,8位最灵活。
发送顺序是LSB(最低有效位)先发,MSB(最高有效位)后发。这一点和I2C、SPI不一样,别搞混了。
校验位:简单的错误检测
校验位是可选的。有奇校验、偶校验、无校验三种模式。
| 校验模式 | 规则 | 示例(数据 0x55 = 01010101) |
|---|---|---|
| 无校验(N) | 不发送校验位 | 帧长度 = 1 + 8 + 1 = 10位 |
| 奇校验(O) | 数据位中1的个数 + 校验位 = 奇数 | 0x55有4个1,校验位=1,总1数=5(奇数) |
| 偶校验(E) | 数据位中1的个数 + 校验位 = 偶数 | 0x55有4个1,校验位=0,总1数=4(偶数) |
校验位只能检测奇数个位错误。如果两个位同时翻转,校验位就发现不了。不过对于大多数嵌入式场景,够用了。
波特率:通信的“节拍器”
波特率就是每秒传输的符号数。对UART来说,一个符号就是一个位。所以波特率 = 位速率。
常用波特率有:9600、19200、38400、115200、921600。115200是很多MCU的默认值,速度适中,稳定性好。
收发双方的波特率必须一致,误差一般要求在±2%以内。误差大了,采样点会偏移,导致数据错位。
波特率误差:看不见的杀手
为什么波特率误差会出问题?我画个时序图你就明白了。
你看,误差会累积。起始位检测时对齐,但每过一个位,采样点就偏移一点。到最后一个数据位或停止位时,可能就采到边界上了。
UART配置的常见组合
实际项目中,UART配置通常用三个字母表示:数据位-校验位-停止位。比如8N1、8E1、7O2。
| 配置 | 数据位 | 校验位 | 停止位 | 帧长度 | 适用场景 |
|---|---|---|---|---|---|
| 8N1 | 8 | 无 | 1 | 10位 | 最通用,效率最高 |
| 8E1 | 8 | 偶校验 | 1 | 11位 | Modbus RTU 默认 |
| 8O1 | 8 | 奇校验 | 1 | 11位 | 部分工业协议 |
| 7E1 | 7 | 偶校验 | 1 | 10位 | 老式ASCII终端 |
| 8N2 | 8 | 无 | 2 | 11位 | 长线、高干扰环境 |
UART的硬件流控
除了基本帧格式,UART还有硬件流控:RTS(请求发送)和CTS(允许发送)。
简单说:发送前先问对方“能收吗?”,对方说“能”再发。这样能防止接收缓冲区溢出。
不过,很多嵌入式场景不用流控。只要双方处理速度匹配,或者用软件协议控制,就够了。
小结
UART协议基础,说白了就是约定好“怎么开始、怎么结束、中间传什么、传多快”。起始位和停止位保证帧同步,数据位承载信息,校验位提供基础检错,波特率决定速度。这些参数必须收发一致,否则通信失败。