8位循环冗余检验CRC校验说明
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第一部分
//===========================CRC-8 原理说明================================== //CRC(Cyclic Redundancy Check) :是数据通信领域中最常用的一种差错校验码, //其特征是信息字段和校验字段的长度可以任意选定。 //CRC 校验可以简单地描述为:例如我们要发送一些数据(信息字段) , //为了避免一些干扰以及 在接收端的对读取的数据进行判断是否接受的是真实的数据, //这时我们就要加上校验数据(即 CRC 校验码) ,来判断接收的数据是否正确。 //在发送端,根据要传送的 k 位二进制码序列,以一定的规则(CRC 校验有不同的规则。 //这个规则, 在差错控制理论中称为"生成多项式"。 ) 产生一个校验用的 r 位校验码(CRC 码), //附在原始信息后边,构成一个新的二进制码序列数共 k+r 位,然后发送出去。在接收端, //根据信息码和 CRC 码之间所遵循的规则 (即与发送时生成 CRC 校验码相同的规则) 进行检 验, //校验采用计算机的模二除法,即除数和被除数(即生成多项式)做异或运算, //进行异或运算时除数和被除数最高位对齐,进行按位异或运算,若最终的数据能被除尽, //则传输正确;否则,传输错误。 //CRC-8 即 最 终 生 成 的 CRC 校 验 码 为 1 字 节 , 其 生 成 多 项 式 , 生 成 多 项 式 为 g(x)=x^8+x^5+x^4+x^0, //相当于 g(x)=1·x^8+0·x^7+0·x^6+1·x^5+1·x^4+0·x^3+0·x^2+0·x^1+1·x^0, //即对应的二进制数为 100110001。 //=============================CRC-8 校验算法======================= //a.信息字段代码为: m(x) = 0x0102 = x^8+x^1 = 1 0000,0010 //b.多项式为:g(x) =x^8+x^5+x^4+x^0= 0x0131 = 100110001 //高位对齐: 1 0000,0010 0000,0000 //注:0x0102<<8 (m(x)左移 8 位) 100110001 //^ g(x)^m(x) 做模二运算,最终的余数就是所要的 CRC8 校验码 -----------------------------------------//(其二进制数的位数一定比生成多项式 g(x)的位数小) 000110011 00000000 100110001 // ^ 高位为 1 对齐 ------------------------------------------------------------01010100100000 100110001 // ^ -------------------------------------------------------------
/****************************************************************************** ** 软件名称:CRC 算法说明 ** 功能描述: 最近看的 CRC-8 资料,分享如下 ** 公司名称: ROBAM ** 作 者:顾长超 ** 芯 片: ** 日 期: 2017-8-1 ** 修改日期: ******************************************************************************/
第二部分
//==============================SHT3X 规格书验证==============================
// 代码如下:
static u8t SHT3X_CalcCrc(u8t data[], u8t nbrOfBytes) { u8t bit; // bit mask u8t crc = 0xFF; // calculated checksum u8t byteCtr; // byte counter // calculates 8-Bit checksum with given polynomial for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++) { crc ^= (data[byteCtr]); for(bit = 8; bit > 0; --bit) { if(crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL; // 保证高位为 1 对齐 else crc = (crc << 1);
HSB^0X0C = 0X0C^0XEF = 1110,0011 // 再进行运算: 1110,0011,0000,0000 //0x0c^0xef = 1110,0011 1001,1000,1 // ^ ------------------------------------------------------------0111,1011,1000,0000 100,1100,01 // ^ ------------------------------------------------------------011,0111,1100,0000 10,0110,001 // ^ ------------------------------------------------------------01,0001,1110,0000 1,0011,0001 // ^ ------------------------------------------------------------0,0010,1111,0000 10,0110,001 // ^ ------------------------------------------------------------00,1001,0010 = 0x92
} } return crc; } // 算法如下: //m(x) = 0xBEEF = HSB-LSB=0XEF+0XEF //g(x) = 0x0131 = 100110001 HSB=0XBE HSB^0XFF = 0X41 = 0100,0001 0100,0001,0000,0000 //------> 0x41<<8 (m(x)左移 8 位) ^ 100,1100,01 ------------------------------------------------------------000,1101,0100,0000 , 1001,1000,1 // ^ ------------------------------------------------------------0100,1100,1000 100,1100,01 // ^ ------------------------------------------------------------000,0000,1100 = 0X0C
0011000110000 100110001 // ^ ------------------------------------------------------------01011110100 100110001 // ^ ------------------------------------------------------------0010010110 //最后生成的只有 8 位就是所要的 CRC8 校验码,前面的 0 不算,以 1 为准 = 10010110= 0x96
// 结果: HSB LSB -->CRC 符合 SHT3X 规格书里面的:Examples CRC (0xBEEF) = 0x92
第三部分
//====================逆序 CRC 信息单元编码算法============================ //===================低位 LSB 对齐 CRC-8 原理说明=========================== //首先需要明确 CRC-8 常见的表格数据中是按照先传输 LSB, //并通过右移寄存器来判断的,因此每次要判断的就是寄存器的最低位 LSB。 //同时要将多项式 x^8+x^5+x^4+x^0(也就是 0x131(0011 0001)), //按位颠倒后得到的 0x8c(1000 1100)来在计算过程中做异或运算 //(为什么 0x131 中的第一个 1 没有被颠倒?! 答:因为它是隐藏的。)-->网上说法!。 //注:其实最低位也是被颠倒了,1000 1100 (1) -(只是程序软件算法需要,把最低位省略了) //m(x) =0x01 作为示例来进行计算说明: //在程序运算中,要求被算的 CRC 变量最低位为 1 时,需要>>1 ,(右移一位), // 也就是和多项式(翻转之后的为 1000 1100 1)的最低位 X^8 的 1 对齐, // 0X01>>1= 0000 0000 1 // 和 1000 1100 1(多项式(翻转之后的)异或为: 0000 0000 (1) ^ ^ 1000 1100 (1) -----------------------------------------1000 1100 (0) // 可以看出最低位都是 1,异或结果也固定都是 0, // 所以,程序里面简化运算,直接把最低位为 1 移出去,不再对最低位进行运算。 // 程序软件算法: for(bit = 8;bit > 0;bit--) { if(crc & 0x01) // 最低位为 1,则右移一位,和 POLY 进行异或运算. crc = (crc >> 1)^POLY; //POLY=0X8C= 1000 1100 (1) 注: (1)-最低位省略 0X8C else crc = crc >> 1; } ------------------------------------------------------------//具体步骤如下: //-判断 crc 最低位是否为 1,如果为 1,先将 crc 右移一位, //-然后 多项式(0x8c)进行异或运算,结果保存在 crc 中。 //-如果最低位为 0,则将 crc 右移一位 //-直到 crc 中的 8 位数据全部从右移出 ------------------------------------------------------------//m(x) = 0x01 = 0000 0001 //g(x) = 1000 1100 1
0000,0000,0000,0001 // 左边加 8 个 0,变成 16 位 ^ 1,0001,1001// 低位对齐:(注:前面的 CRC 算法是高位对齐,注意区别) ------------------------------------------------------------0000,0001,0001,1000 1000,1100,1 // ^ ------------------------------------------------------------0000,1001,1101,0 1,0001,1001 // ^ ------------------------------------------------------------0001,1000,0100 100,0110,01 // ^ ------------------------------------------------------------0101,1110,00 // 最低位为 0 的,直接右移出去 = 0101,1110 = 0x5e // 所以,0X01 的 CRC-8 运算结果为: 0x5e,与 0X5E = CRC8Table[0X01] 一致。 ---ຫໍສະໝຸດ Baidu---------------------------------------------------------