栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【STM32】HAL库-CRC校验

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【STM32】HAL库-CRC校验

CRC

循环冗余校验(CRC)计算单元是根据固定的生成多项式得到任一32位全字的CRC计算结果。

使用CRC-32(以太网)多项式:0x4C11DB7

CRC计算单元含有1个32位数据寄存器:

  • 对该寄存器进行写操作时,作为输入寄存器,可以输入要进行CRC计算的新数据。
  • 对该寄存器进行读操作时,返回上一次CRC计算的结果。

每一次写入数据寄存器,其计算结果是前一次CRC计算结果和新计算结果的组合(对整个32位字进行CRC计算,而不是逐字节地计算)。

在CRC计算期间会暂停CPU的写操作,因此可以对寄存器CRC_DR进行背靠背写入或者连续地写-读操作。

可以通过设置寄存器CRC_CR的RESET位来重置寄存器CRC_DR为0xFFFF FFFF。该操作不影响寄存器CRC_IDR内的数据。

CRC在线计算网站链接
STM32的CRC校验等同于

对STM32的CRC解释

CRC的DR寄存器如下

字节1字节2字节3字节4
XXXXXXXX

假设我们需要发送字符串ABC按照4字节对齐,那么校验的字符串为ABC(0x00),发送与校验的字符串如下

字节1字节2字节3字节4
ABC0x00

并且在写入CRC的DR寄存器前,需要对写入的字进行高低字节转换,先写入高字节即 0x00 最后写入A
也就是unsigned int num = 0x00434241; CRC->DR = num
这样才是对字符串ABC(0x00)进行了CRC校验,否则是对(0x00)CBA进行校验。

CRC校验demo

采用STM32F103C8T6单片机,KeilMDK5.32版本

在串口输出数据之前,对数据进行CRC校验,并将数据进行4字节对齐(因为CRC校验是对字进行校验)

STM32CubeMX配置

主程序代码

串口加CRC函数

extern CRC_HandleTypeDef hcrc;

int USARTPrintfCRCEx(UART_HandleTypeDef *huart, unsigned char *pBuff, char isEnableCRC, const char *format, ...)
{
	int bytes = 0;
	va_list list;

	
	va_start(list, format);
	bytes = vsprintf((void*)pBuff, format, list);
	va_end(list);
	
	if(bytes > USART_SENDBUFF_MAX_BYTES)
	{
		return -1;
	}
	
	if(isEnableCRC && (bytes >= 0))
	{
		
		if(READ_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN))
		{
			uint32_t CRCValue = 0U;
			uint32_t *temp = (void*)pBuff;
			uint8_t mode = bytes % 4;
			
			
			if(mode)
			{
				
				for(int i = bytes; i < bytes + 4 - mode; i++)
				{
					pBuff[i] = 0U;
				}
				bytes += (4 - mode);//增加无效字节的字节数
			}
			
			__HAL_CRC_DR_RESET(&hcrc);
			
			for(int i = 0; i < bytes / 4; i++)
			{
				CRCValue = *temp;//暂存数据,避免破坏源数据
				CRCValue = BytesSwap32(CRCValue);//高低字节转换
				WRITE_REG(hcrc.Instance->DR, CRCValue);
				temp = (void*)&pBuff[(i + 1) * 4];
			}
			CRCValue = READ_REG(hcrc.Instance->DR);//读取 CRC 计算的结果
			
			CRCValue = BytesSwap32(CRCValue);
			
			memcpy(pBuff + bytes, &CRCValue, sizeof(CRCValue));
			bytes += 4;
		}
		else
		{
			return -1;
		}
	}
	
	if(HAL_UART_Transmit_DMA(huart, pBuff, bytes) != HAL_OK)
	{
		return -1;
	}
	return bytes;
}

高低字节转换宏定义

#define BytesSwap16(num) 
			( ((num) & 0xFF00U) >> 8U | 
			  ((num) & 0x00FFU) << 8U )
#define BytesSwap32(num) 
			( ((num) & 0xFF000000U) >> 24U | 
			  ((num) & 0x00FF0000U) >> 8U  | 
			  ((num) & 0x0000FF00U) << 8U  | 
			  ((num) & 0x000000FFU) << 24U )

效果

工程文件下载链接

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/937990.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号