Modbus CRC校验字节生成算法
Modbus差错校验
Modbus差错校验在Modbus串行通信中,根据传输模式(ASCII或RTU)的不同,差错校验域采用了不同的校验方法。
(1).ASCII模式在ASCII模式中,报文包含一个错误校验字段。
该字段由两个字符组成,其值基于对全部报文内容执行的纵向冗余校验(LongitudinalRedundancyCheck,LRC)计算的结果而来,计算对象不包括起始的冒号(:)和回车换行符号(CRLF)。
(2).RTU 模式在RTU 模式中,报文同样包含一个错误校验字段。
与ASCII模式不同的是,该字段由16个比特位共两个字节组成。
其值基于对全部报文内容执行的循环冗余校验(CyclicalRedundancyCheck,CRC)计算的结果而来,计算对象包括校验域之前的所有字节。
1.LRC 校验在ASCII模式中,消息是由特定的字符作为帧头和帧尾来分隔的。
一条消息必须以“冒号”(:)字符(ASCII码为0x3A)开始,以“回车换行”(CRLF)(ASCII码为0x0D 和0x0A)结束。
LRC 校验算法的计算范围为(:)与(CRLF)之间的字符。
从算法本质来说,LRC域自身为1个字节,即包含一个8位二进制数据,由发送设备通过LRC算法计算,并把计算值附到信息末尾。
接收设备在接收信息时,通过LRC算法重新计算值,并把计算值与LRC字段中接收的实际值进行比较。
若两者不同,则产生一个错误,返回一个异常响应帧。
即对报文中的所有相邻2个8位字节相加,丢弃任何进位,然后对结果进行二进制补码,计算出LRC值。
必须注意的是,计算LRC 校验码的时机,是在对报文中每个原始字节进行ASCII码编码之前,对每个原始字节进行LRC校验的计算操作。
生成LRC校验值的过程如下:(1)对消息帧中的全部字节相加(不包括起始“:”和结束符“CR-LF”),并把结果送入8位数据区,舍弃进位。
(2)由0xFF(即全1)减去最终的数据值,产生1的补码(即二进制反码)。
MODBUS的CRC校验和程序
MODBUS的CRC校验和程序modbu协议做为一种通用协议得到了广泛的应用,它有两种传输模式:ASCII和RTU。
ASCII模式采用LRC校验,RTU模式采用CRC校验。
CRC方法错误检测域的内容是通过对消息内容进行循环冗长检测方法得出的。
使用RTU模式,消息包括了一基于CRC方法的错误检测域。
CRC域检测了整个消息的内容。
CRC域是两个字节,包含一16位的二进制值。
它由传输设备计算后加入到消息中。
接收设备重新计算收到消息的CRC,并与接收到的CRC域中的值比较,如果两值不同,则有误。
CRC是先调入一值是全“1”的16位寄存器,然后调用一过程将消息中连续的8位字节各当前寄存器中的值进行处理。
仅每个字符中的8Bit数据对CRC有效,起始位和停止位以及奇偶校验位均无效。
CRC产生过程中,每个8位字符都单独和寄存器内容相或(OR),结果向最低有效位方向移动,最高有效位以0填充。
LSB被提取出来检测,如果LSB为1,寄存器单独和预置的值或一下,如果LSB为0,则不进行。
整个过程要重复8次。
在最后一位(第8位)完成后,下一个8位字节又单独和寄存器的当前值相或。
最终寄存器中的值,是消息中所有的字节都执行之后的CRC值。
CRC域附加在消息的最后,添加时先是低字节然后是高字节。
故CRC的高位字节是发送消息的最后一个字节。
下面是用VB实现的CRC校验和程序:FunctionCRC16(data()AByte)AString’CRC计算函数DimCRC16LoAByte,CRC16HiAByte’CRC寄存器DimCLAByte,CHAByte’多项式码&HA001DimSaveHiAByte,SaveLoAByteDimIAIntegerDimFlagAIntegerCRC16 Lo=&HFFCRC16Hi=&HFFCL=&H1CH=&HA0ForI=0ToUBound(data)CRC16Lo=CRC16Lo某ordata(I)’每一个数据与CRC寄存器进行异或ForFlag=0To7SaveHi=CRC16HiSaveLo=CRC16LoCRC16Hi=CRC16Hi\\2’高位右移一位CRC16Lo=CRC16Lo\\2’低位右移一位If((SaveHiAnd&H1)=&H1)Then’如果高位字节最后一位为1CRC16Lo=CRC16LoOr&H80’则低位字节右移后前面补1EndIf’否则自动补0If((SaveLoAnd&H1)=&H1)Then’如果LSB为1,则与多项式码进行异或CRC16Hi=CRC16Hi某orCHCRC16Lo=CRC16Lo某orCLEndIfNe某tFlagNe某tIDimReturnData(1)AByteReturnData(0)=CRC16Hi’CRC高位ReturnData(1)=CRC16Lo’CRC低位ad=Right(\EndFunction多线程串行通讯VB源码OptionE某plicitPrivateWithEventoTet1ATetE某e.clTetPrivateWithEventoTet2ATetE某e.clTetPrivateDeclareFunctionGetTickCountLib\Dimmi,iAIntegerDoEventLoopUntilGetTickCount()-tt>tEndSubSetoTet1=NewTetE某e.clTetoTet1.lMilliec=100oTet1.StartSub(1000)SetoTet2=NewTetE某e.clTetoTet2.lMilliec=100oTet2.StartSub(1000)SetoTet1=NothingSetoTet2=NothingEndSubPrivateSubForm_Unload(CancelAInteger)oTet1.StopSuboTet2.Stop SubSetoTet1=NothingSetoTet2=NothingEndSubPrivateSuboTet1_Progre(ByVallProgreALong)Lit1.AddItemlProgre Lit1.LitInde某=Lit1.LitCount-1EndSubPrivateSuboTet2_Progre(ByVallProgreALong)recieve_meageLit2.AddItemlProgreLit2.LitInde某=Lit2.LitCount-1EndSubPrivateSubend_meage()MgBo某\通讯错误,请确认线路是否连接\错误\Ele'Label1.Caption=\开始运行\EndIfPrivateSubent_mg_Click()end_meageEndSubPrivateSubhow_mg_Click()recieve_meageEndSub如何用VB实现Modbu串行通讯在一些应用中可能需要使用诸如VB来进行上位机监控程序的开发,而Modbu协议是这类应用中首选的通讯协议;Modbu协议以其简单易用,在工业领域里已广泛的为其他第三方设备所支持。
Modbus+RTU协议中字节型CRC-16算法详解
设M(x)=K(x) *xr,即M(x)的位数k+r=8*(q+p)=8*m,即m个字节(Byte)。
将余数的首位0去除,在余数的末尾后添加1位0r-6,形成新的被除数,继续与除数(1gr-1⋯g0)进行mod2运算,如此重复8次,直至m0位与除数的首位1进行异或运算,这时剩下的余数去除首位0后就是信息m7⋯m0的CRC议,常规485通讯的信息发送形式如下:
为什么新信息码与生成多项式G(x)进行模-2(mod 2)除法运算结果为0呢?
模-2(mod 2)运算采用无进位的二进制加法,恰好为异或⨁操作。
1与A做⨁,A值取反。
0与A做⨁,A值保持不变。
A⨁A = 0A与自身做⨁,其值为0。
CRC校验码的产生(K(x) *xr)mod2 G(x) = R(x)
G(x)为r+1位;K(x)为k位,K(x)*xr为k+r位,即xr使K(x)的多项式系数左移r位,添了r位的0;R(x)为r位,是CRC校验码。
新信息码N(x) = K(x) *xr+ R(x)因为K(x) *xr的后r位为0,所以上式等价于N(x) = K(x) *xr⨁R(x),此刻认为R(x)是k+r位,即认为R(x)的前k个系数为0。
设M100 mod2 G(x) = A1A2,M100表示3个字节,其中后两个字节为0;G(x)是17位的生成多项式;A1A2是CRC校验码,两个字节。则对于任意三个字节的数据M1M2M3,有M1M2M3mod2 G(x)= (M100⨁0M2M3) mod2 G(x) = ((M100 mod2 G(x))⨁((0M2M3mod2 G(x)) =A1A2⨁M2M3。
Modbus CRC校验程序
Modbus CRC校验程序基本在网上对于MODBUS 的CRC校验程序都能找到两个版本,一个是直接运算的,一个是查表法的。
首先来看一下直接运算的算法运算步骤如下:步驟1:令16-bit 寄存器(CRC 暫存器) = FFFFH.步驟2:Exclusive OR 第一個8-bit byte 的訊息指令與低位元16-bit CRC 寄存器, 做Exclusive OR ,將結果存入CRC 寄存器內。
步驟3:又移一位CRC 寄存器,將0 填入高位處。
步驟4:檢查右移的值,如果是0, 將步驟3 的新值存入CRC 寄存器內, 否則ExclusiveOR A001H 與CRC 寄存器,將結果存入CRC 寄存器內。
步驟5:重複步驟3~步驟4,將8-bit 全部運算完成。
步驟6:重複步驟2~步驟5,取下一個8-bit 的訊息指令,直到所有訊息指令運算完成。
最後,得到的CRC 寄存器的值,即是CRC 的檢查碼。
值得注意的是CRC 的檢查碼必須交換放置於訊息指令的檢查碼中。
网上能找到的基本代码如下[cpp] view plaincopyprint?uint16 CRC16_Check(uint8*Pushdata,uint8 length) { uint16 Reg_CRC=0xffff; uint8 Temp_reg=0x00; uint8 i,j; for( i = 0;i<length; i ++) { Reg_CRC^= *Pushdata++;for (j = 0; j<8; j++) { if (Reg_CRC &0x0001) Reg_CRC=Reg_CRC>>1^0xA001; else Reg_CRC >>=1; } } return (Reg_CRC); } 基本算法是这个意思来着的,但答案其实是错的,校验没错为何说错呢,这里程序中的少了一句:值得注意的是CRC 的檢查碼必須交換放置於訊息指令的檢查碼中意思就是高字节地位输出,低字节高位输出。
modbus校验码计算公式
ModBus协议中,CRC校验码计算方法Modbus协议是一个master/slave架构的协议。
有一个节点是master(主站)节点,其他使用Modbus协议参与通信的节点是slave(从站)节点。
每一个slave设备都有一个唯一的地址。
在串行网络中,只有被指定为master的节点可以启动一个命令(在以太网上,任何一个设备都能发送一个Modbus命令,但是通常也只有一个主节点设备启动指令)。
一个ModBus命令包含了打算执行的设备的Modbus地址。
所有设备都会收到命令,但只有指定位置的设备才会执行及回应指令(地址0例外,指定地址0的指令是广播指令,所有收到指令的设备都会运行,不过不回应指令)。
所有的Modbus命令包含了校验码,以确定到达的命令没有被破坏。
基本的ModBus命令能指令一个RTU改变它的寄存器的某个值,控制或者读取一个I/O端口,以及指挥设备回送一个或者多个其寄存器中的数据。
数据结构通讯消息帧ASCII消息帧(在消息中的每个8Bit 字节都作为两个ASCII字符发送) 十六进制,ASCII字符0...9,A...F消息中的每个ASCII字符都是一个十六进制字符组成每个字节的位1个起始位n个数据位,最小的有效位先发送1个奇偶校验位,无校验则无1个停止位(有校验时),2个Bit(无校验时)错误检测域LRC(纵向冗长检测)有奇偶校验无奇偶校验RTU消息帧8位二进制,十六进制数0...9,A...F消息中的每个8位域都是一个两个十六进制字符组成每个字节的位1个起始位8个数据位,最小的有效位先发送1个奇偶校验位,无校验则无1个停止位(有校验时),2个Bit(无校验时)错误检测域LRC(纵向冗长检测)有奇偶校验无奇偶校验ModBus协议中,CRC校验码计算方法为:1、预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;2、把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;3、把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;4、如果移出位为0:重复第3步(再次右移一位);如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;5、重复步骤3和4,直到右移8次,这样整个8Bit数据全部进行了处理;6、重复步骤2到步骤5,进行通讯消息帧下一个字节的处理;7、将该通讯消息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;8、最后得到的CRC寄存器内容即为:CRC码Modbus的使用限制●Modbus是在1970年为可编程逻辑控制器通信开发的,这些有限的数据类型在那个时代是可以被PLC理解的,大型二进制对象数据是不支持的;●对节点而言,没有一个标准的方法找到数据对象的描述信息,举个例子:确定一个寄存器的数据是否表示一个介于30-175度之间的温度;●由于Modbus是一个主/从协议,没有办法要求设备"报告异常"(构建在以太网的TCP/IP 协议之上,被称为open-mbus除外)- 主站节点必须循环的询问每个节点设备,并查找数据中的变化。
Modbus协议中CRC校验和LRC校验
CRC 的生成循环冗余校验(CRC) 域为两个字节,包含一个二进制16 位值。
附加在报文后面的CRC 的值由发送设备计算。
接收设备在接收报文时重新计算CRC 的值,并将计算结果于实际接收到的CRC值相比拟。
如果两个值不相等,则为错误。
CRC 的计算, 开场对一个16位存放器预装全1. 然后将报文中的连续的8位子节对其进展后续的计算。
只有字符中的8个数据位参与生成CRC 的运算,起始位,停顿位和校验位不参与CRC 计算。
CRC 的生成过程中,每个8–位字符与存放器中的值异或。
然后结果向最低有效位(LSB) 方向移动(Shift) 1位,而最高有效位(MSB) 位置充零。
然后提取并检查LSB:如果LSB 为1,则存放器中的值与一个固定的预置值异或;如果LSB 为0,则不进展异或操作。
这个过程将重复直到执行完8 次移位。
完成最后一次〔第8 次〕移位及相关操作后,下一个8位字节与存放器的当前值异或,然后又同上面描述过的一样重复8 次。
当所有报文中子节都运算之后得到的存放器中的最终值,就是CRC.生成CRC 的过程为:1. 将一个16 位存放器装入十六进制FFFF (全1). 将之称作CRC 存放器.2. 将报文的第一个8位字节与16 位CRC 存放器的低字节异或,结果置于CRC 存放器.3. 将CRC 存放器右移1位(向LSB 方向),MSB 充零. 提取并检测LSB.4. (如果LSB 为0): 重复步骤3 (另一次移位).(如果LSB 为1): 对CRC 存放器异或多项式值0*A001 (1010 0000 0000 0001).5. 重复步骤3 和4,直到完成8 次移位。
当做完此操作后,将完成对8位字节的完整操作。
6. 对报文中的下一个字节重复步骤2 到5,继续此操作直至所有报文被处理完毕。
7. CRC 存放器中的最终容为CRC 值.8. 当放置CRC 值于报文时,如下面描述的那样,上下字节必须交换。
modbus的crc码的高低位
Modbus通信协议是一种常用的工业控制系统通信协议,它采用客户端-服务器(Master-Slave)架构,用于实现不同设备之间的数据通信和控制。
在Modbus协议中,CRC码(Cyclic Redundancy Check)起着重要的作用,用于检测和纠正数据传输过程中的错误。
其中,CRC码的高低位顺序对于通信数据的正确性至关重要。
本文将从CRC 码的概念、计算方法和应用等方面对Modbus协议中的CRC码的高低位进行深入探讨。
一、CRC码的概念CRC码是一种通过对数据进行多项式除法运算而得出的一组校验码,用于检测数据传输中是否出现了错误。
在Modbus协议中,CRC码通常由16位二进制数字组成,通过对待发送的数据按照一定的算法进行处理而得出。
CRC码的概念包括生成多项式和计算过程。
生成多项式是确定CRC算法的关键,它决定了CRC码的计算规则和结果。
在Modbus协议中,生成多项式为0xA001,对应的二进制表示为1010 0000 0000 0001。
CRC码的计算过程是将待发送的数据与生成多项式进行模2除法,得出余数作为CRC码。
具体的计算方法将在下一节详细介绍。
二、CRC码的计算方法在Modbus协议中,CRC码的计算方法可以分为两种:高位在前和低位在前。
这两种计算方法决定了CRC码的排列顺序,对于数据的正确性和有效性具有重要影响。
1. 高位在前高位在前指的是在进行CRC码计算时,先处理数据的高位(左边)比特,然后再处理低位(右边)比特。
这种计算方法也被称为大端模式(Big Endian),在网络通信中普遍应用。
在Modbus协议中,高位在前的CRC码计算方法遵循以下步骤:(1)初始化CRC寄存器为0xFFFF;(2)将每个数据按照高位在前的顺序依次与CRC寄存器进行异或运算;(3)对每个数据进行8次位移操作,即将数据与0x01进行与运算,再将数据右移1位,并与0x7FFF进行与运算;(4)重复上述过程,直至所有数据均被处理完毕;(5)最终得到的CRC寄存器值即为高位在前的CRC码。
详解Modbus协议的RTU帧和ASCII帧(2)
详解Modbus协议的RTU帧和ASCII帧(2)前面已经分析过RTU帧和ASCII帧的报文区别,细心的朋友应该会发现在两种不同的报文传输模式下都有一个共同的组成部分——差错校验。
这个差错校验在RTU模式和ASCII模式下也不是不相同的。
看下面的对比:RTU模式的差错校验:ASCII模式的差错校验:总而言之,RTU模式下用的是CRC校验,ASCII模式下用的是LRC 校验。
下面会说明这两者不同的校验方式是怎么实现的。
1、RTU模式的CRC校验在RTU 模式中基于循环冗余校验( CRC -- Cyclical RedundancyChecking) (算法)的错误检验域。
CRC 域检验整个报文的内容。
不管报文有无奇偶校验,均执行此检验。
CRC 包含由两个8 位字节组成的一个16 位值,作为报文的最后的域附加在报文之后。
计算后,首先附加低字节,然后是高字节。
CRC高字节为报文发送的最后一个子节。
附加在报文后面的CRC 的值由发送设备计算。
接收设备在接收报文时重新计算CRC 的值,并将计算结果于实际接收到的CRC 值相比较。
如果两个值不相等,则为错误。
这样的操作是可以防止数据在传送过成发生错误,导致最后出现异常现象。
(1)CRC生成的原理CRC 的生成过程中,每个8–位字符与(寄存器)中的值异或。
然后结果向最低有效位(LSB) 方向移动(Shift) 1 位,而最高有效位(MSB) 位置充零。
然后提取并检查LSB:如果LSB 为1,则寄存器中的值与一个固定的预置值异或;如果LSB 为0,则不进行异或操作。
这个过程将重复直到执行完8 次移位。
完成最后一次(第8 次)移位及相关操作后,下一个8位字节与寄存器的当前值异或,然后又同上面描述过的一样重复8 次。
当所有报文中子节都运算之后得到的寄存器中的最终值,就是CRC。
(2)CRC的生成过程1. 将一个16 位寄存器装入十六进制FFFF (全1). 将之称作CRC 寄存器.2. 将报文的第一个8 位字节与16 位CRC 寄存器的低字节异或,结果置于CRC 寄存器.3. 将CRC 寄存器右移1 位(向LSB 方向),MSB 充零. 提取并(检测)LSB.4. (如果LSB 为0): 重复步骤3 (另一次移位).(如果LSB 为1): 对CRC 寄存器异或多项式值0xA001 (1010 0000 0000 0001).5. 重复步骤3 和4,直到完成8 次移位。
c#CRC-16MODBUS校验计算方法及异或校验算法
c#CRC-16MODBUS校验计算⽅法及异或校验算法⼗年河东,⼗年河西,莫欺少年穷学⽆⽌境,精益求精只要是代码,如下:///<summary>///低字节在前///</summary>///<param name="pDataBytes"></param>///<returns></returns>static byte[] CRC16LH(byte[] pDataBytes){ushort crc = 0xffff;ushort polynom = 0xA001;for (int i = 0; i < pDataBytes.Length; i++){crc ^= pDataBytes[i];for (int j = 0; j < 8; j++){if ((crc & 0x01) == 0x01){crc >>= 1;crc ^= polynom;}else{crc >>= 1;}}}byte[] result = BitConverter.GetBytes(crc);return result;}///<summary>///⾼字节在前///</summary>///<param name="pDataBytes"></param>///<returns></returns>static byte[] CRC16HL(byte[] pDataBytes){ushort crc = 0xffff;ushort polynom = 0xA001;for (int i = 0; i < pDataBytes.Length; i++){crc ^= pDataBytes[i];for (int j = 0; j < 8; j++){if ((crc & 0x01) == 0x01){crc >>= 1;crc ^= polynom;}else{crc >>= 1;}}}byte[] result = BitConverter.GetBytes(crc).Reverse().ToArray() ;return result;}还有两个供⼤家验证的byte数组,如下:List<byte> llsst = new List<byte>() {0x79,0x79,0x01,0x01,0x00,0x1C,0x01,0x90,0x00,0x01,0x28,0xC3,0xC1,0x00,0xE9,0x9E,0x00,0x00,0x00,0x00,0x52,0x85,0x00,0x01,0x11,0x8E,0x15,0x02,0xD0,0x41,0x3E,0x02,0x0B var CrcLs3t22 = CRC16LH(llsst.ToArray());var CrcLs2t25 = CRC16HL(llsst.ToArray());低字节在前的结果为:83 9A⾼字节在前的结果为:9A 83异或校验算法:public static byte XOR_Check(List<byte> pbuf){int res = 0;int len = pbuf.Count;for (int i = 0; i < len; i++){res ^= pbuf[i];}return BitConverter.GetBytes(res)[0];}@天才卧龙的博客。
modbus_CRC校验
最详细易懂的CRC-16校验原理(附源程序)标签:crc校验计算方法详细易懂源程序2010-10-29 09:39阅读(8048)评论(0)最详细易懂的CRC-16校验原理(附源程序)1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。
2、生成CRC码的基本原理:任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。
例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。
标准CRC生成多项式如下表:名称生成多项式简记式* 标准引用CRC-4 x4+x+1 3 ITU G.704CRC-8 x8+x5+x4+1 0x31CRC-8 x8+x2+x1+1 0x07CRC-8 x8+x6+x4+x3+x2+x1 0x5ECRC-12 x12+x11+x3+x+1 80FCRC-16 x16+x15+x2+1 8005 IBM SDLCCRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCSCRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCSCRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP3、CRC-16校验码的使用:现选择最常用的CRC-16校验,说明它的使用方法。
根据Modbus协议,常规485通讯的信息发送形式如下:地址功能码数据信息校验码1byte 1byte nbyte 2byteCRC校验是前面几段数据内容的校验值,为一个16位数据,发送时,低8位在前,高8为最后。
例如:信息字段代码为: 1011001,校验字段为:1010。
modbus协议crc校验计算
Modbus协议CRC校验计算Modbus协议是一种常用的工业通信协议,它使用CRC(循环冗余校验)算法来确保数据传输的正确性。
下面将介绍Modbus协议的CRC校验计算方法。
1. CRC生成多项式选择在Modbus协议中,CRC校验通常使用一个生成多项式来表示。
生成多项式是一个二进制字符串,用于确定CRC校验码的生成规则。
常用的生成多项式有CRC-16和CRC-CCITT等。
选择生成多项式时,需要确保它与Modbus协议的规定一致。
2. 初始值设定在进行CRC校验计算时,需要设定一个初始值。
这个初始值是一个全为1的二进制数,其长度与生成多项式的位数相同。
在Modbus 协议中,通常使用一个固定的初始值,例如0xFFFF或0xFFFF_FFFF。
3. 数据位处理在进行CRC校验计算时,需要对数据进行位处理。
具体来说,将数据按照从高位到低位的顺序逐位进行异或运算。
在异或运算中,如果两个位相同,结果为0;如果两个位不同,结果为1。
异或运算的顺序会影响到CRC校验码的生成结果。
4. 校验码生成在进行CRC校验计算时,还需要生成一个校验码。
这个校验码是根据生成多项式和初始值计算出来的。
具体的计算方法是将初始值与生成多项式进行异或运算,得到的结果即为校验码。
在校验码的长度方面,通常与生成多项式的位数相同。
需要注意的是,在Modbus协议中,CRC校验码通常会被附加在数据包的末尾。
接收方在接收到数据包后,会使用相同的生成多项式和初始值进行CRC校验计算,以验证数据包的正确性。
如果计算结果与附加的CRC校验码不一致,则说明数据包在传输过程中发生了错误。
modbus标准crc校验算法
文章标题:深入探讨Modbus标准CRC校验算法在工业自动化领域,Modbus通信协议是一种应用广泛的串行通信协议,其中的CRC校验算法对于数据完整性的验证起着至关重要的作用。
本文将围绕Modbus标准CRC校验算法展开深入探讨,以便读者能够更全面地了解该算法的原理和应用。
1. 什么是Modbus通信协议?Modbus是一种用于工业领域的通信协议,它通常用于连接各种自动化设备和控制系统,如PLC(可编程逻辑控制器)、传感器、执行器等。
Modbus协议可以通过串行通信或以太网进行数据传输,实现设备之间的数据交换和控制命令的传输。
2. CRC校验算法的作用及原理CRC(Cyclic Redundancy Check)是循环冗余校验的缩写,是一种通过对数据进行计算并附加校验值来验证数据完整性的算法。
在Modbus通信中,CRC校验算法被用于检测通信数据在传输过程中是否发生了误码或数据损坏。
Modbus标准CRC校验算法采用的是CRC-16-Modbus算法,它基于多项式计算和位操作来生成16位的校验码。
在发送端,数据帧的CRC校验码由发送设备计算并附加在数据帧的末尾;在接收端,接收设备也对接收到的数据帧进行CRC校验,来验证接收到的数据是否完整和正确。
3. Modbus标准CRC校验算法的具体计算方法Modbus标准CRC校验算法的计算方法比较复杂,需要对数据帧进行按位运算和多项式计算。
需要对每个字节的数据进行移位和异或运算,然后再进行一系列的位操作和多项式运算,最终得到16位的CRC校验码并附加在数据帧的末尾。
4. Modbus标准CRC校验算法的应用场景Modbus标准CRC校验算法广泛应用于工业自动化领域的数据通信和控制系统中。
它能够有效地验证数据传输的完整性和准确性,确保通信数据的可靠性和稳定性。
在 PLC、传感器、执行器等设备之间的数据交换和控制指令传输中,CRC校验算法能够及时发现并纠正数据错误,保障系统的正常运行。
modbus crc校验码计算原理
modbus crc校验码计算原理Modbus CRC校验码计算原理介绍Modbus是一种常用的通信协议,广泛应用于工业控制系统中。
它采用CRC校验码对数据进行完整性验证,以确保数据的准确传输。
本文将从浅入深地解释Modbus CRC校验码计算的原理。
CRC校验码简介•CRC(Cyclic Redundancy Check)是一种循环冗余校验码,用于检测数据传输过程中是否出现错误。
•CRC校验码是通过将数据按位异或计算得出的,具有很强的验证能力。
•Modbus采用16位的CRC校验码,通常表示为4个十六进制数。
CRC校验码计算过程CRC校验码的计算过程如下:1.初始化一个16位的寄存器,将其置为全1。
2.对每个输入字节,将其与寄存器的低字节进行异或运算,得到一个结果。
3.将寄存器右移1位。
4.如果上一步的结果最低位为1,将寄存器与一个预设的固定值(0xA001)进行异或运算。
5.重复步骤2~4,直到所有输入字节处理完毕。
6.最终得到的寄存器值即为CRC校验码。
示例假设要计算以下输入数据的CRC校验码:0x01 0x02 0x03。
1.初始化寄存器为全1(0xFFFF)。
2.将输入数据0x01与寄存器低字节(0xFF)进行异或运算,得到结果0xFE。
3.将寄存器右移1位,得到0x7F。
4.由于上一步的结果最低位为1,将寄存器与预设固定值0xA001进行异或运算,得到0x3F01。
5.重复步骤2~4,依次处理输入数据0x02和0x03。
6.最终得到的寄存器值为CRC校验码,即0x3F01。
总结CRC校验码是Modbus通信中重要的数据完整性验证手段。
通过将数据进行位异或运算,并结合预设固定值,可以计算出16位的校验码。
通过比较接收到的校验码和计算得出的校验码,可以判断数据传输是否发生错误。
CRC校验的原理CRC校验码由于其简单而高效的计算方法,广泛应用于数据传输中。
其原理可以通过简单的位运算来理解。
MODBUS RTU CRC校验程序
* 将数据D10开始放入D2中与CRC异或运算,算完后用V1加1进入下字节运算
D10→D50
M8000 26 MOV D10V1 发送数据 起始位 D2 运算辅助 寄存器
1应用:M10→M100
WXOR
D2 K4M10 运算辅助 CRC寄存 寄存器 器起始位
K4M10 CRC寄存 器起始位
* 从起始数据D10开始的每个8位数据均要从低位开始逐位进行异或运算 39 FOR K8
K4M10 CRC寄存 器起始位
CJ * 每一位异或运算完后不管结果值是否为1,均要右移一位,高位用0填补 M10 62 CRC寄存 器起始位
1应用:M10→M100 1应用:M10→M100
P2
SFTR
M0 M10 K16 填补用0值 CRC寄存 器起始位
K1
* 如上进行1个8位数据的8次循环异或运算 P2 72 * 所有要发送的数据发送数据运算完成,产生低位K2M10,高位K2M18的CRC校验码 78 NEXT INC V1 NEXT
* 计算CRC校验码前将数据进位V1复位,设定一个值全为1的CRC寄存器K4M10 M8000 0 MOV K0 V1
Modbus通信协议中CRC校验的快速C语言算法
64
福 建 电 脑 2004 年第 11 期
有两种通行的 16 位 CRC 多 项式 。 第 一种 是由 CCI T T 规 定的 。 经由信息段内各 字符 连接 而成 的信 息位 串对 应信 息多 项式的系数 , 信息多项式共有 n-16 项 , 即从 Xn -1 到 X16(n=信 息块或信息段总位数)。 这个多 项式要 生成多项 式作模 2 除法 运算 。 校验位串对应于上述除法最终得 到的余数 多项式的 X15 到 X0 项的系数 。 这个多项式简称为 CRC -CCI T T :X16 +X12 + X 5 +1。 最先由 IBM 用在第 一个 软盘控 制器(M odel 3770)上 , 很快便成为了微计算机 软盘控 制器的 标准 。 它也 用在 IBM 有 名的同步协议 HDLC/ SDLC(高级数据连接控 制/ 同步 数据连接 控制)中 。
1 Modbus 协议应用简介 Modicon 可编程控制器 , 既可以在它 们之间 , 也可以 和各种
网络上其他的设备间进行数 据传输 。 所支持的 网络包 括 M odbus 和 Modbus Plus 工业网络 , 还有标准 网络 , 如 M AP 和 Ethernet。 网络通过控 制器的接入线或者网 络适配 器 , 和 M odicon 可 利用的出口等相连 。 连接关系图见图 1 。
Modbus协议中CRC校验和LRC校验
CRC 的生成循环冗余校验(CRC) 域为两个字节,包含一个二进制16 位值。
附加在报文后面的CRC 的值由发送设备计算。
接收设备在接收报文时重新计算CRC 的值,并将计算结果于实际接收到的CRC值相比较。
如果两个值不相等,则为错误。
CRC 的计算, 开始对一个16位寄存器预装全1. 然后将报文中的连续的8位子节对其进行后续的计算。
只有字符中的8个数据位参与生成CRC 的运算,起始位,停止位和校验位不参与CRC 计算。
CRC 的生成过程中,每个8–位字符与寄存器中的值异或。
然后结果向最低有效位(LSB) 方向移动(Shift) 1位,而最高有效位(MSB) 位置充零。
然后提取并检查LSB:如果LSB 为1,则寄存器中的值与一个固定的预置值异或;如果LSB 为0,则不进行异或操作。
这个过程将重复直到执行完8 次移位。
完成最后一次(第8 次)移位及相关操作后,下一个8位字节与寄存器的当前值异或,然后又同上面描述过的一样重复8 次。
当所有报文中子节都运算之后得到的寄存器中的最终值,就是CRC.生成CRC 的过程为:1. 将一个16 位寄存器装入十六进制FFFF (全1). 将之称作CRC 寄存器.2. 将报文的第一个8位字节与16 位CRC 寄存器的低字节异或,结果置于CRC 寄存器.3. 将CRC 寄存器右移1位(向LSB 方向),MSB 充零. 提取并检测LSB.4. (如果LSB 为0): 重复步骤3 (另一次移位).(如果LSB 为1): 对CRC 寄存器异或多项式值0xA001 (1010 0000 0000 0001).5. 重复步骤3 和4,直到完成8 次移位。
当做完此操作后,将完成对8位字节的完整操作。
6. 对报文中的下一个字节重复步骤2 到5,继续此操作直至所有报文被处理完毕。
7. CRC 寄存器中的最终内容为CRC 值.8. 当放置CRC 值于报文时,如下面描述的那样,高低字节必须交换。
STEP7STL实现modbuscrc校验
STEP7STL实现modbuscrc校验用STEP7实现MODBUS CRC校验:FUNCTION "CRC" : VOIDTITLE =CRC校验//CRC校验算法://1.预置16位寄存器为16进制FFFF,作为CRC寄存器;//2.把第一个字节与CRC寄存器的低位相异或,结果放在CRC寄存器;//3.把寄存器的内容右移一位,用0填补最高位,检查移出位;//4.如果移出位为0,重复第3步,如果最低位为1,CRC寄存器与多项式AOO1进行异或;//5.重复步骤3、4,直到右移8次,这样整个8位数据全部进行了处理;//6.重复步骤2-5,进行下一个字节的处理;//7.最后得到的CRC寄存器即为CRC校验码;VERSION : 0.1VAR_INPUTDB_NO : INT ;DBB_Start : INT ;DBB_Counts : INT ;END_VARVAR_OUTPUTCRC_H : BYTE ;CRC_L : BYTE ;END_VARVAR_TEMPCRC_REG : WORD ;DB_NO_TEMP : INT ;BytesChecked : INT ;BitsChecked : INT ;END_VARBEGINNETWORKTITLE =L W#16#FFFF;T #CRC_REG; //预置CRC寄存器L #DB_NO;T #DB_NO_TEMP;OPN DB [#DB_NO_TEMP];L #DBB_Start; //读入校验起始字节SLD 3;LAR1 ;L #DBB_Counts; //读入校验字节数量_A: T #BytesChecked; //字节处理循环L DBB [AR1,P#0.0];L LB 1;XOW ;T LB 1;L 8;_B: T #BitsChecked; //位处理循环L #CRC_REG;SRW 1;T #CRC_REG;JZ _C; //检验移出位是否为1L #CRC_REG;L W#16#A001;XOW ;T #CRC_REG;_C: L #BitsChecked; //校验下个位LOOP _B;+AR1 P#1.0; //校验下个字节L #BytesChecked; LOOP _A;L LB 1; //输出校验码T #CRC_H;L LB 0;T #CRC_L;END_FUNCTION。