modbus(RTU) CRC-16计算过程


前言

CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。


一、modbus(RTU) CRC-16计算

以下为OMRON温控表通信协议中对modbus(RTU) CRC-16计算步骤的说明。
需要注意的是:CRC-16计算范围不包括最后两位CRC-16位;CRC-16高位在后,低位在前。

CRC-16计算

二、使用步骤

1.代码演示

代码如下:

#include <stdio.h>

u16 Get_Modbus_Crc_16(u8 *buffer, u16 len)
{
	u16 calcrc = 0XFFFF;//(1)16位CRC寄存器赋初始值
	u8  temp;
	u16  i = 0, j = 0;//计数
	for (i = 0; i < len; i++)//(6)除最后两位CRC位,其余每个字节数据都需要计算
	{
		temp = *buffer & 0XFF;
		buffer++;
		calcrc = calcrc ^ temp;//(2)将八位数据与CRC寄存器亦或,数据存入CRC寄存器
		for (j = 0; j < 8; j++)//(5)每字节的8位数据都需计算
		{
			if (calcrc & 0X0001)//判断即将右移出的位是不是1,如果是1则与0XA001进行异或。
			{
				calcrc = calcrc >> 1;//(3)先将数据右移一位
				calcrc = calcrc ^ 0XA001;//(4)数据与0XA001进行异或
			}
			else
			{
				calcrc = calcrc >> 1;(3)(4)//如果是0,直接移出
			}
      printf("第%d次转换为%04X\n",j+1,calcrc);
		}
    printf("第%d个字节转换结束\n",i+1);
	}
	u8  CRC_L;
	u8  CRC_H;
	CRC_L = calcrc & 0xFF;//CRC的低八位
	CRC_H = calcrc >> 8;//CRC的高八位
	return ((CRC_L << 8) | CRC_H);//(7)返回CRC最终值,低位在左,高位在右
}

int main () 
{
	u8  buffer[7]={0x01,0x03,0x04,0x00,0x00,0x03,0xE8} ;//CRC-16计算范围(除最后两位CRC校验位)数据举例
    u16 crc = 0;
    crc = Get_Modbus_Crc_16(buffer,7);

    printf("最终结果为:%X",crc);
}

2.计算结果

每次计算结果如下:

1次转换为7FFF2次转换为9FFE
第3次转换为4FFF4次转换为87FE
第5次转换为43FF6次转换为81FE
第7次转换为40FF8次转换为807E
第1个字节转换结束
第1次转换为E03F
第2次转换为D01E
第3次转换为680F4次转换为94065次转换为4A03
第6次转换为85007次转换为42808次转换为21402个字节转换结束
第1次转换为10A2
第2次转换为08513次转换为A429
第4次转换为F215
第5次转换为D90B
第6次转换为CC84
第7次转换为66428次转换为33213个字节转换结束
第1次转换为B991
第2次转换为FCC9
第3次转换为DE65
第4次转换为CF33
第5次转换为C798
第6次转换为63CC
第7次转换为31E68次转换为18F34个字节转换结束
第1次转换为AC78
第2次转换为563C
第3次转换为2B1E
第4次转换为158F5次转换为AAC6
第6次转换为55637次转换为8AB0
第8次转换为45585个字节转换结束
第1次转换为82AC
第2次转换为41563次转换为20AB
第4次转换为B054
第5次转换为582A
第6次转换为2C15
第7次转换为B60B
第8次转换为FB04
第6个字节转换结束
第1次转换为7DF6
第2次转换为3EFB
第3次转换为BF7C
第4次转换为5FBE
第5次转换为2FDF
第6次转换为B7EE
第7次转换为5BF7
第8次转换为8DFA
第7个字节转换结束
最终结果为:FA8D

可以百度CRC在线计算,验证计算结果:

Modbus协议有多种校验方式,常用的有两种:CRC校验和LRC校验。 1. CRC校验 CRC校验是采用循环冗余校验的方式,可以检测数据传输过程中的错误。Modbus协议中使用的是16CRC校验,计算方式如下: 首先,将传输数据按照8位一组进行分组,并将每组数据看作16位的二进制数。然后,将每组数据与上一个16位的CRC校验值进行异或运算,得到一个新的16位的结果。最后,将所有分组的结果再次进行异或运算,得到最终的16CRC校验值。 以下是一个Python实现的CRC校验函数: ```python def calculate_crc(data): crc = 0xFFFF for i in range(len(data)): crc ^= data[i] for j in range(8): if (crc & 0x0001): crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc ``` 2. LRC校验 LRC校验是采用纵向冗余校验的方式,可以检测传输数据中的一些简单错误。Modbus协议中使用的是8位LRC校验,计算方式如下: 首先,将传输数据中的每个字节相加,得到一个8位的结果。然后,将这个结果取反(按位取反),得到最终的8位LRC校验值。 以下是一个Python实现的LRC校验函数: ```python def calculate_lrc(data): lrc = 0 for i in range(len(data)): lrc += data[i] lrc = (~lrc) & 0xFF return lrc ``` 注意:在使用Modbus协议进行通信时,需要根据具体情况选择适当的校验方式。同时,在计算校验值时,需要考虑传输数据的字节顺序(大端序或小端序)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值