前言
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
一、modbus(RTU) CRC-16计算
以下为OMRON温控表通信协议中对modbus(RTU) 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次转换为7FFF
第2次转换为9FFE
第3次转换为4FFF
第4次转换为87FE
第5次转换为43FF
第6次转换为81FE
第7次转换为40FF
第8次转换为807E
第1个字节转换结束
第1次转换为E03F
第2次转换为D01E
第3次转换为680F
第4次转换为9406
第5次转换为4A03
第6次转换为8500
第7次转换为4280
第8次转换为2140
第2个字节转换结束
第1次转换为10A2
第2次转换为0851
第3次转换为A429
第4次转换为F215
第5次转换为D90B
第6次转换为CC84
第7次转换为6642
第8次转换为3321
第3个字节转换结束
第1次转换为B991
第2次转换为FCC9
第3次转换为DE65
第4次转换为CF33
第5次转换为C798
第6次转换为63CC
第7次转换为31E6
第8次转换为18F3
第4个字节转换结束
第1次转换为AC78
第2次转换为563C
第3次转换为2B1E
第4次转换为158F
第5次转换为AAC6
第6次转换为5563
第7次转换为8AB0
第8次转换为4558
第5个字节转换结束
第1次转换为82AC
第2次转换为4156
第3次转换为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在线计算,验证计算结果: