打印
[应用相关]

STM32CRC校验

[复制链接]
327|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-10-23 09:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、基础知识
        要学习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

使用特权

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

本版积分规则

1855

主题

15449

帖子

11

粉丝