STM32F7 硬件CRC校验驱动,支持CRC7,CRC8,CRC16,CRC32

本来想实现32bit写入,一次进行4字节校验,结果测试过程中发现兼容性不好,最后放弃了,统一使用字节模式写入。

已经实现了硬件的CRC7,CRC8,CRC16,CRC32运算,并且均进行了测试对比,计算结果完全正确,通过配置可以实现不同的CRC校验,我已经实现了如下的配置:

//////////////////////////////////////////////////////////////////////////////////////////////////////
//常见的CRC校验配置
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC32;					//默认的CRC-32校验 
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC32_MPEG2;				//CRC-32/MPEG-2校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_XMODEM;				//CRC-16/XMODEM校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_MODBUS;				//CRC-16/MODBUS校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_USB;				//CRC-16/USB校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_IBM;				//CRC-16/IBM校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8;						//CRC-8
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8_MAXIM;				//CRC-8/MAXIM校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8_ROHC;				//CRC-8/ROHC校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8_ITU;					//CRC-8/ITU校验 
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC7_MMC;					//CRC-7/MMC校验
//////////////////////////////////////////////////////////////////////////////////////////////////////

如果有别的可以从这个网站获取并测试:http://www.ip33.com/crc.html

配置项结构如下:

//STM32F7 CRC配置
typedef struct
{
	CRC_POLY_SIZE	Size;		//多项式宽度
	u32				Poly;		//多项式
	u32				Init;		//初始值
	u32				XOROUT;		//结果异或值
	bool 			isREFIN;	//输入数据反转
	bool			isREFOUT;	//输出数据反转
}STM32F7_CRC_Config;

例子:

//默认的CRC-32校验-比如以太网
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC32 = 
{
	CRC_POLY_CRC32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, TRUE, TRUE
};

//CRC-32/MPEG-2校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC32_MPEG2 = 
{
	CRC_POLY_CRC32, 0x04C11DB7, 0xFFFFFFFF, 0x00000000, FALSE, FALSE
};

//CRC-16/XMODEM校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_XMODEM = 
{
	CRC_POLY_CRC16, 0x1021, 0x0000, 0x0000, FALSE, FALSE
};

//完整代码,代码中使能CRC的时钟函数我就不给出了,自己去实现,一行代码而已。

/*************************************************************************************************************
 * 文件名			:	STM32F7_CRC.c
 * 功能				:	STM32F7 硬件CRC32驱动
 * 作者				:	[email protected]
 * 创建时间			:	2020-02-08
 * 最后修改时间		:	2020-02-08
 * 详细:			:	支持硬件CRC7,CRC8,CRC16,CRC32,并准备了一些常用的配置,也可以自己去修改配置实现一些其他的CRC校验方式
						虽然支持32bit写入,但是兼容性不够强,所有的同一使用8bit写入
						重入支持:需要自己实现信号量,并调用接口对信号量申请与释放进行初始化
*************************************************************************************************************/
#include "system.h"
#include "STM32F7_CRC32.h"

//输出结果异或值
static u32 sg_CRC_XOROUT;		
static const STM32F7_CRC_Config *csg_pCRC_Config = NULL;								//记录全局的配置
//当直接写入数据到CRC_DR寄存器,均会被识别为32bit写入,通过不同长度的指针,可以让CRC知道写入的到底是8位,16位还是32位,如果开启了输入翻转,翻转的长度要同步设置
static vu8  *sg_pCRC_DR8	 =	(vu8 *)(&CRC->DR);										//BYTE 校验时,写入的DR指针
//static vu16 *sg_pCRC_DR16	 =	(vu16 *)(&CRC->DR);										//WORD 校验时,写入的DR指针
//static vu32 *sg_pCRC_DR32	 =	(vu32 *)(&CRC->DR);										//DWORD 校验时,写入的DR指针
//信号量函数
static void (*sg_pCRC_MutexPen)(void) = NULL;											//申请信号量接口,默认为空,不进行信号量申请
static void (*sg_pCRC_MutexPost)(void) = NULL;											//释放信号量接口,默认为空,不进行信号量释放

//////////////////////////////////////////////////////////////////////////////////////////////////////
//常见的CRC校验配置
//默认的CRC-32校验-比如以太网
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC32 = 
{
	CRC_POLY_CRC32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, TRUE, TRUE
};

//CRC-32/MPEG-2校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC32_MPEG2 = 
{
	CRC_POLY_CRC32, 0x04C11DB7, 0xFFFFFFFF, 0x00000000, FALSE, FALSE
};

//CRC-16/XMODEM校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_XMODEM = 
{
	CRC_POLY_CRC16, 0x1021, 0x0000, 0x0000, FALSE, FALSE
};

//CRC-16/MODBUS校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_MODBUS = 
{
	CRC_POLY_CRC16, 0x8005, 0xFFFF, 0x0000, TRUE, TRUE
};

//CRC-16/USB校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_USB = 
{
	CRC_POLY_CRC16, 0x8005, 0xFFFF, 0xFFFF, TRUE, TRUE
};

//CRC-16/IBM校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_IBM = 
{
	CRC_POLY_CRC16, 0x8005, 0x0000, 0x0000, TRUE, TRUE
};

//CRC-8
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8 = 
{
	CRC_POLY_CRC8, 0x07, 0x00, 0x00, FALSE, FALSE
};

//CRC-8/MAXIM校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8_MAXIM = 
{
	CRC_POLY_CRC8, 0x31, 0x00, 0x00, TRUE, TRUE
};

//CRC-8/ROHC校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8_ROHC = 
{
	CRC_POLY_CRC8, 0x07, 0xFF, 0x00, TRUE, TRUE
};

//CRC-8/ITU校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8_ITU = 
{
	CRC_POLY_CRC8, 0x07, 0x00, 0x55, FALSE, FALSE
};

//CRC-7/MMC校验
const STM32F7_CRC_Config cg_CRC_CONFIG_CRC7_MMC = 
{
	CRC_POLY_CRC7, 0x09, 0x00, 0x00, FALSE, FALSE
};
//////////////////////////////////////////////////////////////////////////////////////////////////////

__inline void STM32F7_CRC_SetInitValue(u32 Value) {CRC->INIT = Value;}			//设置CRC的初始值(STM32F7_CRC_Start()会设置默认初始值为:0xFFFFFFFF)
__inline void STM32F7_CRC_Reset(void) {CRC->CR |= (1<<0);}						//CRC复位,两次计算之间需要复位一次CRC
__inline u32 STM32F7_CRC_GetInitValue(void) {return CRC->INIT;}					//获取CRC的初始值
__inline void STM32F7_CRC_SetPolyValue(u32 Value) {CRC->POL = Value;}			//设置CRC的多项式
__inline u32 STM32F7_CRC_GetPolyValue(void) {return CRC->POL;}					//获取CRC的多项式值
void STM32F7_CRC_Start(const STM32F7_CRC_Config *pConfig);						//STM32F7 CRC32开始(复位)
void STM32F7_CRC_SetREFIN(STM32F7_CRC_REFIN REFIN);								//STM32F7 CRC设置输入字节反转
u32 STM32F7_CRC32(u8 * pBuff, u32 len);											//STM32F7 CRC32计算
u16 STM32F7_CRC16(u8 * pBuff, u32 len);											//STM32F7 CRC16计算
u8 STM32F7_CRC8(u8 * pBuff, u32 len);											//STM32F7 CRC8计算
__inline u8 STM32F7_CRC7(u8 * pBuff, u32 len) {return STM32F7_CRC8(pBuff, len);}//STM32F7 CRC7计算

/*************************************************************************************************************************
* 函数			:	void STM32F7_CRC_Start(const STM32F7_CRC_Config *pConfig)
* 功能			:	STM32F7 CRC32开始(复位并设置)
* 参数			:	pConfig:多项式配置
* 返回			:	无
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2020-02-08
* 最后修改时间	:	2020-02-08
* 说明			: 	对CRC时钟进行使能,并复CRC位寄存器
*************************************************************************************************************************/
void STM32F7_CRC_Start(const STM32F7_CRC_Config *pConfig)
{
	u32 temp;
	
	csg_pCRC_Config = pConfig;									//记录全局配置
	SYS_DeviceClockEnable(DEV_CRC,TRUE);						//初始化CRC32时钟
	CRC->CR |= 1<<0;											//先复位
	temp = (pConfig->Size & 0x3) << 3;							//设置多项式长度
	if(pConfig->isREFOUT)										//反转输出数据
	{
		temp |= 1 << 7;
	}
	if(pConfig->isREFIN)										//反转输入数据
	{
		temp |= 0x1 << 5;										//强制使用按字节执行位反转
		/*switch(pConfig->Size)
		{
			case CRC_POLY_CRC32	:	//32位多项式,CRC32
			{
				temp |= 0x3 << 5;								//按字执行位反转
			}break;
			case CRC_POLY_CRC16	:	//16位多项式,CRC16
			{
				temp |= 0x2 << 5;								//按半字执行位反转
			}break;
			default:				//8/7位多项式,CRC8,CRC7
			{
				temp |= 0x1 << 5;								//按字节执行位反转
			}break;
		}*/
	}
	STM32F7_CRC_SetPolyValue(pConfig->Poly);					//设置多项式
	STM32F7_CRC_SetInitValue(pConfig->Init);					//设置多项式初值
	temp |= (1<<0); 											//复位CRC寄存器
	CRC->CR = temp;												//设置并复位CRC
	sg_CRC_XOROUT = pConfig->XOROUT;							//记录输出结果异或值
}



/*************************************************************************************************************************
* 函数			:	void STM32F7_CRC_SetREFIN(STM32F7_CRC_REFIN REFIN)
* 功能			:	STM32F7 CRC设置输入字节反转
* 参数			:	REFIN:反转设置值,见STM32F7_CRC_REFIN
* 返回			:	无
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2020-02-08
* 最后修改时间	:	2020-02-08
* 说明			: 	会根据初始化时是否开启了输入反转进行设置,如果没有配置输入反转,将不会进行任何设置
					此设置会影响到校验结果,比如输入的是u32,就必须设置为字,要与校验输入值对应
*************************************************************************************************************************/
void STM32F7_CRC_SetREFIN(STM32F7_CRC_REFIN REFIN)
{
	u32 temp = CRC->CR;
	
	if(csg_pCRC_Config->isREFIN == FALSE) return;	//不需要设置输入反转
	temp &= ~(1<<0);			//不能复位
	temp &= ~(3<<5);			//清除之前的反转设置
	temp |= (REFIN & 0x3) << 5;	//重新设置
	
	CRC->CR = temp;				//写入配置
}


/*************************************************************************************************************************
* 函数			:	void STM32F7_CRC_Disable(void)
* 功能			:	STM32F7 CRC32结束(关闭时钟,降低功耗)
* 参数			:	无
* 返回			:	无
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2015-08-29
* 最后修改时间	:	2018-03-09
* 说明			: 	校验完成,关闭时钟
*************************************************************************************************************************/
void STM32F7_CRC_Disable(void)
{
	csg_pCRC_Config = NULL;						//crc关闭后,配置变为无效
	SYS_DeviceClockEnable(DEV_CRC,FALSE);		//关闭CRC32时钟
}

//这个函数是废弃的,只是当时想做这个尝试,暂时留着
/*************************************************************************************************************************
* 函数			:	u32 STM32F7_CRC32(u8 * pBuff, u32 len)
* 功能			:	STM32F7 CRC32计算
* 参数			:	pBuff:8位数组;len:数据长度
* 返回			:	CRC32结果
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2020-02-08
* 最后修改时间	:	2020-02-08
* 说明			: 	建议pBuff是4字节对齐模式,这样可以直接进行32bit校验,效率会高一些,如果不是4字节对齐,会自动按照字节模式处理
					如果长度不是4的整数倍,余下的1-3字节会自动进行字节模式的校验
					计算完成后会自动进行复位,下次可以直接调用
					直接使用4字节模式处理,测试发现无论怎么偏移,STM32F7内存访问均没问题,完全不需要4字节对齐
					本来想使用4字节对齐模式,测试CRC32/MPEG-2模式时发现只能使用字节模式输入,不能一次写入32位,否则与其他软件计算结果不一致,只能放弃掉了
*************************************************************************************************************************/
/*u32 STM32F7_CRC32(u8 * pBuff, u32 len)
{
	u32 i;
	u32 offset = 0;
	u32 *pU32;						//32位模式下的指针
	u32 temp;
	u32 IntCount;					//4字节模式下的数据条数
	u8 RemCount;					//长度非4字节的数据条数,可以是1-3字节
	*/
	/*temp = (u32)pBuff;
	//测试发现无论是否4字节对齐了,STM32F7均不会出现访问异常,如果你遇到了地址对齐访问异常,可以把以下注释的代码启用即可
	if((temp & 0x3) || len < 4)		//地址没有进行4字节对齐,或长度不足4字节
	{
		uart_printf("警告:STM32F7_CRC32输入地址没有进行4字节对齐或长度不足4字节,将会按照字节模式处理!\r\n");
		STM32F7_CRC_SetREFIN(CRC_REFIN_BYTE);						//STM32F7 CRC设置输入字节反转
		for(i = 0;i < len;i ++)
		{
			*sg_pCRC_DR8 = pBuff[i];								//按照字节进行CRC32运算
		}
	}		
	else*/				//地址是4字节对齐的
	/*{
		pU32 = (u32 *)pBuff;
		//uart_printf("提示:STM32F7_CRC32输入地址是4字节对齐的!\r\n");
		IntCount = len/4;	//计算有多少个4字节对齐的数据
		offset = IntCount * 4;
		RemCount = len % 4;//不足4字节的数据长度
		STM32F7_CRC_SetREFIN(CRC_REFIN_DWORD);						//STM32F7 CRC设置输入字反转
		//先处理4字节对齐的数据
		for(i = 0;i < IntCount;i ++)
		{
			*sg_pCRC_DR32 = pU32[i];								//按照字进行CRC32运算
		}
		if(RemCount)	//有余数
		{
			STM32F7_CRC_SetREFIN(CRC_REFIN_BYTE);					//STM32F7 CRC设置输入字节反转
			for(i = 0;i < RemCount;i ++)
			{
				*sg_pCRC_DR8 = pBuff[offset];						//按照字节进行CRC32运算
				offset ++;
			}
		}
	}
	temp = CRC->DR;
	temp ^= sg_CRC_XOROUT;											//结果异或
	STM32F7_CRC_Reset();											//计算完成,复位CRC	
	
	return temp;
}*/



/*************************************************************************************************************************
* 函数			:	u32 STM32F7_CRC32(u8 * pBuff, u32 len)
* 功能			:	STM32F7 CRC32计算
* 参数			:	pBuff:8位数组;len:数据长度
* 返回			:	CRC32结果
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2020-02-08
* 最后修改时间	:	2020-02-08
* 说明			: 	只使用字节模式输入数据,全局的输入数据反转必须设置为字节反转
*************************************************************************************************************************/
u32 STM32F7_CRC32(u8 * pBuff, u32 len)
{
	u32 temp;
	
	while(len --)
	{
		*sg_pCRC_DR8 = *pBuff++;
	}
	temp = CRC->DR;
	temp ^= sg_CRC_XOROUT;											//结果异或
	STM32F7_CRC_Reset();											//计算完成,复位CRC	
	
	return temp;
}

/*************************************************************************************************************************
* 函数			:	u16 STM32F7_CRC16(u8 * pBuff, u32 len)
* 功能			:	STM32F7 CRC16计算
* 参数			:	pBuff:8位数组;len:数据长度
* 返回			:	CRC32结果
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2020-02-08
* 最后修改时间	:	2020-02-08
* 说明			: 	只使用字节模式输入数据,全局的输入数据反转必须设置为字节反转
*************************************************************************************************************************/
u16 STM32F7_CRC16(u8 * pBuff, u32 len)
{
	u16 temp;
	
	while(len --)
	{
		*sg_pCRC_DR8 = *pBuff++;
	}
	temp = CRC->DR;
	temp ^= sg_CRC_XOROUT;											//结果异或
	STM32F7_CRC_Reset();											//计算完成,复位CRC	
	
	return temp;
}



/*************************************************************************************************************************
* 函数			:	u8 STM32F7_CRC8(u8 * pBuff, u32 len)
* 功能			:	STM32F7 CRC8计算
* 参数			:	pBuff:8位数组;len:数据长度
* 返回			:	CRC32结果
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2020-02-08
* 最后修改时间	:	2020-02-08
* 说明			: 	只使用字节模式输入数据,全局的输入数据反转必须设置为字节反转
*************************************************************************************************************************/
u8 STM32F7_CRC8(u8 * pBuff, u32 len)
{
	u8 temp;
	
	while(len --)
	{
		*sg_pCRC_DR8 = *pBuff++;
	}
	temp = CRC->DR;
	temp ^= sg_CRC_XOROUT;											//结果异或
	STM32F7_CRC_Reset();											//计算完成,复位CRC	
	
	return temp;
}


/*************************************************************************************************************************
* 函数			:	u32 STM32F7_CRCxx(const STM32F7_CRC_Config *pConfig, u8 * pBuff, u32 len)
* 功能			:	STM32F7 进行一次CRC校验
* 参数			:	pConfig:校验方式配置;pBuff:8位数组;len:数据长度
* 返回			:	CRC结果
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2020-02-08
* 最后修改时间	:	2020-02-08
* 说明			: 	可以进行CRC32,CRC16,CRC8,CRC7运算,会自动进行时钟使能与初始化,直接调用即可
					可以申请信号量,避免一次过程被打断
*************************************************************************************************************************/
u32 STM32F7_CRCxx(const STM32F7_CRC_Config *pConfig, u8 * pBuff, u32 len)
{
	u32 temp;
	//建议在此处申请信号量,防止重入冲突
	if(sg_pCRC_MutexPen != NULL) sg_pCRC_MutexPen();		//申请信号量-需要自己实现,并进行初始化
	
	if(csg_pCRC_Config != pConfig)	//配置发生了变化或CRC被关闭了
	{
		uart_printf("CRC配置发生了更新,需要重新配置!\r\n");
		STM32F7_CRC_Start(pConfig);	//重新配置,并启动CRC
	}
	switch(pConfig->Size)
	{
		case CRC_POLY_CRC32	:	//32位多项式,CRC32
		{
			temp = STM32F7_CRC32(pBuff, len);
		}break;
		case CRC_POLY_CRC16	:	//16位多项式,CRC16
		{
			temp = STM32F7_CRC16(pBuff, len);
		}break;
		case CRC_POLY_CRC8:		//8位多项式,CRC8
		{
			temp = STM32F7_CRC8(pBuff, len);
		}
		default:				//7位多项式,CRC7
		{
			temp = STM32F7_CRC7(pBuff, len);
		}break;
	}
	//释放掉申请的信号量
	if(sg_pCRC_MutexPost != NULL) sg_pCRC_MutexPost();		//释放信号量-需要自己实现,并进行初始化
	
	return temp;
}

/*************************************************************************************************************************
* 函数			:	u32 STM32F7_CRC_MutexPen_Hook(void (*pMutexPen)(void))
* 功能			:	STM32F7 CRC所需的申请信号量接口注册
* 参数			:	pMutexPen:申请信号量实现函数接口
* 返回			:	CRC结果
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2020-02-08
* 最后修改时间	:	2020-02-08
* 说明			: 	用于防止重入冲突,必须与STM32F7_CRC_MutexPen_Hook()成对初始化
*************************************************************************************************************************/
u32 STM32F7_CRC_MutexPen_Hook(void (*pMutexPen)(void))
{
	sg_pCRC_MutexPen = pMutexPen;		//申请信号量接口定义
}


/*************************************************************************************************************************
* 函数			:	u32 STM32F7_CRC_MutexPost_Hook(void (*pMutexPost)(void))
* 功能			:	STM32F7 CRC所需的释放信号量接口注册
* 参数			:	pMutexPost:释放信号量实现函数接口
* 返回			:	CRC结果
* 依赖			:	底层IO
* 作者			:	[email protected]
* 时间			:	2020-02-08
* 最后修改时间	:	2020-02-08
* 说明			: 	用于防止重入冲突,必须与STM32F7_CRC_MutexPen_Hook()成对初始化
*************************************************************************************************************************/
u32 STM32F7_CRC_MutexPost_Hook(void (*pMutexPen)(void))
{
	sg_pCRC_MutexPost = pMutexPen;		//释放信号量接口定义
}

//头文件

/*************************************************************************************************************
 * 文件名			:	STM32F7_CRC.H
 * 功能				:	STM32F7 硬件CRC32驱动
 * 作者				:	[email protected]
 * 创建时间			:	2020-02-08
 * 最后修改时间		:	2020-02-08
 * 详细:			:	
*************************************************************************************************************/
#ifndef _STM32F7_CRC_H_
#define _STM32F7_CRC_H_
#include "SYSTEM.H"

//CRC多项式大小
typedef enum 
{
	CRC_POLY_CRC32	=	0,	//32位多项式,CRC32
	CRC_POLY_CRC16	=	1,	//16位多项式,CRC16
	CRC_POLY_CRC8	=	2,	//8位多项式,CRC8
	CRC_POLY_CRC7	=	3,	//7位多项式,CRC7
}CRC_POLY_SIZE;


//STM32F7 CRC配置
typedef struct
{
	CRC_POLY_SIZE	Size;		//多项式宽度
	u32				Poly;		//多项式
	u32				Init;		//初始值
	u32				XOROUT;		//结果异或值
	bool 			isREFIN;	//输入数据反转
	bool			isREFOUT;	//输出数据反转
}STM32F7_CRC_Config;



//STM32F7的输入数据反转设置
typedef enum
{
	CRC_REFIN_NONE	=	0,	//不反转
	CRC_REFIN_BYTE	=	1,	//按字节反转
	CRC_REFIN_WORD	=	2,	//按半字反转
	CRC_REFIN_DWORD	=	3,	//按字反转
}STM32F7_CRC_REFIN;

//////////////////////////////////////////////////////////////////////////////////////////////////////
//常见的CRC校验配置
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC32;					//默认的CRC-32校验 
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC32_MPEG2;				//CRC-32/MPEG-2校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_XMODEM;				//CRC-16/XMODEM校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_MODBUS;				//CRC-16/MODBUS校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_USB;				//CRC-16/USB校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC16_IBM;				//CRC-16/IBM校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8;						//CRC-8
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8_MAXIM;				//CRC-8/MAXIM校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8_ROHC;				//CRC-8/ROHC校验
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC8_ITU;					//CRC-8/ITU校验 
extern const STM32F7_CRC_Config cg_CRC_CONFIG_CRC7_MMC;					//CRC-7/MMC校验
//////////////////////////////////////////////////////////////////////////////////////////////////////


u32 STM32F7_CRCxx(const STM32F7_CRC_Config *pConfig, u8 * pBuff, u32 len);	//STM32F7 进行一次CRC校验
void STM32F7_CRC_Disable(void);												//STM32F4 CRC32禁用(关闭时钟,降低功耗)

//如果需要重入支持,可以注册以下2个接口,当然你也可以自己在应用中去实现
u32 STM32F7_CRC_MutexPen_Hook(void (*pMutexPen)(void));					//STM32F7 CRC所需的申请信号量接口注册
u32 STM32F7_CRC_MutexPost_Hook(void (*pMutexPen)(void));				//STM32F7 CRC所需的释放信号量接口注册

#endif //_STM32F7_CRC_H_

//测试代码

//硬件CRC计算
	{		
		u8 buff[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xEF, 0XFF};
		
		uart_printf("\r\n\r\n\r\n");
		uart_printf("开始STM32F7 CRC校验测试... \r\n");
		
		
		uart_printf("CRC32:0x%lX \r\n", STM32F7_CRCxx(&cg_CRC_CONFIG_CRC32, buff, sizeof(buff)));
		uart_printf("CRC32:0x%lX \r\n", STM32F7_CRCxx(&cg_CRC_CONFIG_CRC32, buff, sizeof(buff)-1));		//测试连续转换
		uart_printf("CRC16:0x%lX \r\n", STM32F7_CRCxx(&cg_CRC_CONFIG_CRC16_MODBUS, buff, sizeof(buff)));
		uart_printf("CRC16:0x%lX \r\n", STM32F7_CRCxx(&cg_CRC_CONFIG_CRC16_MODBUS, buff, sizeof(buff)-1));
		uart_printf("CRC8:0x%lX \r\n", STM32F7_CRCxx(&cg_CRC_CONFIG_CRC8, buff, sizeof(buff)));
		uart_printf("CRC8:0x%lX \r\n", STM32F7_CRCxx(&cg_CRC_CONFIG_CRC8, buff, sizeof(buff)-1));
		STM32F7_CRC_Disable();	//测试一下关闭后,是否依旧可以自动启动
		uart_printf("CRC7:0x%lX \r\n", STM32F7_CRCxx(&cg_CRC_CONFIG_CRC7_MMC, buff, sizeof(buff)));
		uart_printf("CRC7:0x%lX \r\n", STM32F7_CRCxx(&cg_CRC_CONFIG_CRC7_MMC, buff, sizeof(buff)-1));
		
		OSTimeDlyHMSM(1,0,0,0);
	}

测试结果,自己可以使用上面提供的网站进行对比,我都测试过

发布了143 篇原创文章 · 获赞 370 · 访问量 81万+

猜你喜欢

转载自blog.csdn.net/cp1300/article/details/104224619
今日推荐