收藏 分销(赏)

Modbus协议中CRC校验和LRC校验.doc

上传人:丰**** 文档编号:3362445 上传时间:2024-07-03 格式:DOC 页数:9 大小:57.54KB
下载 相关 举报
Modbus协议中CRC校验和LRC校验.doc_第1页
第1页 / 共9页
Modbus协议中CRC校验和LRC校验.doc_第2页
第2页 / 共9页
Modbus协议中CRC校验和LRC校验.doc_第3页
第3页 / 共9页
Modbus协议中CRC校验和LRC校验.doc_第4页
第4页 / 共9页
Modbus协议中CRC校验和LRC校验.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

1、CRC 的生成循环冗余校验(CRC) 域为两个字节,包含一个二进制16 位值。附加在报文后面的CRC 的值由发送设备计算。接受设备在接受报文时重新计算CRC 的值,并将计算结果于实际接受到的CRC值相比较。假如两个值不相等,则为错误。CRC 的计算, 开始对一个16位寄存器预装全1. 然后将报文中的连续的8位子节对其进行后续的计算。只有字符中的8个数据位参与生成CRC 的运算,起始位,停止位和校验位不参与CRC 计算。CRC 的生成过程中, 每个 8位字符与寄存器中的值异或。然后结果向最低有效位(LSB) 方向移动(Shift) 1位,而最高有效位(MSB) 位置充零。然后提取并检查LSB:假

2、如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. (假

3、如LSB 为0): 反复环节3 (另一次移位).(假如LSB 为1): 对CRC 寄存器异或多项式值0xA001 (1010 0000 0000 0001).5. 反复环节3 和 4,直到完毕8 次移位。当做完此操作后,将完毕对8位字节的完整操作。6. 对报文中的下一个字节反复环节2 到5,继续此操作直至所有报文被解决完毕。7. CRC 寄存器中的最终内容为CRC 值.8. 当放置CRC 值于报文时,如下面描述的那样,高低字节必须互换。MODBUS协议的CRC校验子程序代码为方便读者使用MODBUS协议,将VC、VB、ASM51环境下MODBUS协议的CRC校验子程序代码一并给出,供读者参考。

4、/*CRC Calculation for MODBUS Protocol for VC */数组snd为地址等传输字节,num为字节数,发为6收为5/unsigned int mb_crc(BYTE *snd,int num)int i,j;unsigned int c,crc=0xFFFFfor (i=0;inum;i ) c=sndi & 0x00FF;crc=c;for(j=0,j=1;crc=0xA001;else crc=1return(crc);unsigned short int CrcCheck(const unsigned char * buffer, const int

5、buffLen) unsigned short int crcValue = 0; if (!buffer | buffLen 0) return crcValue; int CRCHi = 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41, 0x0,0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41

6、, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41,

7、 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40,

8、0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0

9、x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40, 0x1,0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x0, 0xC1, 0x81, 0x40, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x1

10、, 0xC0, 0x80, 0x41, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40 ; int CRCLo = 0x0, 0xC0, 0xC1, 0x1, 0xC3, 0x3, 0x2, 0xC2, 0xC6, 0x6, 0x7, 0xC7, 0x5,0xC5, 0xC4, 0x4, 0xCC, 0xC, 0xD, 0xCD, 0xF, 0xCF, 0xCE, 0xE, 0xA, 0xCA, 0xCB, 0xB, 0xC9, 0x9, 0x8, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB,0xDA, 0x1A,

11、 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14,0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,

12、0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D,0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0

13、xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x

14、70, 0xB0,0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x4

15、4, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 ; int i, m; int dCRCHi = 0xFF; int dCRCLo = 0xFF; for (i = 0; i buffLen; i+) m = dCRCLo bufferi; dCRCLo = dCRCHi CRCHim; dCRCHi = CRCLom; crcValue = dCRCLo + (dCRCHi 8); return crcValue; /*CRC Calculation for

16、 MODBUS Protocol for VB*/Function mb_crc(ByRef snd() as BYTE,num as integer) as Longcrc_l=crc_h=&HFFfor i=1 to numcrc_l=crc_l XOR snd(i)for j=1 to 8if crc_l AND 1 thencrc_l=(crc_l1)/2if crc_h and 1 thencrc_l=crc_l 128crc_h=(crc_h1)/2end ifcrc_l=crc_l XOR &HA0crc_h=crc_h XOR &H01else: crc_l=crc_l/2if

17、 crc_h and 1 thencrcl_l=crc_l 128crc_h=(crc_h1)/2else: crc_h=crc_h/2end ifend ifnext jnext imb_crc=crc_l crc_h*256End Function;CRC Calculation for MODBUS Protocol for ASM51;R1 为发送(接受)字节的缓存首地址;R2 为发送(接受)字节的字节数(不含CRC字节),;R3 为CRC校验低位字节,;R4 为CRC校验高位字节,CRC: MOV A,#0FFHMOV R4,AMOV R3,ACRC1: MOV A,R1XRL A,

18、R3MOV R3,AMOV R2,#08HCRC8: CLR CMOV A,R4RRC AMOV R4,AMOV A,R3RRC AMOV R3,AJNC CRC10MOV A,R3XRL A,#01HMOV R3,AMOV A,R4XRL A,#0A0HMOV R4,ACRC10: DJNZ R2,CRC8INC R1DJNZ CRC1RETLRC 的生成纵向冗余校验(LRC)为一个字节,具有8 位二进制值。LRC 由发送设备计算,并附加LRC 到报文。接受设备在接受文时计算LRC, 并将计算的结果与在LRC 接受到的实际值相比较,假如两个值不相等,则结果为错。LRC 的计算, 对报文中的所

19、有的连续8 位字节相加,忽略任何进位,然后求出其二进制补码。LRC 为一个8 位域,那么每个会导致值大于255新的相加只是简朴的将域的值在零”缭绕”。由于没有第9 位,进位被自动放弃。生成一个LRC 的过程为:1.不涉及起始”冒号”和结束CRLF 的报文中的所有字节相加到一个8位域,故此进位被丢弃。2.从FF (全1)十六进制中减去域的最终值,产生1 的补码(二进制反码)。3.加1 产生二进制补码.将 LRC 置于报文当8 位LRC (2 个 ASCII 字符) 在报文中传送时,高位字符一方面发送,然后是低位字符。例如,假如LRC 值为十六进制61 (0110 0001):例: 下面给出了执行

20、生成LRC 的C 语言函数。函数带有两个参数:unsigned char *auchMsg; 指向具有用于生成LRC 的二进制数据报文缓冲区的指针,unsigned short usDataLen; 报文缓冲区的字节数.LRC 生成函数static unsigned char LRC(auchMsg, usDataLen) /* 函数返回unsigned char 类型的LRC 结果*/unsigned char *auchMsg ; /* 要计算LRC 的报文*/unsigned short usDataLen ; /* 报文的字节数*/unsigned char uchLRC = 0 ; /* LRC 初始化*/while (usDataLen-) /* 完毕整个报文缓冲区*/uchLRC += *auchMsg+ ; /* 缓冲区字节相加,无进位*/return (unsigned char)(-(char)uchLRC) ; /* 返回二进制补码*/

展开阅读全文
相似文档                                   自信AI助手自信AI助手
猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服