1、引言
(1). CRC寄存器初始值为 0xFFFF;即16个字节全为1。
(2). CRC-16 / ModBus的模型为:X16+X15+X2+1,由于16进制数只能0~15位,所以舍去X16位,最后得出:0x8005H(1000 0000 0000 0101 B)。
(3). 通过把 0x8005H 的 “ 高位 ” 与 “ 低位 ” 进行互换,得到最终的多项式:0xA001H(1010 0000 0000 0001 B)。
2、计算步骤
(1). 预置 16 位寄存器为十六进制 0xFFFF(即全为 1) ,称此寄存器为 CRC 寄存器;
(2). 把第一个 8 位数据与 16 位 CRC 寄存器的低位相异或,把结果放于 CRC 寄存器;
(3). 检测相异或后的CRC寄存器的最低位,若最低位为1,CRC寄存器先右移1位,再与多项式A001H进行异或;若为0,则CRC寄存器右移1位,无需与多项式进行异或。
(4). 重复步骤 3 ,直到右移 8 次,这样整个 8 位数据全部进行了处理;
(5). 重复步骤 2 到步骤 4,进行下一个 8 位数据的处理;
(6). 最后得到的 CRC 寄存器即为 CRC 校验码。
附参考:
数据(16进制):01 03 61 00 00 02 CRC校验:F7 DB
3、代码的实现
/*
* 函数名 :CRC16
* 描述 : 计算CRC16
* 输入 : puchMsg---数据地址,usDataLen---数据长度
* 输出 : 校验值
*/
uint16_t CRC16_MudBus(uint8_t *puchMsg, uint8_t usDataLen){
uint16_t uCRC = 0xffff;//CRC寄存器
for(uint8_t num=0;num<usDataLen;num++){
uCRC = (*puchMsg++)^uCRC;//把数据与16位的CRC寄存器的低8位相异或,结果存放于CRC寄存器。
for(uint8_t x=0;x<8;x++){ //循环8次
if(uCRC&0x0001){ //判断最低位为:“1”
uCRC = uCRC>>1; //先右移
uCRC = uCRC^0xA001; //再与0xA001异或
}else{ //判断最低位为:“0”
uCRC = uCRC>>1; //右移
}
}
}
return uCRC;//返回CRC校验值
}
int main(void) {
uint8_t x[]={0x01 ,0x03 ,0x61 ,0x00 ,0x00 ,0x02};
while(1){
uint16_t wCRC_16 = CRC16_MudBus(x,sizeof(x)); //获取CRC16校验值
//输出校验值wCRC_16 即可(注意:CRC16-->低位在前,高位在后)
}
}
4、在线CRC校验网址
(1)链接
网址: http://www.ip33.com/crc.html.
附参考:
数据(16进制):01 03 61 00 00 02 CRC校验:F7 DB
结束语
尊重原创->原文链接:https://blog.youkuaiyun.com/qq_26043945/article/details/123566360
发表此篇文章的目的:防止收藏的资料原版被删除或失去权限查看不了,方便编写程序时快速找到我想要的资料。