打印
[牛人杂谈]

M451的CRC8数据校验

[复制链接]
997|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
<blockquote>/*



/*-------------------------------------------------------*/
/*                    变量区                             */
/*-------------------------------------------------------*/



/*-------------------------------------------------------*/
/*                    函数区                             */
/*-------------------------------------------------------*/


/****************************************
*函数名称:main
*输    入:无
*输    出:无
*功    能:函数主体
******************************************/
INT32 main(VOID)
{
    const uint8_t acCRCSrcPattern[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
    uint32_t i, u32TargetChecksum = 0x58, u32CalChecksum = 0;
               
                PROTECT_REG
                (
                        /*1.系统时钟初始化 */
                        SYS_Init(PLL_CLOCK);
                        /*2.串口0初始化 */
                        UART0_Init(115200);
       
    )
               
    printf("\n\nCPU @ %d Hz\n", SystemCoreClock);
    printf("+-----------------------------------------+\n");
    printf("|    CRC-8 Polynomial Mode Sample Code    |\n");
    printf("+-----------------------------------------+\n\n");

    printf("# Calculate [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39] CRC-8 checksum value.\n");
    printf("    - Seed value is 0x5A             \n");
    printf("    - CPU write data length is 8-bit \n");
    printf("    - Checksum complement disable    \n");
    printf("    - Checksum reverse disable       \n");
    printf("    - Write data complement disable  \n");
    printf("    - Write data reverse disable     \n");
    printf("    - Checksum should be 0x%X        \n\n", u32TargetChecksum);

    /* Configure CRC controller for CRC-8 CPU mode */
    CRC_Open(CRC_8, 0, 0x5A, CRC_CPU_WDATA_8);

    /* Start to execute CRC-8 CPU operation */
    for(i = 0; i < sizeof(acCRCSrcPattern); i++)
    {
        CRC_WRITE_DATA((acCRCSrcPattern & 0xFF));
    }

    /* Get CRC-8 checksum value */
    u32CalChecksum = CRC_GetChecksum();
    printf("CRC checksum is 0x%X ... %s.\n", u32CalChecksum, (u32CalChecksum == u32TargetChecksum) ? "PASS" : "FAIL");

    /* Disable CRC function */
    CRC->CTL &= ~CRC_CTL_CRCEN_Msk;

    while(1);       
       
}


/*-------------------------------------------------------*/
/*                    中断服务函数                       */
/*-------------------------------------------------------*/




沙发
天灵灵地灵灵|  楼主 | 2016-8-9 23:29 | 只看该作者
CRC(Cyclic Redundancy Check,循环冗余校验)算法出现时间较长,应用也十分
广泛,尤其是通讯领域,现在应用最多的就是 CRC32 算法,它产生一个 4 字节(32 位)的校
验值,一般是以 8 位十六进制数,如 FA 12 CD 45 等。CRC 算法的优点在于简便、速度快,
严格的来说,CRC 更应该被称为数据校验算法,但其功能与数据摘要算法类似,因此也作为测
试的可选算法。
在 WinRAR、WinZIP 等软件中,也是以 CRC32 作为文件校验算法的。一般常见的简单
文件校验(Simple File Verify – SFV)也是以 CRC32 算法为基础,它通过该算法生成
一个后缀名为.SFV 的文本文件,这样可以任何时候可以将文件内容 CRC32 运算的结果
与 .SFV 文件中的值对比来确定此文件的完整性。 与 SFV 相关工具软件有很多, 如 MagicSFV
MooSFV 等。
CRC 最重要的特点是就是检错能力极强,开销小,易于用编码器及检测电路实现。从其检
错能力来看,它所不能发现的错误的几率仅为 0.0047%以下。从性能上和开销上考虑,均远远优于奇偶校验及算术和校验等方式。因
而,在数据存储和数据通讯领域,CRC 无处不在:著名的通讯协议 X.25 的 FCS(帧检错序列)采用的是 CRC-CCITT,ARJ、LHA 等
压缩工具软件采用的是 CRC32,磁盘驱动器的读写采用了 CRC16,通用的图像存储格式 GIF、TIFF 等也都用 CRC 作为检错手段。

使用特权

评论回复
板凳
天灵灵地灵灵|  楼主 | 2016-8-9 23:30 | 只看该作者
基本原理
CRC 校验的基本思想是利用线性编码理论,在发送端根据要传送的 k 位二进制码序列,以一定的规则产生一个校验用的监督码 r
位,并附在信息后边,构成一个新的二进制码序列数共(k+r)位,最后发送出去。在接收端,则根据信息码和 CRC 码之间所遵循的规
则进行检验,以确定传送中是否出错。
16 位的 CRC 码产生的规则是先将要发送的二进制序列数左移 16 位后,再除以一个多项式,最后所得到的余数既是 CRC 码。
假设数据传输过程中需要发送 15 位的二进制信息 g=101001110100001,这串二进制码可表示为代数多项式 g(x) = x^14 +
x^12 + x^9 + x^8 + x^7 + x^5 + 1,其中 g 中第 k 位的值,对应 g(x)中 x^k 的系数。将 g(x)乘以 x^m,即将 g 后加 m 个
0,然后除以 m 阶多项式 h(x),得到的(m-1)阶余项 r(x)对应的二进制码 r 就是 CRC 编码。
h(x)可以自由选择或者使用国际通行标准,一般按照 h(x)的阶数 m,将 CRC 算法称为 CRC-m,比如 CRC-32、CRC-64 等。国
际通行标准可以参看 http://en.wikipedia.org/wiki/Cyclic_redundancy_check
g(x)和 h(x)的除运算,可以通过 g 和 h 做 xor(异或)运算。比如将 11001 与 10101 做 xor 运算如下表 23.1.1。
表 23.1.1 g(x)与 h(x)异或运算结果
  g 1 1 0 0 1
  h 1 0 1 0 1
结果 0 1 1 0 0
明白了 xor 运算法则后,举一个例子使用 CRC-8 算法求 101001110100001 的校验码如下表 23.1.2。CRC-8 标准的 h(x) =
x^8 + x^7 + x^6 + x^4 + x^2 + 1,即 h 是 9 位的二进制串 111010101。
表 23.1.2 CRC-8 校验码的迭代运算过程

使用特权

评论回复
地板
天灵灵地灵灵|  楼主 | 2016-8-9 23:31 | 只看该作者
标准
在国际标准中,根据生成多项式 G(x)的不同,CRC 又可分为以下几种标准:
CRC-8 码: G(x)=x^8+x^5+x^4+1
CRC-16 码: G(x)=x^16+x^15+x^2+1
CRC-CCITT 码: G(x)=x^16+x^12+x^5+1
CRC-32 码: G(x)=x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1

使用特权

评论回复
5
天灵灵地灵灵|  楼主 | 2016-8-9 23:31 | 只看该作者
CRC-12 码通常用来传送 6bit 字符串。CRC-16 及 CRC-CCITT 码则用是来传送 8bit 字符,其中 CRC-16 为美国采用,而
CRC-CCITT 为欧洲国家所采用。CRC-32 码大都被采用在一种称为 Point-to-Point 的同步传输中。下面以最常用的 CRC-16 为例
来说明其生成过程。
CRC-16 码由两个字节构成,在开始时 CRC 寄存器的每一位都预置为 1,然后把 CRC 寄存器与 8-bit 的数据进行异或,之后对
CRC 寄存器从高到低进行移位,在最高位(MSB)的位置补零,而最低位(LSB,移位后已经被移出 CRC 寄存器)如果为 1,则把寄
存器与预定义的多项式码进行异或,如果 LSB 为零,则无需进行异或。重复上述的由高至低的移位 8 次,第一个 8-bit 数据处理完
毕,用此时 CRC 寄存器的值与下一个 8bit 数据异或并进行如前一个数据相同的 8 次移位。所有的字符处理完成后 CRC 寄存器内的值
即为最终的 CRC 值。

使用特权

评论回复
6
天灵灵地灵灵|  楼主 | 2016-8-9 23:32 | 只看该作者
计算过程
1) 设置 CRC 寄存器,并给其赋值 FFFF(hex)。
2) 将数据的第一个 8 位字符与 16 位 CRC 寄存器的低 8 位进行异或,并把结果存入 CRC 寄存器。
3) CRC 寄存器向右移一位,MSB 补零,移出并检查 LSB。
4) 如果 LSB 为 0,重复第三步;若 LSB 为 1,CRC 寄存器与多项式码相异或。
5) 重复第 3 与第 4 步直到 8 次移位全部完成。此时一个 8-bit 数据处理完毕。
6) 重复第 2 至第 5 步直到所有数据全部处理完成。
7) 最终 CRC 寄存器的内容即为 CRC 值。

使用特权

评论回复
7
天灵灵地灵灵|  楼主 | 2016-8-9 23:32 | 只看该作者
计算过程
1) 设置 CRC 寄存器,并给其赋值 FFFF(hex)。
2) 将数据的第一个 8 位字符与 16 位 CRC 寄存器的低 8 位进行异或,并把结果存入 CRC 寄存器。
3) CRC 寄存器向右移一位,MSB 补零,移出并检查 LSB。
4) 如果 LSB 为 0,重复第三步;若 LSB 为 1,CRC 寄存器与多项式码相异或。
5) 重复第 3 与第 4 步直到 8 次移位全部完成。此时一个 8-bit 数据处理完毕。
6) 重复第 2 至第 5 步直到所有数据全部处理完成。
7) 最终 CRC 寄存器的内容即为 CRC 值。

使用特权

评论回复
8
天灵灵地灵灵|  楼主 | 2016-8-9 23:33 | 只看该作者
生成步骤
1) 将 x 的最高幂次为 R 的生成多项式 G(x)转换成对应的 R+1 位二进制数。
2) 将信息码左移 R 位,相当与对应的信息多项式 C(x)*2R。
3) 用生成多项式(二进制数)对信息码做模 2 除法,得到 R 位的余数。
4) 将余数拼到信息码左移后空出的位置,得到完整的 CRC 码

使用特权

评论回复
9
天灵灵地灵灵|  楼主 | 2016-8-9 23:33 | 只看该作者
特点
 支持四个常用的多项式:CRC-CCITT, CRC-8, CRC-16, 和 CRC-32。
 可编程种子值。
 支持对输入数据和 CRC 校验值的可编程的反序设定。
 支持对输入数据和 CRC 校验值的可编程的反码设定。
 支持 8/16/32 位数据宽度。
 8-bit 写模式: 1-AHB 时钟周期操作
 16-bit 写模式: 2-AHB 时钟周期操作
 32-bit 写模式: 4-AHB 时钟周期操作
 支持使用 PDMA 写数据并执行 CRC 操作。

使用特权

评论回复
10
天灵灵地灵灵|  楼主 | 2016-8-9 23:34 | 只看该作者
基本配置
CRC 外围时钟在 CRCCKEN (CLK_AHBCLK[7])中使能。设置 CRC 后,用户可以通过 CRC 控制寄存器开始执行 CRC 运算。
CRC 发生器可以执行带可编程多项式设定的 CRC 运算。多项式操作包括 CRC-CCITT, CRC-8, CRC-16 和 CRC-32;用户可
以通过设置 CRCMODE[1:0](CRC_CTL[31:30] CRC 多项式模式)选择 CRC 多项式操作模式。
CRC 发生器只支持 CPU 模式,下面是一个编程顺序例子:
1) 通过设置 CRCEN (CRC_CTL[0] CRC 通道使能控制)来使能 CRC 发生器。
2) CRC 运算初始化设置
a. 通过设置 CHKSFMT(CRC_CTL[27] 校验值反码)来配置 CRC 校验值反码。
b. 通过设置 CHKSREV(CRC_CTL[25] 校验值位反序)来配置 CRC 校验值位反序。
c. 通过设置 DATFMT (CRC_CTL[26] 写入数据反码)来配置 CRC 写入数据反码。
d. 通过设置 DATREV (CRC_CTL[24] 写入数据位反序)来配置 CRC 写入数据位反序。
3) 通过设置 CRCRST (CRC_CTL[1] CRC 引擎复位)来执行 CRC 复位,CRC 复位将装载初始种子值到 CRC 电路。
4) 写数据到 CRC_DAT 寄存器来计算 CRC 校验值。
5) 通过读 CRC_CHECKSUM 寄存器来获得 CRC 校验结果。

使用特权

评论回复
11
dentsgot| | 2016-8-11 21:43 | 只看该作者
CRC数据校验的原理是什么呢?

使用特权

评论回复
12
598330983| | 2016-8-12 09:16 | 只看该作者
尤其是通讯领域,现在应用最多的就是 CRC32 算法

使用特权

评论回复
13
643757107| | 2016-8-12 23:05 | 只看该作者
CRC-16 及 CRC-CCITT 码则用是来传送 8bit 字符,其中 CRC-16 为美国采用,而CRC-CCITT 为欧洲国家所采用。

使用特权

评论回复
14
hotpower| | 2016-11-20 06:14 | 只看该作者
http://www.21ic.com/tools/HotWC3_V1.22.html

使用特权

评论回复
15
dongnanxibei| | 2016-11-25 19:56 | 只看该作者
CRC的校验在通信上很重要,这样可以确保信息的传递是无误的

使用特权

评论回复
16
天灵灵地灵灵|  楼主 | 2016-11-25 22:44 | 只看该作者
主要用来检测或校验数据传输或者保存后可能出现的错误

使用特权

评论回复
17
huangcunxiake| | 2016-11-26 22:27 | 只看该作者
CRC计算器真牛叉,还可以加密

使用特权

评论回复
18
dongnanxibei| | 2016-11-27 16:43 | 只看该作者
16 位的 CRC 码产生的规则是先将要发送的二进制序列数左移 16 位后,再除以一个多项式,最后所得到的余数既是 CRC 码。

使用特权

评论回复
19
dongnanxibei| | 2016-11-27 16:43 | 只看该作者
可不可以通过哈希值的算法来处理这种校验呢,不是说一个文件对应一个哈希值,那么如果我们发送一个文件后附加上哈希值不就可以验证文件是否正确。

使用特权

评论回复
20
天灵灵地灵灵|  楼主 | 2016-11-29 21:07 | 只看该作者
如果你不会这个,想做好牛叉的通信接口应用很难。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

161

主题

3317

帖子

13

粉丝