第二章 XY2-100 协议基础:帧结构、波特率、数据编码方式

做故障定位,最怕的就是连基础协议都没摸清楚就开始上示波器乱戳。我当年刚入行的时候就这么干过,折腾一整天,最后发现是帧格式配错了——丢人吧?

这一章咱们把 XY2-100 的协议底牌摊开。说白了就三样东西:帧结构、波特率、数据编码方式。这三样任何一个对不上,通信必断。

XY2-100 协议基础核心要素 帧结构 起始位 (1 bit) 数据位 (8 bit) 校验位 (1 bit 偶校验) 停止位 (1 bit) 波特率 9600 bps(常用) 19200 bps 38400 bps 数据编码方式 NRZ 不归零编码 时钟同步 (起始位触发) 三者必须完全匹配:同一站点的帧格式、波特率、编码方式 任何一项不一致 → 通信中断 / 误码率暴增 🔧 故障定位第一步:用示波器抓波形,确认帧时序和位宽是否对标 例如 9600 bps 时,1 bit 宽度 ≈ 104 μs

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 了——总线短路或者上拉电阻失效,我都吃过亏。

编码与帧结构配合的那一套完整流程,可以这样理解:

  1. 空闲状态:总线持续高电平(停止位也是高电平,所以连续空闲时一直是高)。
  2. 发送起始位:拉低电平,产生下降沿,通知接收端“准备接收”。
  3. 发送数据位:按 LSB 优先依次送出 8 位,每个 bit 保持对应电平。
  4. 发送校验位:计算前面 8 位中 1 的个数,若为奇数则校验位补 1,若为偶数则补 0,确保总数为偶数。
  5. 发送停止位:拉高电平,结束这一帧。

你会在示波器上看到类似这样的波形(假设发送字节 0x41 = 二进制 01000001,LSB 在前):

空闲高电平 → 起始位(低)→ 数据位: 1 0 0 0 0 0 1 0 → 校验位(偶校验,数一下:数据位有 2 个 1,已偶数 → 补 0)→ 停止位(高)→ 空闲高电平

实际波形里,只要数一下从下降沿到停止位之后的上升沿之间的时间间隔是不是 11 个 bit 宽度,就能判断帧结构是否完整。