4、Modbus ASCII协议详解:报文帧结构、LRC校验、与RTU的对比

好,咱们聊完了RTU,现在来说说Modbus ASCII。说实话,这个协议现在用得越来越少了。但我个人觉得,搞工控的人还是得懂它。为什么?因为有些老设备、或者某些特定场合(比如无线电、电话线通信),ASCII模式反而更稳。我前几年在一个水处理项目中就遇到过,现场干扰大得离谱,RTU死活收不到正确数据,最后换成ASCII模式才搞定。

4.1 什么是Modbus ASCII?

Modbus ASCII,说白了就是把数据用ASCII字符来传输。每个8位字节被拆成两个ASCII字符发送。比如一个字节 0x1A,在ASCII模式下就变成字符 '1''A' 发送出去。

你想想看,这样做的代价是什么?传输效率直接砍半。原来发1个字节的时间,现在要发2个字符。但好处也很明显——所有数据都是可见的ASCII字符,调试的时候用串口助手一看就明白,不用对着十六进制发愣。

核心特点:

  • 每个字节拆成两个ASCII字符传输
  • 报文有固定的起始和结束标记
  • 校验方式用LRC(纵向冗余校验)
  • 传输效率低,但抗干扰能力在某些场景下更好

4.2 报文帧结构

ASCII模式的报文帧结构和RTU差别很大。我刚开始学的时候老搞混,后来画了个对比表才记住。咱们直接看结构:

字段 长度 说明
起始符 1字符 固定为 ':' (0x3A)
地址码 2字符 从站地址,如 '01'
功能码 2字符 '03' 表示读保持寄存器
数据区 可变 实际数据,每个字节用两个ASCII字符表示
LRC校验 2字符 LRC校验值,两个ASCII字符
结束符 2字符 '\r\n' (回车换行)

举个例子,读取从站地址01的保持寄存器,起始地址0x0000,读取2个寄存器:

RTU模式(十六进制):
01 03 00 00 00 02 C4 0B

ASCII模式(字符串形式):
: 01 03 00 00 00 02 F7 \r \n

实际发送的ASCII字符:
':' '0' '1' '0' '3' '0' '0' '0' '0' '0' '0' '0' '2' 'F' '7' '\r' '\n'

看到了吗?RTU里一个字节 0x01,在ASCII里变成了两个字符 '0''1'。这就是效率低的原因。

我个人习惯:调试ASCII模式时,直接用串口助手看文本模式就行。RTU你得开十六进制显示,ASCII直接看字符串,一目了然。这也是它最大的优势——人类可读。

4.3 LRC校验详解

ASCII模式不用CRC,用LRC。LRC全称Longitudinal Redundancy Check,纵向冗余校验。算法比CRC简单得多。

计算步骤:

  1. 从地址码开始,到数据区结束,把所有字节累加
  2. 取累加和的补码(按位取反再加1)
  3. 只保留低8位

说白了就是:LRC = (0xFF - (累加和 & 0xFF)) + 1

咱们用上面的例子算一下:

累加字节:0x01, 0x03, 0x00, 0x00, 0x00, 0x02
累加和 = 0x01 + 0x03 + 0x00 + 0x00 + 0x00 + 0x02 = 0x06
取低8位:0x06
补码:0xFF - 0x06 + 1 = 0xFA
所以LRC = 0xFA,发送时变成字符 'F' 和 'A'

嗯,这里要注意:LRC校验的范围不包括起始符 ':' 和结束符 '\r\n'。只校验地址、功能码和数据区。

我曾经踩过的坑:有一次写ASCII从站程序,LRC算出来总是对不上。查了半天才发现,我把起始符 ':' 也算进校验范围了。记住,LRC只算 ':' 之后、'\r\n' 之前的内容。

4.4 与RTU的对比

咱们直接上对比表,这样最清楚:

对比项 ASCII模式 RTU模式
数据表示 每个字节用2个ASCII字符 直接发送二进制字节
传输效率 低,约RTU的一半
校验方式 LRC(2字符) CRC-16(2字节)
报文分隔 有明确起始符 ':' 和结束符 '\r\n' 靠3.5字符静默时间
调试难度 低,文本可见 高,需十六进制查看
抗干扰能力 某些场景下更好(字符可见,易纠错) 一般
应用场景 老设备、无线通信、电话线 绝大多数工业现场

我个人的经验是:能用RTU就用RTU。效率高、占用带宽小、CRC校验也比LRC更可靠。但如果你遇到以下情况,可以考虑ASCII:

  • 通信链路质量很差,经常丢数据
  • 调试阶段,需要快速看报文内容
  • 对接的老设备只支持ASCII模式
  • 通过无线模块或电话线通信,数据包需要可见字符

避坑指南:我曾经在一个项目中,RTU模式在强电磁干扰下频繁出错。换成ASCII后,虽然速度慢了,但至少数据能收对了。为什么?因为ASCII模式下每个字节都是可见字符,接收端可以更容易地判断数据是否完整。而且有明确的起始和结束标记,不会像RTU那样因为静默时间判断不准而粘包。

4.5 实际应用建议

如果你现在要设计一个新系统,我建议:

  1. 默认选RTU,这是行业主流,几乎所有设备都支持
  2. 只有特殊需求才考虑ASCII,比如上面提到的那些场景
  3. 如果设备同时支持两种模式,优先用RTU,除非测试发现通信不稳定
  4. 注意波特率,ASCII模式因为效率低,建议用更高的波特率(比如19200以上)来弥补

好了,ASCII协议就讲这么多。下一章咱们聊聊RTU和ASCII之间的转换方案,以及怎么用硬件或软件实现网络桥接。到时候我会分享一个我实际做过的网关项目,挺有意思的。