1 / 9
文档名称:

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

格式:doc   大小:57KB   页数:9页
下载后只包含 1 个 DOC 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

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

上传人:海洋里徜徉知识 2025/3/11 文件大小:57 KB

下载得到文件列表

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

相关文档

文档介绍

文档介绍:该【Modbus协议中CRC校验和LRC校验 】是由【海洋里徜徉知识】上传分享,文档一共【9】页,该文档可以免费在线阅读,需要了解更多关于【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 值于报文时,如下面描述的那样,高低字节必须互换。
MODBUS协议的CRC校验子程序代码
为方便读者使用MODBUS协议,将VC、VB、ASM51环境下MODBUS协议的CRC校验子程序代码一并给出,供读者参考。
//***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=0xFFFF
for (i=0;i<num;i )
{
c=snd[i] & 0x00FF;
crc^=c;
for(j=0,j<8,j )
{
if (crc & 0x0001)
{
crc>>=1;
crc^=0xA001;
}
else
crc>>=1
}
}
return(crc);
}
unsigned short int CrcCheck(const unsigned char * buffer, const int 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, 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, 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, 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, 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, 0x1, 0xC0, 0x80, 0x41, 0x0, 0xC1, 0x81, 0x40, 0x1, 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, 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, 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, 0xA5, 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, 0x70, 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,
0x44, 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 ^ buffer[i];
dCRCLo = dCRCHi ^ CRCHi[m];
dCRCHi = CRCLo[m];
}
crcValue = dCRCLo + (dCRCHi << 8);
return crcValue;
}
' //***CRC Calculation for MODBUS Protocol for VB***//
Function mb_crc(ByRef snd() as BYTE,num as integer) as Long
crc_l=crc_h=&HFF
for i=1 to num
crc_l=crc_l XOR snd(i)
for j=1 to 8
if crc_l AND 1 then
crc_l=(crc_l-1)/2
if crc_h and 1 then
crc_l=crc_l 128
crc_h=(crc_h-1)/2
end if
crc_l=crc_l XOR &HA0
crc_h=crc_h XOR &H01
else: crc_l=crc_l/2
if crc_h and 1 then
crcl_l=crc_l 128
crc_h=(crc_h-1)/2
else: crc_h=crc_h/2
end if
end if
next j
next i
mb_crc=crc_l crc_h*256
End Function
 
;CRC Calculation for MODBUS Protocol for ASM51
;R1 为发送(接受)字节的缓存首地址
;R2 为发送(接受)字节的字节数(不含CRC字节),
;R3 为CRC校验低位字节,
;R4 为CRC校验高位字节,
CRC: MOV A,#0FFH
MOV R4,A
MOV R3,A
CRC1: MOV A,***@R1
XRL A,R3
MOV R3,A
MOV R2,#08H
CRC8: CLR C
MOV A,R4
RRC A
MOV R4,A
MOV A,R3
RRC A
MOV R3,A
JNC CRC10
MOV A,R3
XRL A,#01H
MOV R3,A
MOV A,R4
XRL A,#0A0H
MOV R4,A
CRC10: DJNZ R2,CRC8
INC R1
DJNZ CRC1
RET
LRC 的生成
纵向冗余校验(LRC)为一个字节,具有8 位二进制值。LRC 由发送设备计算,并附加LRC 到报文。接受设备在接受文时计算LRC, 并将计算的结果与在LRC 接受到的实际值相比较,假如两个值不相等,则结果为错。
LRC 的计算, 对报文中的所有的连续8 位字节相加,忽略任何进位,然后求出其二进制补码。
LRC 为一个8 位域,那么每个会导致值大于255新的相加只是简朴的将域的值在零”缭绕”。由于没有第9 位,进位被自动放弃。生成一个LRC 的过程为:
”冒号”和结束CRLF 的报文中的所有字节相加到一个8位域,故此进位被丢弃。
(全1)十六进制中减去域的最终值,产生1 的补码(二进制反码)。
产生二进制补码.
将 LRC 置于报文当8 位LRC (2 个 ASCII 字符) 在报文中传送时,高位字符一方面发送,然后是低位字符。例如,假如LRC 值为十六进制61 (0110 0001):
例: 下面给出了执行生成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))) ; /* 返回二进制补码*/
}

最近更新

2023安徽安全员B证考试题库 29页

2025年山海经读书笔记00字 10页

2025年属龙缺金皮姓男孩名字精选 4页

2025年属龙缺水周姓出生男孩有哪些好名 5页

2025年属龙洋气的姓牛男孩名字 7页

2025年属鼠缺火赵姓男孩起名 4页

2025年属鼠缺木宦姓男孩名字精选 4页

高二班会:树立目标,规划未来-学生目标规划激.. 22页

高中英语阅读理解策略-提高高二阅读理解 24页

2025年属蛇缺火李姓男宝宝起名 4页

高中数学解析几何之直线与平面的交点问题-数学.. 27页

2025年属蛇人全年运势介绍 8页

2025年属虎缺火苗姓女宝宝名字精选 4页

2025年属虎缺水唐姓男宝宝名字大全 4页

高三学生身心健康教育-健康教育专家 25页

个人自我陈述报告(4篇) 3页

2025年属猴缺金谢姓女孩取名 4页

中秋节晚会主持活动开场白范文(9篇) 10页

医疗污水处理工艺介绍及设计实例 3页

2025年属猴缺土鲍姓女孩名字大全 4页

2025年属猪缺金蒋姓男孩起名 4页

北京零售企业可持续发展评价研究 3页

体育组工作总结 15页

驱动未来:数据之路-创新、优化与协作的成功策.. 30页

驭风破浪,共筑未来-半年度绩效与未来发展蓝图.. 27页

香料品质的科学管理-提升品质,赋予香料新魅力.. 27页

加快小城镇建设步伐的措施研究——以达州为例.. 3页

2025年属牛缺水和姓男宝宝名字精选 4页

2025年属牛缺土彭姓女孩起名 4页

人教精通版六年级英语下册-名师教学课件-unit.. 23页