CRC校验原理及其使用 您所在的位置:网站首页 查表法crc16_x25 CRC校验原理及其使用

CRC校验原理及其使用

#CRC校验原理及其使用| 来源: 网络整理| 查看: 265

目录

何为CRC

为什么需要校验

为什么是CRC

CRC的缺点

目录

何为CRC

为什么需要校验

为什么是CRC

CRC的缺点

如何进行CRC校验

校验标准式是什么玩意?

常见的CRC校验

CRC校验计算过程

CRC校验代码参考

代码解读

生成CRC8校验表的代码

CRC检验网站

如何进行CRC校验

校验标准式是什么玩意?

常见的CRC校验

生成CRC校验的代码

何为CRC

CRC,循环冗余校验码,本质就是一个校验码,用于检测通讯数据是否正确。常见的还有奇偶校验,校验和(所有数据相加)、LRC校验、异或校验、MD5校验等。

为什么需要校验

数据传输过程中,由于其他干扰的存在,有概率会出现数据传输错误的现象。为了识别接收的数据是否正确,我们需要在数据传输完成后增加一个校验数据,接收端按照校验规则计算出(所接收数据的)校验码,与发送端的校验码进行对比,两个校验码不相等说明数据传输出错,反之,通讯正确。

为什么是CRC

数据校验本身没有优略之分,CRC可以很大程度上识别出数据传输。举个不恰当的例子,奇偶校验可能识别出百分之五十的数据传输错误,CRC可能可以识别到百分之九十;检测的成本也比较低(占用的资源相对少),从性价比上来看,CRC是个很好的校验法。

CRC的缺点

循环冗余校验法检验不出来的错的情况:收到的位串虽然是错误的,但是恰巧能被生成多项式整除,这个时候检测不出来

如何进行CRC校验

在了解了CRC是什么之后,还需要了解怎么做。

CRC校验的逻辑是将需要校验的数据与校验标准式进行异或运算,也就是模2除法。不懂什么叫模2除法根本没关系,只要理解什么叫异或运算就可以了。

校验标准式是什么玩意?

本质就是一个用于异或的值。这个东西的存在的意义就是规范接收端与发送端的异或值。理论上,式子越复杂,通讯错误的识别率就越高。下面的表格就是常见的CRC校验标准式,摘自链接

 有没有被标准式的复杂给震慑住?不用怕,它们就是纸老虎,看懂后,你会发现它们连纸老虎都不如。

式子中x的次方只是标位数,后面的计算根本就不需要考虑。

比如  x^{4}+x^{1}+1  对应的异或值就是 0001 0011 也就是0x13;

x^{4}是第四位,x^{1}是第一位,1就是第零位

再看一个

x^{5}+x^{3}+1,对应的异或值就是 0010 1001 也就是0x29;

x^{5}是第五位,x^{3}是第三位,1就是第零位

看完两个例子,懂得怎么将标准式转换出异或值就行,这个标准式就是为了得到异或值,没有其他的用处了,是不是很简单。

注:要注意的一点就是,需要根据CRC校验位数对异或值进行取低位,舍高位。

比如 x^{8}+x^{5}+x^{4}+1  ,对应的异或值是1 0011 0001,也就是0x131,但我们用的是CRC8的话,只需要取低八位,也就是0x31就行;

常见的CRC校验

常见的CRC校验有CRC8,CRC16,CRC32,其中CRC8与CRC16用于通讯在嵌入式行业比较常用。

目前我就掌握了CRC8的使用,我看到CRC16,CRC32是只取低8位进行计算,原理上可能也差不多吧。

CRC校验计算过程

摘自计算过程

计算过程就是进行异或运算,首先先对数据进行补0处理(CRC8补8位),然后与标准式进行异或计算。

具体计算过程了解一下就行,写程序又不用你来手算,了解原理就好。

CRC校验代码参考

代码取自 原代码地址

#include "crcLib.h" /****************************************************************************** * Name: CRC-4/ITU x4+x+1 * Poly: 0x03 * Init: 0x00 * Refin: True * Refout: True * Xorout: 0x00 * Note: *****************************************************************************/ uint8_t crc4_itu(uint8_t *data, uint16_t length) { uint8_t i; uint8_t crc = 0; // Initial value while(length--) { crc ^= *data++; // crc ^= *data; data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0x0C;// 0x0C = (reverse 0x03)>>(8-4) else crc = (crc >> 1); } } return crc; } /****************************************************************************** * Name: CRC-5/EPC x5+x3+1 * Poly: 0x09 * Init: 0x09 * Refin: False * Refout: False * Xorout: 0x00 * Note: *****************************************************************************/ uint8_t crc5_epc(uint8_t *data, uint16_t length) { uint8_t i; uint8_t crc = 0x48; // Initial value: 0x48 = 0x09> 1); } } return crc; } /****************************************************************************** * Name: CRC-5/USB x5+x2+1 * Poly: 0x05 * Init: 0x1F * Refin: True * Refout: True * Xorout: 0x1F * Note: *****************************************************************************/ uint8_t crc5_usb(uint8_t *data, uint16_t length) { uint8_t i; uint8_t crc = 0x1F; // Initial value while(length--) { crc ^= *data++; // crc ^= *data; data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0x14;// 0x14 = (reverse 0x05)>>(8-5) else crc = (crc >> 1); } } return crc ^ 0x1F; } /****************************************************************************** * Name: CRC-6/ITU x6+x+1 * Poly: 0x03 * Init: 0x00 * Refin: True * Refout: True * Xorout: 0x00 * Note: *****************************************************************************/ uint8_t crc6_itu(uint8_t *data, uint16_t length) { uint8_t i; uint8_t crc = 0; // Initial value while(length--) { crc ^= *data++; // crc ^= *data; data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0x30;// 0x30 = (reverse 0x03)>>(8-6) else crc = (crc >> 1); } } return crc; } /****************************************************************************** * Name: CRC-7/MMC x7+x3+1 * Poly: 0x09 * Init: 0x00 * Refin: False * Refout: False * Xorout: 0x00 * Use: MultiMediaCard,SD,ect. *****************************************************************************/ uint8_t crc7_mmc(uint8_t *data, uint16_t length) { uint8_t i; uint8_t crc = 0; // Initial value while(length--) { crc ^= *data++; // crc ^= *data; data++; for ( i = 0; i < 8; i++ ) { if ( crc & 0x80 ) crc = (crc


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有