<!-- 本文件由脚本自动转换生成，请勿手动编辑 -->

> **《LKS32MC45x User Manual》CRC** . 完整目录见 [README.md](README.md)
>
> **声明**：本文档由芯片用户手册自动转换生成，仅供检索与查阅参考。Markdown 格式可被自由编译、修改，本文档不构成正式技术文件，相关内容以凌鸥创芯官方网站正式发布的手册为准。
>
> 南京凌鸥创芯电子有限公司 . (C) 2020, 版权归凌鸥创芯所有 . 机密文件，未经许可不得扩散

# CRC

## 概述

CRC即[循环冗余校验码](https://baike.baidu.com/item/%E5%BE%AA%E7%8E%AF%E5%86%97%E4%BD%99%E6%A0%A1%E9%AA%8C%E7%A0%81%22%20\t%20%22_blank)（Cyclic
Redundancy
Check）：是数据通信领域中最常用的一种查错校验码，其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查（CRC）是一种数据传输检错功能，对数据进行多项式计算，并将得到的结果附在帧的后面，接收设备也执行类似的算法，以保证数据传输的正确性和完整性。

利用CRC进行检错的过程可简单描述为：在发送端根据要传送的K位二进制码序列，以一定的规则产生一个校验用的R位监督码(CRC码)，附在原始信息后边，构成一个新的二进制码序列数共K+R位，然后发送出去。在接收端，根据信息码和CRC码之间所遵循的规则进行检验，以确定传送中是否出错。这个规则，在差错控制理论中称为“生成多项式”。

## 基本原理

循环冗余校验码（CRC）的基本原理是：在K位信息码后再拼接R位的校验码，整个编码长度为N位，因此，这种编码也叫（N，K）码。对于一个给定的（N，K）码，可以证明存在一个[最高次幂](https://baike.baidu.com/item/%E6%9C%80%E9%AB%98%E6%AC%A1%E5%B9%82%22%20\t%20%22_blank)为N-K=R的多项式G(x)。根据G(x)可以生成K位信息的校验码，而G(x)叫做这个CRC码的生成多项式。校验码的具体生成过程为：假设要发送的信息用多项式C(X)表示，将C(x)左移R位（可表示成C(x)\*2<sup>R</sup>），这样C(x)的右边就会空出R位，这就是校验码的位置。用
C(x)\*2<sup>R</sup> 除以生成多项式G(x)得到的余数就是校验码。

任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。例如：代码1010111对应的[多项式](https://baike.baidu.com/item/%E5%A4%9A%E9%A1%B9%E5%BC%8F%22%20\t%20%22_blank)为x<sup>6</sup>+x<sup>4</sup>+x<sup>2</sup>+x+1，而多项式为x<sup>5</sup>+x<sup>3</sup>+x<sup>2</sup>+x+1对应的代码101111。

## 基本概念

### 对应关系

多项式和二进制数有直接对应关系：X的最高幂次对应二进制数的最高位，以下各位对应多项式的各幂次，有此幂次项对应1，无此幂次项对应0。可以看出：X的最高幂次为R，转换成对应的二进制数有R+1位。

[多项式](https://baike.baidu.com/item/%E5%A4%9A%E9%A1%B9%E5%BC%8F%22%20\t%20%22_blank)包括生成多项式G(X)和信息多项式C(X)。

如生成多项式为G(X)=X<sup>4</sup>+X<sup>3</sup>+X+1，可转换为二进制数码11011。

而发送信息为
101111，可转换为数据多项式为C(X)=X<sup>5</sup>+X<sup>3</sup>+X<sup>2</sup>+X+1。

### 生成多项式

生成多项式是接受方和发送方的一个约定，也就是一个[二进制数](https://baike.baidu.com/item/%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%95%B0%22%20\t%20%22_blank)，在整个传输过程中，这个数始终保持不变。

在发送方，利用生成多项式对信息多项式做模2除生成校验码。在接收方利用生成多项式对收到的编码多项式做模2除检测和确定错误位置。

应满足以下条件：

A、生成多项式的最高位和最低位必须为1。

B、当被传送信息（CRC码）任何一位发生错误时，被生成多项式做除后应该使余数不为0。

C、不同位发生错误时，应该使余数不同。

D、对[余数](https://baike.baidu.com/item/%E4%BD%99%E6%95%B0%22%20\t%20%22_blank)继续做除，应使余数循环。

### 校验码位数

CRC校验码位数 = 生成多项式位数 -
1。注意有些生成多项式的简记式中将生成多项式的最高位1省略了。

### 生成步骤

1、将X的最高次幂为R的生成多项式G(X)转换成对应的R+1位二进制数。

2、将信息码左移R位，相当于对应的信息多项式C(X)\*2<sup>R</sup>。

3、用生成多项式（二进制数）对信息码做除，得到R位的余数(注意：这里的二进制做除法得到的余数其实是模2除法得到的余数，并不等于其对应十进制数做除法得到的余数。)。

4、将余数拼到信息码左移后空出的位置，得到完整的CRC码。

【例】假设使用的生成多项式是G(X)=X3+X+1。4位的原始报文为1010，求编码后的报文。

解：

1、将生成多项式G(X)=X3+X+1转换成对应的二进制除数1011。

2、此题生成多项式有4位（R+1）(注意：4位的生成多项式计算所得的校验码为3位，R为校验码位数)，要把原始报文C(X)左移3（R）位变成1010
000

3、用生成多项式对应的二进制数对左移3位后的原始报文进行模2除（高位对齐），相当于按位异或：

1010000

1011

------------------

0001000

0001011

------------------

0000011

得到的余位011，所以最终编码为：1010 011

POL=0x13，data=0x77

011101110000000

10010011

01111101000000

10010011

0110100100000

10010011

010000010000

10010011

00010001000

10010011

00011011

## 寄存器

CRC模块的寄存器读写需要先打开CRC模块的时钟使能SYS_CLK_CFG.CRC_CLK_EN

### 地址分配

CRC的基地址是0x4001_6800，寄存器列表如下：

表10-1
CRC寄存器列表

||||
|---|---|---|
|名称|偏移地址|说明|
|CRC_DR|0x00|CRC数据（输入信息码/输出编码）寄存器|
|CRC_CR|0x04|CRC控制寄存器|
|CRC_INIT|0x08|CRC初始码寄存器|
|CRC_POL|0x0C|CRC生成多项式对应的二进制码寄存器|

### 寄存器描述

#### CRC_DR CRC 信息码寄存器

地址：0x4001_6800

复位值：0x0

表10-2
CRC数据寄存器CRC_DR

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|
|DR||||||||||||||||
|RW||||||||||||||||
|0||||||||||||||||
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
|DR||||||||||||||||
|RW||||||||||||||||
|0||||||||||||||||

||||
|---|---|---|
|位置|位名称|说明|
|\[31:0\]|DR|存放待编码的信息码和经CRC校验后的编码|

CRC_DR寄存器既用于放入待校验数据，也用于返回校验结果。写入CRC_DR寄存器即触发一次CRC计算。待编码数据应在CR等寄存器配置完成后最后写入，以触发CRC计算开始。

#### CRC_CR CRC 控制寄存器

地址：0x4001_6804

复位值：0x0

表10-3
CRC控制寄存器CRC_CR

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
||||REV_OUT_TYPE|||REV_IN_TYPE||||POLY_SIZE|||||RESET|
||||RW|||RW||||RW|||||WO|
||||0|||0||||0|||||0|

||||
|---|---|---|
|位置|位名称|说明|
|\[31:13\]||未使用|
|\[12\]|REV_OUT_TYPE|是否将CRC校验后的编码反转后输出，即b\[31\]=b\[0\], b\[30\]=b\[1\],… \[b0\]=b\[31\]|
|\[11:10\]||未使用|
|\[9:8\]|REV_IN_TYPE|待编码数据反转类型00:不反转01:按字节反转，即b\[31\]=b\[24\], b\[30\]=b\[25\], …, b\[24\]=b\[31\], …, b\[7\]=b\[0\], b\[6\]=b\[1\], …, b\[0\]=b\[7\]10:按半字（16bit）反转，即b\[31\]=b\[16\], b\[30\]=b\[17\], …, b\[16\]=b\[31\], …, b\[15\]=b\[0\], b\[14\]=b\[1\], …, b\[0\]=b\[15\]11:按字反转，即b\[31\]=b\[0\], b\[30\]=b\[1\],… \[b0\]=b\[31\]|
|\[7:6\]||未使用|
|\[5:4\]|POLY_SIZE|输出编码（多项式）位宽00: 32bits01: 16bits10: 8bits11: 7bits|
|\[3:1\]||未使用|
|\[0\]|RESET|与输入信息码进行CRC计算的数据来源0:来自于上一次的计算结果1:来自于CRC_INIT写入1实现CRC数据重置并自动清零，读回恒为0.|

同时需要注意的是，向CRC_CR.RESET写入1会将CRC_INIT寄存器复位为0xFFFFFFFF。

如果需要清除CRC的计算结果，应向CRC_CR.RESET写入1，否则后续CRC计算会以之前的计算结果为初值进行。

#### CRC_INIT CRC 初始码寄存器

地址：0x4001_6808

复位值：0xFFFFFFFF

表10-4
CRC初始码寄存器CRC_INIT

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|
|INIT||||||||||||||||
|RW||||||||||||||||
|0xFFFFFFFF||||||||||||||||
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
|INIT||||||||||||||||
|RW||||||||||||||||
|0xFFFFFFFF||||||||||||||||

||||
|---|---|---|
|位置|位名称|说明|
|\[31:0\]|INIT|存放初始码|

CRC_DR与CRC_INIT相异或后开始进行CRC校验计算。

#### CRC_POL CRC 生成码寄存器

地址：0x4001_680C

复位值：0x04C11DB7

表10-5
CRC生成码寄存器CRC_POL

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|
|POL||||||||||||||||
|RW||||||||||||||||
|0x04C11DB7||||||||||||||||
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
|POL||||||||||||||||
|RW||||||||||||||||
|0x04C11DB7||||||||||||||||

||||
|---|---|---|
|位置|位名称|说明|
|\[31:0\]|POL|存放生成多项式对应的生成码|

