CRC校验原理及CRC-8简单校验函数设计

CRC为循环冗余校验码,是一种常用的、具有检错、纠错能力的校验码。通常发送方在发送的数据之后,附上其CRC校验码。接收方收到数据后,也做同样的CRC校验,得到本地CRC校验码,并和接收到的CRC校验码比较,如果一致,则认为数据无误,如果不一致,则认为发收过程中出错。

CRC校验码是被计算数据和计算码的二进制模二除法的余数。二进制模二除法和二进制常规算法的区别是,模二除法在除法运算过程中采用模二减法,不产生借位,也就是0-1=1,0-0=0,1-1=0,1-0=1;而00-01=01,10-01=11。也就是按位异或的效果。

CRC-8计算方式

以MLX90614测温芯片的CRC-8校验为例,其计算码多项式为X^8 + X^2 + X^1 + 1 ,也就是对应9个二进制位的数据,即100000111,第一位和最后一位都是1,也即0x107。在计算时,对于计算数据要计算到最后一位,因此实际计算时,计算数据要左移8位,再与0x107进行模二除法。

算法方面,要首先对计算数据进行从高位开始的第一个二进制“1”的位置搜索,因为模二除法从这里开始启动。
对于MLX90614读取的温度数据长度为5个字节,左移8位后就是6个字节,可以用64位无符号长整型装载。而9位的计算码可以用16位无符号短整型装载。
在算法计算过程中,要考虑前面一次计算后,余数已小于计算码时,需要给余数从计算数据中进行补位的各种情况,包括余数已为全0而计算还未完成的情况,所以每次补位的长度不一样。这里需要注意,补位是补到余数的后面,而不是和余数直接进行异或,而是补位后的余数再和计算码进行模二减法。
当计算到已无法通过补位继续进行计算的时候,则此余数就是最后的校验码。

CRC-8校验函数

MLX90614读操作的时序如下:
前面5个字节数据的校验码为PEC(第六个字节), 也即设计的校验函数PY_CRC_MLX90614_READ(0xb4, 0x07, 0xd2, 0x3a)计算结果为0x30。注意这里根据MLX90614输入数据特征在函数内部做了处理,输入变量是4个字节,实际对应是5个字节。

校验函数设计如下:

uint8_t PY_CRC_MLX90614_READ(uint8_t daddr, uint8_t Raddr, uint8_t dl, uint8_t dh)
{   //Written by Pegasus Yu 2022/02/22uint64_t cdata = 0; //Computed total datauint16_t data_t = 0; //Process data of CRC computinguint16_t crc_poly = 0x0107; //X^8+X^2+X^1+1 total 9 effective bits. Computed total data shall be compensated 8-bit '0' before CRC computing from 9-1=8.uint16_t index_t = 47;  ///bit shifting index for initial '1' searchinguint16_t index = 47;    //bit shifting index for CRC computinguint8_t rec = 0; //bit number needed to be compensated for next CRC computingcdata |= (((uint64_t)daddr)<<40);       //device write addresscdata |= (((uint64_t)Raddr)<<32);       //register access addresscdata |= (((uint64_t)(daddr+1))<<24);   //device read addresscdata |= (((uint64_t)dl)<<16);          //data LSBcdata |= (((uint64_t)dh)<<8);           //data HSB//8-bit '0' compensated into cdata so cdata involves 48 bits stored in 64-bit format.while(index_t>0){if( (cdata>>index_t)&1 ){index = index_t;index_t = 0;data_t |= (cdata>>(index-8));{data_t = data_t ^ crc_poly;}while((index!=0x5555)&&(index!=0xaaaa)){if ((data_t>>7)&1) rec = 1;else if ((data_t>>6)&1) rec = 2;else if ((data_t>>5)&1) rec = 3;else if ((data_t>>4)&1) rec = 4;else if ((data_t>>3)&1) rec = 5;else if ((data_t>>2)&1) rec = 6;else if ((data_t>>1)&1) rec = 7;else if ((data_t>>0)&1) rec = 8;else rec = 9; ///if((index-8)<rec){data_t = data_t<<(index-8);data_t |=  (uint16_t)((cdata<<(64-(index-8)))>>(64-(index-8)));index = 0x5555;}else{for(uint8_t i=1;i<=rec;i++){data_t = (data_t<<1)|((cdata>>(index-8-i))&1) ;}if(rec!= 9){data_t = data_t ^ crc_poly;index -= rec;}else{data_t = 0;index_t = index-8-1;index = 0xaaaa;}}}if(index==0x5555) break;}else{index_t--;if(index_t<8) break;}}return (uint8_t)data_t;
}

CRC-8长数据校验

如上面的算法原理解释,这里的简单校验函数只支持到7个字节的输入数据校验,如果计算数据太长,则需要进行升级设计,设计上可以按照64位进行分段,当高一段64位计算到尽头时,在下一段64位开始对余数进行位补,以使得模二减法能继续进行下去。直到最后一个64位段计算到尽头,则余数是CRC-8的8位校验码。

而当进行的是CRC-16或CRC-32校验码计算时,依然可升级上述算法进行实现,因为无符号64位宽度能够覆盖16位和32位的模二除法(减法)计算要求。这是本算法相对于其它用8位单字节宽度来分段计算数据的算法的特点。

–End–

CRC校验原理及CRC-8简单校验函数设计相关推荐

  1. 一文详解循环冗余校验校验算法(CRC校验)及C语言代码的实现 ---- 以CRC-16/MODBUS为例讲解

    一.概述 现在的产品开发过程中,无论是数据的储存还是传输,都需要确保数据的准确性,所以就需要在数据帧后面附加一串校验码,方便接收方使用校验码校验接收到的数据是否是正确的. 常用的校验方式有奇偶校验.异 ...

  2. 32位crc校验码程序_CRC码计算及校验原理的最通俗诠释

    CRC校验原理 CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的.其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注 ...

  3. CRC校验原理及STM32 IAP在线升级程序

    CRC校验原理: 什么是CRC校验? CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据 ...

  4. tcp中的crc检验算法原理_CRC校验原理及其实现

    原文作者:王超的独立博客 出处:http://www.wangchaochao.top/2020/09/20/Principle-and-implementation-of-CRC/ 前言 最近的工作 ...

  5. 简单易懂的CRC校验原理阐述

    不要跑,CRC没这么难!(简单易懂的CRC原理阐述) 网上大多的教材都是面向大佬的很多细节原理都没有讲清楚,对于我们这些新萌菜鸟们实在太不友好了.于是我写一篇相对轻松易懂的博客,希望能对学习CRC的朋 ...

  6. CRC校验原理的完整学习

    前言:1.想直接用CRC的可以直接看程序,想了解原理,或者写程序的原理的.可以看按顺序看整篇 2.模二除法没有深入研究,所以模二除法待验证,也不去验证了,我花了一个月的业余时间写.3.本文只进行了16 ...

  7. 【个人学习总结】CRC校验原理及实现

    [个人学习总结]CRC校验原理及实现 一.CRC校验原理[理论篇] 1.硬核视频讲解[重点看,非常非常好!!!] 2.基础文章[略看] 3.深入文章!!![代码.查表法有点看不懂,跨越有点大] 理解重 ...

  8. java 文件crc校验_JavaCRC校验原理

    一.基本原理 CRC检验原理实际上就是在一个p位二进制数据序列之后附加一个r位二进制检验码(序列),从而构成一个总长为n=p+r位的二进制序列:附加在数据序列之后的这个检验码与数据序列的内容之间存在着 ...

  9. 蓝牙:CRC原理详解(附crc16校验代码)

    CRC原理详解(附crc16校验代码) 参考链接: https://www.cnblogs.com/esestt/archive/2007/08/09/848856.html Cyclic Redun ...

最新文章

  1. maven学习(下)利用Profile构建不同环境的部署包
  2. TensorFlow学习笔记之三(神经网络的优化)
  3. python巡检脚本juniper_python实现巡检系统(solaris)示例
  4. Spring框架初写
  5. Win7matlab7.0安装教程,Win7下MATLAB7.0安装教程
  6. 树莓派架设VNC服务
  7. 在线常用正则表达式可视化生成与测试工具与示例 Regular Expression
  8. Delphi Android menu,Delphi菜单组件TMainMenu使用方法详解
  9. 自定义更改虚拟机中Ubuntu的ip地址
  10. 公众号引流进阶教程(公众号对接电影,影视资源)
  11. python 导出到excel ,打开excel有错误,错误的提示为:发现“***”中的部分内容问题,是否让我们尽量尝试修复?如果您信任此工作簿的源,请单击“是”。
  12. KeyError: [] not found in axis_最IN拉花潮改“出圈”,欧拉白猫拓创无限可能_搜狐汽车...
  13. HUAWEI华为MateBook13 2020锐龙版R5集显16G+512GB(HNL-WFQ9)原装出厂系统恢复原厂系统
  14. linux系统配置x11,配置Xorg X11窗口系统
  15. cad隐藏图层命令快捷键_CAD隐藏当前图层和只显示当前图层的快捷键是什么快捷键?...
  16. 回首2019,瞻仰2020
  17. 华为虚拟服务器密码忘记怎么办,手机云服务器密码忘记了
  18. 大数据面试题——数据库
  19. 数据结构:求两个有序列表的交集,并集
  20. 如何一键计算OR值?

热门文章

  1. 51单片机的nop延时延时函数
  2. 亿发软件:中大型仓库进出货管理系统解决方案,定制软件让仓储作业高效便捷
  3. 46家中外知名企业面试题目
  4. JavaScript 教程「1」:与君初相识
  5. 【身份鉴别-身份标识】Linux系统用户及用户组管理
  6. SYS.MON_MODS$、SYS.MON_MODS_ALL$和DBA_TAB_MODIFICATIONS
  7. 微信小程序怎么开发自己的小程序?
  8. 【庖丁解牛】成功解决nginx报错:bind() to 0.0.0.0:8090 failed (13: Permission denied)
  9. Object Detection(目标检测神文)(二)
  10. 爬取虎牙TV全站主播信息