STM32的硬件CRC

本文详细介绍STM32的硬件CRC校验功能,包括其32位CRC校验原理及使用方法。通过标准库示例展示CRC计算步骤,并提供与硬件CRC一致的软件实现代码,确保跨平台通信的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

基于STM32F105介绍STM32的硬件CRC和使用方法,并记录软件检验实现。

STM32的CRC介绍


手册中说明STM32的CRC硬件校验使用的是32位CRC校验,多项式为0x04C11DB7;CRC计算时一次性运算32bits,不是按照字节运算;CRC_DR寄存器的复位值为0xFFFFFFFF,即CRC计算的初始值。

STM32的CRC使用

  • STM32的CRC_DR寄存器既作为输入寄存器又作为输出寄存器
  • 作为输入寄存器时直接写入要进行CRC计算的数据
  • 作为输出寄存器时,通过读操作返回上次CRC计算结果
  • 每一次写入数据寄存器的计算结果是前一次计算结果和新计算结果的组合;在新的数据块进行CRC计算之前,需要复位CRC_DR寄存器

以STM32F105的标准库为例,介绍CRC计算的步骤

uint32_t buff[4] = {0x01,0x02,0x03,0x04};
CRC_ResetDR();
CRC_CalcBlockCRC(buff,4);
delay(5);
ret = CRC_GetCRC();

STM32的CRC软件实现

STM32硬件CRC计算出来的结果与常用的CRC32计算出的CRC值不一样,如果通信中用到了STM32的硬件CRC计算值,需要外部实现与硬件CRC一致的计算结果,详细代码如下,提供参考链接

uint32_t crc32_st(uint32_t *pbuf, uint32_t size)
{
	const uint32_t st_const_value = 0x04c11db7;
	uint32_t	crc_value = 0xffffffff;
	uint32_t	xbit;
	uint32_t 	bits;
	uint32_t	i;

	for (i = 0; i < size; i++)
	{
		xbit = 0x80000000;
		for (bits = 0; bits < 32; bits++)
		{
			if (crc_value & 0x80000000)
			{
				crc_value <<= 1;
				crc_value ^= st_const_value;
			}
			else
			{
				crc_value <<= 1;
			}
			if (pbuf[i] & xbit)
			{
				crc_value ^= st_const_value;
			}
			xbit >>= 1;
		}
	}
	return crc_value;
}

总结

其它平台与STM32通信时,如果用到CRC值,可以通过这种软件计算与STM32的CRC保持一致。

### STM32硬件CRC功能概述 STM32微控制器内置了一个专门用于循环冗余校验(CRC)计算的模块,该模块能够显著提高数据传输和存储过程中的可靠性。与传统的软件实现相比,硬件CRC具有更高的效率和更低的CPU负载[^1]。 #### 硬件CRC的特点 STM32硬件CRC的主要特点如下: - **高速性能**:硬件CRC利用专用电路完成计算,无需消耗MCU的核心处理能力,因此速度极快[^2]。 - **灵活性**:尽管硬件CRC提供了快速的计算能力,但在某些情况下可能需要特定配置才能匹配常见的标准算法。 - **易用性**:通过ST官方提供的HAL库函数`HAL_CRC_Calculate()`可以直接调用并获取CRC值,简化了开发者的工作流程[^3]。 以下是基于STM32 HAL库的一个典型CRC计算实例: ```c #include "stm32f1xx_hal.h" // 初始化CRC句柄结构体 CRC_HandleTypeDef hcrc; void MX_CRC_Init(void) { hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; // 默认多项式启用 hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; // 默认初始值启用 hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; // 输入数据反转模式关闭 hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; // 输出数据反转禁用 hal_status = HAL_CRC_Init(&hcrc); } uint32_t Calculate_CRC(uint32_t *data_buffer, uint32_t length) { return HAL_CRC_Calculate(&hcrc, data_buffer, length); // 调用HAL库函数进行CRC计算 } ``` 上述代码展示了如何初始化CRC外设以及执行具体的CRC计算操作。需要注意的是,在实际应用中应根据具体需求调整输入/输出数据反转模式以及其他参数设置。 --- ### 数据流与结果解析 当使用`HAL_CRC_Calculate()`函数时,传入的数据缓冲区会被逐字节送入CRC单元进行累加运算,最终返回一个32位的结果值。如果希望将此数值转换为便于观察的形式,则可以将其拆分为四个8位部分分别存放到一个字符数组里以便后续处理或发送至其他设备显示。 例如下面这段程序片段演示了怎样把得到的CRC值分解成单独字节形式并通过UART接口上传给计算机终端打印出来: ```c uint32_t Data_buffer[5] = {0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005}; uint32_t CRC_Value = 0; uint8_t CRC_Result[4] = {0}; CRC_Value = HAL_CRC_Calculate(&hcrc, (uint32_t*)Data_buffer, 5); CRC_Result[3] = CRC_Value & 0xFF; CRC_Result[2] = (CRC_Value >> 8) & 0xFF; CRC_Result[1] = (CRC_Value >> 16) & 0xFF; CRC_Result[0] = (CRC_Value >> 24) & 0xFF; HAL_UART_Transmit(&huart2, CRC_Result, 4, 500); ``` 这里我们先调用了`HAL_CRC_Calculate()`来获得整个数据块对应的CRC检验码,接着按照低位到高位顺序依次提取每一位放入准备好的临时变量组内最后经由串口传递出去供调试工具捕获分析。 --- ### 配置注意事项 为了确保正确无误地运用好这个强大的特性,有几个方面值得特别留意: - 正确设定逆变选项以适应不同协议的要求; - 如果遇到不一致的情况,请核查当前使用的生成多项式是否符合预期标准; - 对于初次使用者来说建议优先采用默认配置作为起点逐步探索更多可能性. 综上所述,借助STM32自带的硬件支持配合简单直观的应用层API可以让原本复杂耗时的任务变得轻松快捷许多同时也极大提升了系统的整体表现力.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

怦然心动如往昔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值