发表于:2020/1/8 10:08:05
#0楼
Modbus协议,相信大家都不陌生。串口Modbus协议的数据形式分为两类,Modbus-RTU(二进制)和Modbus-ASCII。其中常用的是Modbus-RTU的方式,报文内容如下:
(以03读寄存器为例)
字节1:站号
字节2:功能码
字节3:从站地址高位
字节4:从站地址低位
字节5:读取数量高位
字节6:读取数量低位
字节7:CRC校验高位
字节8:CRC校验低位
例如:读取4号从站的0002号寄存器:
04 03 00 02 00 01 25 9F
最后的25 9F就是报文中的CRC校验。对于每一个主站发给从站的Modbus命令,都要附带2个字节的CRC校验,这样才能确保数据的准确无误性。
那么问题来了,CRC校验是如何得出的呢?如果我们要用自由口的方式来编写Modbus程序,如何来计算CRC校验值呢?
先看一下CRC校验的定义:
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
CRC校验算法主要分为七个步骤:
1、设置CRC存储器为16#FFFF。
2、把第一个参与校验的8位数与CRC的低八位进行异或运算结果仍存与CRC。
3、把CRC右移一位,最高位补0,检查最低位b0位。
4、若b0=0,CRC不变,若b0=1,CRC与16#A001进行异或运算,结果仍存与CRC。
5、重复3、4两步,直到右移8次,这样第一个八位数就进行处理了结果仍然存于CRC。
6、重复2~5步,处理第二个八位数。
7、处理完后,对所得结果进行高低字节交换
流程图如下所示:
从上图中发现,有两个循环过程,小循环是对单个数据的CRC的计算,主要是对首个数据的CRC暂存器进行8次移位运算,大循环是所有数据的运算(先运算完一个8位数据的CRC,下一个数据与这个CRC进行运算),这样把所有数据都计算完成后即可得到CRC校验码。
按照流程图步骤进行编写程序如下:
1、初始CRC值:HFFFF;
2、大循环4次,依次对数据来源D10、D11、D12、D13进行校验;
3、小循环8次,对于每一个数据,
◆首先将M20复位是为了后面的高位补零用,
◆SFTR指令是位右移指令,表示对M0为起始位置的16数据右移1位置,高位用M20填补即高位补零,低位M0为移除的溢出数据即LSB。
◆如果LSB=1,则需要把移位后的数据与A001H进行异或计算,结果保存到CRC暂存器K4M0中,此时将覆盖原来的K4M0中的数据,
◆如果LSB=0,只要把移位后的数据放入CRC暂存器中即可。
4、所有数据运算完成之后,我们要对结果寄存器进行高低8位调换,将CRC校验码的低位存放到D200,高位存放发到D201中。至此CRC校验码计算完成。
看完这篇讲解,大家是不是觉得Modbus很难呢?实际并不是这样的。
FX3U系列以上的PLC都已经内置了CRC校验指令,完全不需要我们来专门计算CRC了。
退一步讲,就算是1S这种停产的PLC要做Modbus,如果是固定的几个数据读取,不需要计算CRC。就算要计算,我们也可以通过触摸屏的方式来代替。
对于Modbus协议,我们建议使用ADP-MB等专用模块,可以支持Modbus便利指令的。
事实上,越高级的PLC对于Modbus协议也是越来越简单的,结合PLC调试神器来测试数据,难度已经降低很多了。
所以,对于这篇文章,大家如果觉得理解不了的话,那就欣赏一下即可。只需要记得Modbus协议需要添加一个CRC校验就行。
————
转
(以03读寄存器为例)
字节1:站号
字节2:功能码
字节3:从站地址高位
字节4:从站地址低位
字节5:读取数量高位
字节6:读取数量低位
字节7:CRC校验高位
字节8:CRC校验低位
例如:读取4号从站的0002号寄存器:
04 03 00 02 00 01 25 9F
最后的25 9F就是报文中的CRC校验。对于每一个主站发给从站的Modbus命令,都要附带2个字节的CRC校验,这样才能确保数据的准确无误性。
那么问题来了,CRC校验是如何得出的呢?如果我们要用自由口的方式来编写Modbus程序,如何来计算CRC校验值呢?
先看一下CRC校验的定义:
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
CRC校验算法主要分为七个步骤:
1、设置CRC存储器为16#FFFF。
2、把第一个参与校验的8位数与CRC的低八位进行异或运算结果仍存与CRC。
3、把CRC右移一位,最高位补0,检查最低位b0位。
4、若b0=0,CRC不变,若b0=1,CRC与16#A001进行异或运算,结果仍存与CRC。
5、重复3、4两步,直到右移8次,这样第一个八位数就进行处理了结果仍然存于CRC。
6、重复2~5步,处理第二个八位数。
7、处理完后,对所得结果进行高低字节交换
流程图如下所示:
从上图中发现,有两个循环过程,小循环是对单个数据的CRC的计算,主要是对首个数据的CRC暂存器进行8次移位运算,大循环是所有数据的运算(先运算完一个8位数据的CRC,下一个数据与这个CRC进行运算),这样把所有数据都计算完成后即可得到CRC校验码。
按照流程图步骤进行编写程序如下:
1、初始CRC值:HFFFF;
2、大循环4次,依次对数据来源D10、D11、D12、D13进行校验;
3、小循环8次,对于每一个数据,
◆首先将M20复位是为了后面的高位补零用,
◆SFTR指令是位右移指令,表示对M0为起始位置的16数据右移1位置,高位用M20填补即高位补零,低位M0为移除的溢出数据即LSB。
◆如果LSB=1,则需要把移位后的数据与A001H进行异或计算,结果保存到CRC暂存器K4M0中,此时将覆盖原来的K4M0中的数据,
◆如果LSB=0,只要把移位后的数据放入CRC暂存器中即可。
4、所有数据运算完成之后,我们要对结果寄存器进行高低8位调换,将CRC校验码的低位存放到D200,高位存放发到D201中。至此CRC校验码计算完成。
看完这篇讲解,大家是不是觉得Modbus很难呢?实际并不是这样的。
FX3U系列以上的PLC都已经内置了CRC校验指令,完全不需要我们来专门计算CRC了。
退一步讲,就算是1S这种停产的PLC要做Modbus,如果是固定的几个数据读取,不需要计算CRC。就算要计算,我们也可以通过触摸屏的方式来代替。
对于Modbus协议,我们建议使用ADP-MB等专用模块,可以支持Modbus便利指令的。
事实上,越高级的PLC对于Modbus协议也是越来越简单的,结合PLC调试神器来测试数据,难度已经降低很多了。
所以,对于这篇文章,大家如果觉得理解不了的话,那就欣赏一下即可。只需要记得Modbus协议需要添加一个CRC校验就行。
————
转