第二章 XY2-100 协议基础:帧结构、波特率、数据编码方式
做故障定位,最怕的就是连基础协议都没摸清楚就开始上示波器乱戳。我当年刚入行的时候就这么干过,折腾一整天,最后发现是帧格式配错了——丢人吧?
这一章咱们把 XY2-100 的协议底牌摊开。说白了就三样东西:帧结构、波特率、数据编码方式。这三样任何一个对不上,通信必断。
1. 帧结构:每一比特都不能错
XY2-100 用的是标准异步串行帧,一帧总共 11 位(1个起始位 + 8个数据位 + 1个偶校验位 + 1个停止位)。你想想看,如果设备 A 配了奇校验,设备 B 配了偶校验,两边根本说不上话——这我遇到过,某次现场运维说通信不稳定,结果发现是有人误改了校验方式。
- 起始位:拉低电平,持续 1 个 bit 时间,用来通知接收端“我要发数据了”。
- 数据位:低位在前,高位在后,共 8 位(一个字节)。
- 校验位:偶校验,保证数据位 + 校验位里“1”的个数为偶数。
- 停止位:拉高电平,持续 1 个 bit 时间,给接收端一点喘息准备接收下一帧。
实用指标:发送一帧的总时长 = (1 + 8 + 1 + 1) / 波特率。9600 bps 时,一帧 ≈ 1.145 ms。每秒最多 870 帧左右。
2. 波特率:通信的节拍器
波特率就是每秒传输的比特数。XY2-100 支持三种:9600、19200、38400。一般来说,距离短、干扰小的场景用 38400;长距离或走旧线缆,老老实实 9600。我这里有个避坑经验:
我曾经遇到过一台设备波特率设成 19200,另一台却因为固件 bug 实际上跑的是 20000——两者误差超过 2%,结果每发几十帧就丢一帧。所以不光要设成一样的数值,还要用示波器量一下实际位宽。
波特率允许的最大误差一般 ±2%,建议控制在 ±1% 以内。尤其是多个节点挂在同一总线上时,晶振偏移叠加会要命。
| 波特率 (bps) | 每 bit 宽度 | 一帧总时长 | 适用场景 |
|---|---|---|---|
| 9600 | ≈ 104 μs | ≈ 1.145 ms | 长距离、干扰大 |
| 19200 | ≈ 52.1 μs | ≈ 573 μs | 中等距离 |
| 38400 | ≈ 26.0 μs | ≈ 286 μs | 短距离、快速响应 |
3. 数据编码方式:NRZ 不归零编码
XY2-100 用的是最经典的 NRZ(Non-Return-to-Zero) 编码。什么叫 NRZ?说白了就是:高电平表示 1,低电平表示 0,一个 bit 时间内电平不变。不需要在每一位内部翻转回来。
这种编码实现简单,抗干扰能力也不错。但有个缺点:连续发多个“0”或“1”时,电平长时间不变,接收端容易失去时钟同步。所以 XY2-100 利用起始位的跳变来重新同步时钟——每次帧起始时必定有一次 1→0 的下降沿,接收端拿这个沿来校准。
我个人习惯:在调试时,先看波形上有没有清晰的下降沿(起始位),没有的话很可能是电平卡在 0 或 1 了——总线短路或者上拉电阻失效,我都吃过亏。
编码与帧结构配合的那一套完整流程,可以这样理解:
- 空闲状态:总线持续高电平(停止位也是高电平,所以连续空闲时一直是高)。
- 发送起始位:拉低电平,产生下降沿,通知接收端“准备接收”。
- 发送数据位:按 LSB 优先依次送出 8 位,每个 bit 保持对应电平。
- 发送校验位:计算前面 8 位中 1 的个数,若为奇数则校验位补 1,若为偶数则补 0,确保总数为偶数。
- 发送停止位:拉高电平,结束这一帧。
你会在示波器上看到类似这样的波形(假设发送字节 0x41 = 二进制 01000001,LSB 在前):
空闲高电平 → 起始位(低)→ 数据位: 1 0 0 0 0 0 1 0 → 校验位(偶校验,数一下:数据位有 2 个 1,已偶数 → 补 0)→ 停止位(高)→ 空闲高电平
实际波形里,只要数一下从下降沿到停止位之后的上升沿之间的时间间隔是不是 11 个 bit 宽度,就能判断帧结构是否完整。