yangneet 发表于 2022-1-21 14:58:40

modbus crc16校验码的算法

   转自另一个大神给写的,非常简洁,我也测试非常OK,如果换成其它校验,可以更改下初始值和多项式。(下面代码的初始值0xffff 即10进制的65535,多项式为0xA001即10进制的40961。把它贴到这里,方便大家查找使用。


先写下一般算法原理:
  (1)、预置1个16位的寄存器值0xFFFF,称此寄存器为CRC寄存器;
  (2)、把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低
  8位相异或,把结果放于CRC寄存器,高八位数据不变;
  (3)、把CRC寄存器的内容右移一位(朝高位)用0填补最高位,并检查右移后的移出位;
  (4)、如果移出位为0:重复第3步(再次右移一位);如果移出位为1,CRC寄存器与一多
  项式(A001)进行异或;
  (5)、重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
  (6)、重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
  (7)、将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低
  字节进行交换;
  (8)、最后得到的CRC寄存器内容即为:CRC码。下面是E4A的源码:过程 到八位无符号(传址 数据 为 整数型)
      如果 数据 < 0 则
                数据 = 数据 + 256
      结束 如果
结束 过程

函数 ModBUS_CRC16(data 为 字节型()) 为 整数型
      变量 crc 为 整数型,i 为 整数型,x 为 整数型,数据 为 整数型
      crc = 65535 'CRC初始值 其它CRC可更改成对应的
      判断循环首 x < 取数组成员数(data)
                数据 = data(x)
                到八位无符号(数据) '最主要的是这句 必须转成无符号
                crc = crc 异或 数据
                i = 0
                判断循环首 i < 8
                        如果 (crc 且 1) 则
                              crc = crc \ 2 '无符号右移1位
                              crc = crc 异或 40961 '0xA001其它CRC可更改成对应的
                        否则
                              crc = crc \ 2 '无符号右移1位
                        结束 如果
                        i = i + 1
                判断循环尾
                x = x + 1
      判断循环尾
      ModBUS_CRC16 = crc
结束 函数

cxycxycxy 发表于 2022-2-5 13:28:06

这个厉害!

wyc666 发表于 2022-2-14 22:59:02

{:4_86:}{:4_86:}

wyc666 发表于 2022-2-14 22:59:57

明晨-紫月QQ:2240973822
欢迎加入安卓开发交流群:691958084

pq9999 发表于 2022-7-23 08:09:59

告诉对方就是根据施工技术犯规

恒泰源 发表于 2022-11-5 08:42:52

正瞌睡来个枕头

AAA111 发表于 2023-2-11 08:37:47

这个做出来后要进行高低字节交换,不交换一般不识别
页: [1]
查看完整版本: modbus crc16校验码的算法