MODBUS协议在RS485总线上有RTU和ASCII两种传输格式。
其中ASCII协议应用比较少,主要还是以RTU格式为主。
相比较于RTU的2进制传输,ASCII使用的是文本传输,整个数据包都是可打印字符。
下面是示例:
:010300000001FB\r\n
帧头是冒号(:),帧尾是换行符(\r\n),掐头去尾得到有效数据:
010300000001FB
我们再把字符串转换为16进制就得到:
0x01,0x03,0x00,0x00,0x00,0x01,0xFB
0x01是设备地址,0x03是功能码,0x0000是寄存器地址,0x0001是寄存器数量,0xFB是校验。
由些可见,ASCII帧格式虽然与RTU有所差别,但是功能码和寄存器格式是一样的。
唯一不同的是校验位,ASCII格式使用的是LRC校验算法,RTU格式使用的是CRC16校验算法。
下面是校验位的算法:
0xFB = (~(0x01 + 0x03 + 0x00 + 0x00 + 0x00 + 0x01) + 1) & 0xFF
再举一个例子,生成一条数据包:
设备地址为0x10,我要用06功能码写0x0001寄存器,值为0xABCD。
首先是生成命令字节:
0x10,0x06,0x00,0x01,0xAB,0xCD
然后计算校验位:
(~(0x10+0x06+0x00+0x01+0xAB+0xCD)+1)&0xFF = 0x71
添加校验后的有效数据:
0x10,0x06,0x00,0x01,0xAB,0xCD ,0x71
把数组转成16进制字符串:
10060001ABCD71
最后加上帧头帧尾:
:10060001ABCD71\r\n
最后的最后,别忘了通过RS485把这一串字符串发出去!
关于MODBUS-RTU的功能码详细说明,请参见下面的文章:
MODBUS常用功能码_星沉地动的博客-CSDN博客_modbus功能码Modbus中常用的功能码有8个,可以分为位操作和字操作两类.https://blog.csdn.net/qq446252221/article/details/125293329