Modbus协议中的CRC16校验原理与实现
创作时间:
作者:
@小白创作中心
Modbus协议中的CRC16校验原理与实现
引用
CSDN
1.
https://m.blog.csdn.net/2301_76337507/article/details/142053871
Modbus协议是一种广泛应用于工业自动化领域的通信协议,其中CRC16校验是确保数据传输可靠性的重要机制。本文将详细介绍Modbus协议的基础知识、CRC16校验的计算原理,并通过代码实现和手算演算过程,帮助读者深入理解这一技术。
1. Modbus基础
Modbus是一种串行通信协议,最初由Modicon(目前属于施耐德电气公司)于1979年开发。Modbus协议是应用在Modicon产品上的,后来才被移植到其他产品上。Modbus协议的通信接口可以有多种选择,如RS232、RS485、以太网等。
特点:
- 支持主从方式,即主站、从站。
- Modbus协议主要分为两种格式,即Modbus RTU和Modbus ASCII,Modbus RTU使用二进制格式传输数据,而Modbus ASCII则将数据以ASCII码形式进行传输。
- 此外,Modbus还可以通过TCP/IP协议进行网络通信,称为Modbus TCP/IP。
格式:
- 起始地址(也就是常说的站号)
- 功能码 (01,03,06,10,16等等)
- 数据内容
- 校验码(CRC16校验)
2. 校验原理
2.1 CRC计算方法
- 预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;
- 把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;
- 把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;
- 如果移出位为0:重复第3步(再次右移一位);如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
- 重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
- 重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
- 将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换。
2.2 校验C语言代码
uint16_t CRC_Check(uint8_t *CRC_Ptr,uint8_t LEN)
{
uint16_t CRC_Value = 0;
uint8_t i = 0;
uint8_t j = 0;
CRC_Value = 0xffff;
for(i=0;i<LEN;i++) //LEN为数组长度
{
CRC_Value ^= *(CRC_Ptr+i);
for(j=0;j<8;j++)
{
if(CRC_Value & 0x00001)
CRC_Value = (CRC_Value >> 1) ^ 0xA001;
else
CRC_Value = (CRC_Value >> 1);
}
}
CRC_Value = ((CRC_Value >> 8) + (CRC_Value << 8)); //交换高低字节
return CRC_Value;
}
2.3 手算校验
我们以这个数据包为例,来分析一下校验过程:
Tx:000002-01 03 00 00 00 0A C5 CD
01 起始地址 03功能码 C5 CD 校验码
0x01与0xffff相异或,进行第一轮右移8次运算,得到0x807e;
继续下一轮0x03与0x807e相异或,进行第二轮右移8次运算;
直至0x0A轮次完成,得到最终的crc计算结果C5CD。
2.4 Modbus测试程序
#include <stdio.h>
int main(void)
{
// Tx:000000-01 03 00 00 00 0A C5 CD
unsigned short tmp = 0xffff;
unsigned short val = 0;
unsigned char buff[6] = {0};
buff[0] = 0x01;
buff[1] = 0x03;
buff[2] = 0x00;
buff[3] = 0x00;
buff[4] = 0x00;
buff[5] = 0x0A;
for(int n = 0; n < 6; n++)
{
tmp = buff[n] ^ tmp;
printf("异或数据为:%x\n",tmp);
for(int i = 0;i < 8;i++){ /*此处的8 -- 指每一个char类型又8bit,每bit都要处理*/
printf("遍历层数为:%d\t\t最后一位的数为:%d",i*n, tmp & 0x01);
printf("\t当前tmp为:%x\n",tmp );
if(tmp & 0x01){
tmp = tmp >> 1;
tmp = tmp ^ 0xa001;
}
else{
tmp = tmp >> 1;
}
}
printf("第%d个数据通过crc16校验后为 %x\n",n,tmp);
}
/*将CRC校验的高低位对换位置*/
val = tmp >> 8;
val = val | (tmp << 8);
printf("交换后为: %X\n",val);
return 0;
}
3. 补充说明
异或(XOR)
相异或(XOR,Exclusive OR)是一种逻辑运算,它的基本原则是:当两个比较的位不同时,结果是1(真);当两个比较的位相同时,结果是0(假)。这种运算通常用于计算机科学和数字电子学中。
在这里的“A”和“B”是两个比较的位,而“A XOR B”是相异或运算的结果。二进制运算中,相异或的规则可以用下面的真值表来表示:
A B A XOR B
0 0 0
0 1 1
1 0 1
1 1 0
相与(AND)
相与运算,通常称为“逻辑与”(Logical AND),是一种基本的逻辑运算。在逻辑与运算中,只有当两个(或多个)输入条件都为真(1)时,输出结果才为真(1);如果任何一个输入条件为假(0),输出结果就为假(0)。
这里的“A”和“B”是两个输入位,而“A AND B”是逻辑与运算的结果。逻辑与运算的真值表如下所示:
A B A AND B
0 0 0
0 1 0
1 0 0
1 1 1
热门推荐
海口房价现分化:教育资源成重要支撑
当结直肠癌遇上KRAS突变,为何要『KRAS抑制剂+EGFR单抗』双靶联合治疗?
如何降低甘油三酯?有效的生活方式和饮食调整方法是什么?
手把手教你电子营业执照申领及授权他人使用流程
品茶之乐:从视觉到味觉的全方位体验
惠州广济医院:选择适合的锻炼项目,让锻炼变得更加有趣!
企业工资发放全流程解析:从计算到发放的六大关键环节
参宿四已经进入生命末期,一旦爆炸亮度将超满月,白天甚至可见!
多肉植物养殖全攻略:从土壤到病虫害防治的八大要点
狼人杀的胜负条件有哪些
民国三大土匪,一为东北王,二为广西王,三为东陵大盗
深入解析软件架构中的分层架构
如何放弃一个很喜欢很喜欢的人?不用时间和新欢,做到这点就够了
红包里的年味与温情:春节里的多彩祝福
篮球配色的奥秘:从美学到战术,解读背后的深远影响
十堰至成都自驾游路线推荐
青少年防护——共筑网络安全屏障,护航数字时代成长
甲状腺癌高发,这些饮食调理原则帮你守护颈部健康
跑步十年:身体蜕变与心灵升华的真实故事
中国在国外最火的8位巨星,谁才是第一?成龙榜上有名
狗狗产房必备清单(打造安全舒适的生产环境)
刚出生的小狗喂几毫升奶?新生小狗的奶量如何确定?
为什么喝黑咖啡有助于减脂?
深入探索南京总统府:详解经典游览路线与历史景点
主角光环与昔我晚矣:命运与选择的交织
秦皇岛最新房价状况深度剖析与面临的挑战
浮力式消防员灭火防护服之研究
制作简历的标准
掌握这几招,轻松提高多巴胺,帕金森患者别错过!
90后插画师重现《山海经》神兽风采