一、基础知识
要学习CRC我们需要了解CRC校验的相关知识点。
(1)输入数据
输入数据就是我们原本需要发送的数据,也就是不加校验码的数据。
(2)校验码
校验码其实就是除数的余数。例如5 ÷ 2 =2 余1,那么我们发送数据的时候把余数1加上,最后接收者接收数据的时候,把(5+1)与2相除,最后判断是不是结果0,如果结果是0,那么说明发送来的数据正确,如果不是0,就说明出现了数据错误。
(3)真正发送的数据
输入数据+校验码 = 真正发送的数据。用上例说明,正在发送的数据就是 5+1。
(4)多项式
在CRC校验里面,你就可以把多项式理解成除法里面的除数,例如上例的2。
在STM32CRC检验里面,默认的多项式是
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 + 1。
这个东西就是上面的除数。但是我们除的不是这个式子,而是他们的系数。
举个例子:我现在需要发送一串数据:1101011011
多项式是x^4 + x^1 +x^0 = 1*x^4 + 0*x^3 + 0*x^2 + 1*x^1 + 1*x^0
系数是: 10011
求检验码:1101011011 ÷ 10011 的余数为 1110.
这里1110就是校验码。STM32CRC外设,就是在给我们算这个东西的。只是,默认的多项式是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 + 1。所以最后的校验码是32位的。
注意:这里的 '÷' 是指各个位异或 。可能有些人也注意到了,校验码的位数 = 多项式的位数-1。
有的朋友会有个问题:这个多项式我能不能随便写??
我的回答是:不用,有一批专家专门研究了这个多项式,使用这些多项式,能够保证效果最好。都有哪些呢?如下图所示:
(5)多项式的宽度
多项式的宽度 = 位数 - 1。比如上图CRC-8/MAXIM中用到的位宽为8的生成多项式,其实对应得二进制数有九位:100110001。最高位我们都默认为1了,所以不用计算在内。
这样看下去是不是感觉这种方式的CRC校验挺好的???
但是他有一个很明显的缺陷,那就是数据流的开头如果添加一些0。其实是并不影响最后的校验结果的。但是这并不是我想要的效果啊,我就是要先发送一些0,怎么办呢???
为了解决这个问题,引出了两个概念:第一个概念就是“余数初始值”,另一个就是“结果异或值”。
(6)初始值
初始值是算法开始时寄存器(crc)的初始化预置值,十六进制表示。使用初始值就按着上表来设置就行。
(7)结果异或值
计算结果与此参数异或后得到最终的CRC值。使用结果异或值就按着上表来设置就行。
(8)输入反转、输出反转
输入反转就是将输入的数据进行反转一下,例如:101 变为了 010 。
输出反转就是将输出的数据进行反转一下。
正是因为引入了输入反转和输出反转,所以你能在上图中看到CRC-32和CRC-32/MPEG-2这俩种。
STM32F103系列是默认没有输入反转,输出反转的,也就是说用的使用CRC-32/MPEG-2这种。STM32L431是有专门的控制输入反转、输出反转的,也就是说其可以控制使用CRC-32这种。但是默认配置还是CRC-32/MPEG-2。
二、使用CRC外设
STM32的CRC使用非常简单,步骤如下:
1、开启相关时钟
2、复位CRC计算单元CRC->CR 的RESET位
3、将要输入数据,每32位放到CRC->DR寄存器中。直至将所有数据发送完。
4、从CRC->DR寄存器读取校验码(注意是32位的额,因为上面多项式默认使用的是CRC-32/MPED-2的)
可能有的朋友会有疑问?我一直往DR寄存器里面写数据,会不会影响,或者数据被覆盖??
答案:不会的,因为手册有明确说明,在CRC计算期间会暂停CPU的写操作,也就是说在没有计算完毕后,你想写入是写不进去的。因此我们可以对DR寄存器进行连续的读写操作。
还有的朋友可能会有疑问,为什么读和写都在这个寄存器,会不会有影响??
实际不会的,以为我们对该寄存器的读操作时,返回的是上次CRC校验结束的校验码。就类似于余数了,接着我们继续进行写数据,其实就好比“续”上了。
三、验证
在MCU端通过串口打印DR寄存器中的值,也就是校验码。接着使用http://www.ip33.com/crc.html这个网站进行校验验证。注意:因为STM32F103系列只能每次发32位,但是如果你想发送字符。你要注意字符位额。比如我发送一个 int 数组。
uint32_t tmp [2] ={'a','b'};
你再上面网站验证的时候,你要注意 'a' 仅仅是一个字节 ,前面还有3字节的0呢。不要忘了加上这三字节的0。
STM32默认配置使用的是CRC-32/MPED-2模式的,注意选择额
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_52803467/article/details/143046911
|