3、Modbus ASCII协议:ASCII帧格式、LRC校验计算、RTU与ASCII对比、ASCII模式调试技巧

好,咱们接着聊Modbus。上一节我们把RTU模式扒了个底朝天,这一节轮到它的“亲兄弟”——ASCII模式了。

说实话,我在现场摸爬滚打这么多年,用ASCII模式的时候确实比RTU少得多。但少归少,它有个RTU比不了的优势——可读性强。你想想看,RTU发出来的是一堆二进制数,用示波器抓出来全是乱码,而ASCII模式发的是人能看懂的字母和数字。调试的时候,这玩意儿能救命。

3.1 ASCII帧格式:长得像字符串的报文

ASCII模式的帧结构,说白了就是把RTU里的每个字节拆成两个ASCII字符来发送。比如0x1A,在RTU里直接发一个字节,在ASCII里就发字符'1'和'A'。

来看它的完整帧格式:

起始符 | 地址码 | 功能码 | 数据区 | LRC校验 | 结束符
  ':'   |  2字节 |  2字节 |  N字节  |  2字节  | CR+LF

每个字段都是可见的ASCII字符,这一点很关键。

各字段详解:

  • 起始符:固定为冒号':'(0x3A)。这是帧开始的标志,设备收到冒号就知道新报文来了。
  • 地址码:2个ASCII字符,比如从站地址0x11就发"11"。
  • 功能码:2个ASCII字符,比如读保持寄存器0x03就发"03"。
  • 数据区:长度可变,每个字节拆成两个字符。比如要发0x1234,就发"1234"。
  • LRC校验:2个ASCII字符,计算方式下面细说。
  • 结束符:回车CR(0x0D)+ 换行LF(0x0A)。

一个完整的例子:

读取地址为0x11的从站,起始地址0x006B,读取2个寄存器。

RTU模式发的是:11 03 00 6B 00 02 CRC16

ASCII模式发的是:: 11 03 00 6B 00 02 LRC CR LF

注意,这里的"11 03 00 6B 00 02"都是ASCII字符,不是二进制数。

3.2 LRC校验计算:比CRC简单多了

LRC(纵向冗余校验)的计算逻辑,比CRC16简单不止一个量级。我当年第一次手算LRC,五分钟就搞定了。

计算步骤:

  1. 把地址码、功能码、数据区的所有字节加起来(注意是字节,不是ASCII字符)。
  2. 丢掉进位,只保留低8位。
  3. 用256减去这个结果,得到LRC值。
  4. 把LRC值转成2个ASCII字符,放到帧里。

说白了就是三步:求和 → 取补 → 转ASCII。

举个实际例子:

还是上面那个报文,地址0x11,功能码0x03,数据区0x00 0x6B 0x00 0x02。

求和:0x11 + 0x03 + 0x00 + 0x6B + 0x00 + 0x02 = 0x81
取补:0x100 - 0x81 = 0x7F
转ASCII:'7' 和 'F'

所以LRC字段就是"7F"。

我的小技巧:

写代码的时候,LRC计算可以用一个循环搞定。我习惯这样写:

uint8_t calcLRC(uint8_t *data, uint16_t len) {
    uint8_t sum = 0;
    for(uint16_t i = 0; i < len; i++) {
        sum += data[i];
    }
    return (uint8_t)(0x100 - sum);
}

注意,这个函数计算的是字节和的补码,不是直接取反。

3.3 RTU与ASCII对比:各有各的活法

这两个模式,我打个比方你就明白了:RTU像快递员,送得快但包裹上全是编号;ASCII像邮递员,送得慢但地址写得清清楚楚。

对比项 RTU模式 ASCII模式
数据密度 高,一个字节传一个数据 低,一个字节拆成两个字符
传输效率 高,同样波特率下快一倍 低,只有RTU的一半
校验方式 CRC16,计算复杂但检错强 LRC,计算简单但检错弱
帧间隔 3.5字符时间,严格 CR+LF,明确
可读性 差,全是二进制 好,全是可见字符
适用场景 高速、大数据量 调试、低速、人机交互

什么时候用ASCII? 我个人觉得,就两种情况:

  • 调试阶段,想用串口助手直接看报文内容。
  • 通信链路质量差,RTU的3.5字符间隔老是被打断。

注意:

ASCII模式虽然可读性好,但传输效率只有RTU的一半。同样9600波特率,RTU一秒能传100个报文,ASCII只能传50个。如果你对实时性有要求,老老实实用RTU。

3.4 ASCII模式调试技巧:实战出真知

调试ASCII模式,比RTU舒服多了。为什么?因为你能直接看到报文内容。

技巧一:用串口助手直接看

打开串口助手,设置好波特率、数据位、停止位,选ASCII显示模式。你看到的报文就是这样的:

:1103006B00027F0D0A

一眼就能看出:起始符是':',地址是11,功能码是03,数据是006B0002,校验是7F,结束是0D0A。

技巧二:手算LRC验证

我曾经在现场遇到过一个问题:PLC发过来的ASCII报文,从站就是不响应。我拿计算器一算LRC,发现PLC算错了。这就是ASCII模式的好处——你可以拿笔算。

技巧三:注意字符大小写

Modbus ASCII标准里,十六进制字符A-F用大写。但有些设备不讲究,小写也认。我建议你统一用大写,省得踩坑。

技巧四:帧结束符不能省

ASCII模式靠CR+LF判断帧结束,不像RTU靠时间间隔。如果你漏发了结束符,从站会一直等,等到超时。

调试口诀:

冒号开头CRLF结尾,中间全是可见字符。
LRC校验算补码,大写字母最稳妥。

嗯,ASCII模式的内容就这些。说白了它就是RTU的“慢速可读版”,适合调试和低速场景。下一节我们讲Modbus TCP,那又是另一番天地了。