当前位置:   article > 正文

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

crc校验函数

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/22

	uint64_t cdata = 0; //Computed total data
	uint16_t data_t = 0; //Process data of CRC computing
	uint16_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' searching
	uint16_t index = 47;    //bit shifting index for CRC computing

	uint8_t rec = 0; //bit number needed to be compensated for next CRC computing

	cdata |= (((uint64_t)daddr)<<40);       //device write address
	cdata |= (((uint64_t)Raddr)<<32);       //register access address
	cdata |= (((uint64_t)(daddr+1))<<24);   //device read address
	cdata |= (((uint64_t)dl)<<16);          //data LSB
	cdata |= (((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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

CRC-8长数据校验

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

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

–End–

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/931957
推荐阅读
相关标签
  

闽ICP备14008679号