C语言CRC-32 STM32格式校验函数

22 篇文章 5 订阅

C语言CRC-32 STM32格式校验函数

CRC-32校验产生4个字节长度的数据校验码,通过计算得到的校验码和获得的校验码比较,用于验证获得的数据的正确性。基本的CRC-32校验算法实现,参考: C语言标准CRC-32校验函数

不同厂家通过对输入数据前处理和输出数据后处理的方式不同,又产生了不同的厂家校验函数,这里介绍STM32硬件CRC对应格式的CRC-32校验函数。STM32格式对输入数据,只有预置值为0XFFFF(当做最初的余数)的前处理。但STM32硬件CRC计算函数需要输入值为32位数组/指针,所以对应的软件CRC实现也需要保证输入数据长度是4字节/32位的倍数。

生成多项式为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

由于反向算法更适合于有输入字节倒位序和输出整体数据倒位序的情况,这里只介绍正向算法。实际上,STM32的CRC计算规则基本上与CRC-32 MPEG-2格式校验函数一样,只在每个32位数据内部的字节序顺序不同,所以把CRC-32 MPEG-2格式校验函数介绍的算法中采用32位输入数据的校验函数修改即可得到STM32的CRC-32校验函数。

CRC-32 MPEG-2格式校验函数为:
在这里插入图片描述
相对而言,CRC-32 MPEG-2格式校验函数里做了32位数据内部的字节倒序。而STM32格式校验函数里不做32位数据内部字节倒序。

正向算法

正向算法是符合标准CRC-32的计算理论,从左向右计算,也即计算过程中移位时,向左移出。算法的实现如下:

CRC-32 STM32格式校验函数(32位输入数据格式):

uint32_t PY_CRC_32_T32_STM32(uint32_t *di, uint32_t len)
{
	uint32_t crc_poly = 0x04C11DB7;  //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 total 32 effective bits without X^32.
	//uint32_t data_t = 0; //CRC register
	uint32_t data_t = 0xffffffff; //CRC register

    for(uint32_t i = 0; i < len; i++)
    {
    	data_t ^= di[i]; //32-bit data

        for (uint8_t j = 0; j < 32; j++)
        {
            if (data_t & 0x80000000)
            	data_t = (data_t << 1) ^ crc_poly;
            else
            	data_t <<= 1;
        }
    }
    return (data_t);
}

STM32硬件CRC校验

这里以STM32CUBEIDE环境,STM32F401CCU6芯片为例介绍硬件CRC的计算。

首先建立基本工程并配置时钟:
在这里插入图片描述
在这里插入图片描述
打开硬件CRC功能模块:
在这里插入图片描述
保存并生成基本工程:
在这里插入图片描述
在代码里调用硬件CRC-32计算函数即可,其定义为:

/**
  * @brief  Compute the 32-bit CRC value of a 32-bit data buffer
  *         starting with hcrc->Instance->INIT as initialization value.
  * @param  hcrc CRC handle
  * @param  pBuffer pointer to the input data buffer.
  * @param  BufferLength input data buffer length (number of uint32_t words).
  * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
  */
uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
{
  uint32_t index;      /* CRC input data buffer index */
  uint32_t temp = 0U;  /* CRC output (read from hcrc->Instance->DR register) */

  /* Change CRC peripheral state */
  hcrc->State = HAL_CRC_STATE_BUSY;

  /* Reset CRC Calculation Unit (hcrc->Instance->INIT is
  *  written in hcrc->Instance->DR) */
  __HAL_CRC_DR_RESET(hcrc);

  /* Enter 32-bit input data to the CRC calculator */
  for (index = 0U; index < BufferLength; index++)
  {
    hcrc->Instance->DR = pBuffer[index];
  }
  temp = hcrc->Instance->DR;

  /* Change CRC peripheral state */
  hcrc->State = HAL_CRC_STATE_READY;

  /* Return the CRC computed value */
  return temp;
}

STM32硬件和软件CRC计算效果

通过如下代码定义即可比较硬件CRC和软件CRC计算结果:

uint32_t crc32_rst1 = 0;
uint32_t crc32_rst2 = 0;
crc32_rst1 = HAL_CRC_Calculate(&hcrc, "C-R-C-32", strlen("C-R-C-32")/4);
crc32_rst2 = PY_CRC_32_T32_STM32("C-R-C-32", strlen("C-R-C-32")/4);```

打开STM32CUBEIDE的“”现场表达式功能:
在这里插入图片描述
在这里插入图片描述
并在现场表达式里加入两个变量名crc32_rst1和crc32_rst2.
编译下载并debug代码,在现场表达式里即可看到硬件CRC和软件CRC的计算值相同:
在这里插入图片描述

STM32可配置硬件CRC

一部分STM32芯片如STM32H743支持硬件CRC格式配置,在默认配置下,即和不能配置的硬件CRC格式相同:
在这里插入图片描述

可以根据需要配置和默认CRC校验格式不同的CRC校验格式:

可设置校验多项式,不限于CRC-32
在这里插入图片描述
可设置计算初始值
在这里插入图片描述
可设置输入数据反序
在这里插入图片描述
可设置输出数据反序
在这里插入图片描述
可设置输入数据基本宽度
在这里插入图片描述

对应的软件CRC算法可以从基本原理的CRC校验函数修改实现:
C语言标准CRC-8校验函数
C语言标准CRC-16校验函数
C语言标准CRC-32校验函数

–End-

STM32F030是ST公司生产的一款基于ARM Cortex-M0核心的微控制器,其中CRC(循环冗余校验)模块可以用来计算数据块的CRC校验码。在使用STM32F030的CRC模块计算CRC16时,需要配置CRC模块的相关参数和操作流程,以下是一个基本的配置流程: 1. 配置CRC时钟:确保CRC模块的时钟已经使能。通常情况下,CRC模块的时钟是通过RCC的APB1总线时钟使能的。 2. 初始化CRC数据:CRC模块可以配置多项式、初始值以及输入数据的反转模式等。对于CRC16,多项式通常是`0xA001`,初始值可以设为`0xFFFF`,输入数据不反转。 3. 启动CRC计算:将要计算的数据送入CRC数据寄存器,然后读取CRC结果寄存器得到计算后的CRC值。 以下是伪代码的示例: ```c RCC->AHBENR |= RCC_AHBENR_CRCEN; // 使能CRC时钟 CRC->CR = 0; // 清除之前的配置 CRC->POL = CRC_POL_16BIT; // 设置为16位CRC CRC->INIT = 0xFFFF; // 设置初始值为0xFFFF CRC->CRCR = CRC_POL_16BIT; // 多项式选择,对于CRC16通常是0xA001,但是由于多项式已经固定在硬件中,这里不需要设置 CRC->CR |= CRC_CR_RESET; // 重置CRC计算 // 写入要计算的数据 for (int i = 0; i < data_length; i++) { CRC->DR = data[i]; // 将数据放入DR寄存器进行计算 } uint16_t crc_result = CRC->DR; // 读取计算后的CRC值 ``` 注意:在实际使用时,应根据STM32F030的参考手册和库函数来配置CRC模块,确保操作的准确性和安全性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PegasusYu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值