STM32的硬件CRC32使用

发布者:自在自由最新更新时间:2017-02-07 来源: eefocus关键字:STM32  硬件CRC32 手机看文章 扫描二维码
随时随地手机看文章

最近用到STM32的CRC32模块,看一下官网的Lib,感觉用起来十分简单.但是,你会发现直接使用起来会出现,与很多在线CRC32的网站或者PC端的CRC32校验工具计算结果不一致!

简直就是无语......

搜索了一下,在21IC的论坛上面有关使用STM32的CRC32的大讨论,不过是09年的帖子.主要定论是STM32的CRC32与目前大多数的PC端软件使用的一些数据顺序及方法不一致.这里主要推荐看一下这个链接: STM32内置CRC模块的使用 讨论的很火.

如果真如,那帖子说的那样.那么作为MCU这端,是有必要进行转换,要适应潮流.当然这里不是说ST不好.

按照帖子的结论:

1、每个字节的位序相反。stm32f是按32位,高位在先。而主流实例每字节里面是从低位起的。
2、结果出来后,主流实例与0xffffffff异或了。而stm32f没有。

那么我们可以大概贴出以下代码.

  1.  /******************************************************************************* 

  2. * Function Name  : CRC32_ForWords 

  3. * Description    :输入的是32bit buffer的指针及长度 

  4. * Input          :  

  5. * Output         :  

  6. * Return         :  

  7. * 说明           : 

  8. *******************************************************************************/  

  9. u32 CRC32_ForWords(u32 *pData,u32 uLen)  

  10. {  

  11.     u32 i = 0,uData = 0;  

  12.     if((RCC->AHB1ENR & RCC_CRC_BIT) == 0)  

  13.     {  

  14.         RCC->AHB1ENR |= RCC_CRC_BIT;  

  15.     }  

  16.   

  17.     /* Reset CRC generator */  

  18.     CRC->CR = CRC_CR_RESET;  

  19.     for (i = 0;i < uLen;i++)  

  20.     {  

  21. #ifdef USED_BIG_ENDIAN        

  22.         uData = __REV(*(pData + i));  

  23. #else  

  24.         uData = *(pData + i);  

  25. #endif        

  26.         CRC->DR = revbit(uData);  

  27.     }  

  28.     return revbit(CRC->DR)^0xFFFFFFFF;  

  29. }  

说明:__REV()函数功能是将数据按指节大小反向取 ,如原来的数据为0x41424344,经过这个函数之后变成0x44434241


其中,数据反向的代码(由于是GCC编译器所以不知道为什么不支持)别人的代码:

  1. crc_16_32 revbit(crc_16_32 data)  

  2. {  

  3.   asm("rbit r0,r0");  

  4.   return data;  

  5. };  


自己修改的代码如下:

  1. /******************************************************************************* 

  2. * Function Name  : revbit 

  3. * Description    :对入参uData 按位倒序。如:0111-->1110 

  4. * Input          : uData:被转的数据 

  5. * Output         : None 

  6. * Return         : 转换好的数据 

  7. *******************************************************************************/  

  8. u32 revbit(u32 uData)  

  9.  {  

  10.    u32 uRevData = 0,uIndex = 0;  

  11.    uRevData |= ((uData >> uIndex) & 0x01);  

  12.    for(uIndex = 1;uIndex < 32;uIndex++)  

  13.    {  

  14.     uRevData <<= 1;  

  15.     uRevData |= ((uData >> uIndex) & 0x01);  

  16.    }  

  17.    return uRevData;  

  18.  }  


经过测试,确认能得到与PC端的代码一致的结果.


那接着又有问题了,那如果我传入的buffer非4字节对其能否使用STM32 CRC32能.

当然,答案是肯定的.但是需要软件配合.这里直接推荐一下,我的代码参考的帖子: 实现非4字节对其的CRC32方法

我的代码如下:


  1. #define CRC32_POLYNOMIAL                        ((uint32_t)0xEDB88320)  

  2. #define RCC_CRC_BIT                             ((uint32_t)0x00001000)  

  3.   

  4. //#define   USED_BIG_ENDIAN  

  5.   

  6. /*================================================================== 

  7. * Function  : CRC32_ForBytes 

  8. * Description   : CRC32输入为8bits buffer的指针及长度 

  9. * Input Para    :  

  10. * Output Para   :  

  11. * Return Value:  

  12. ==================================================================*/  

  13. u32 CRC32_ForBytes(u8 *pData,u32 uLen)  

  14. {  

  15.     u32 uIndex= 0,uData = 0,i;  

  16.     uIndex = uLen >> 2;  

  17.       

  18.     if((RCC->AHB1ENR & RCC_CRC_BIT) == 0)  

  19.     {  

  20.         RCC->AHB1ENR |= RCC_CRC_BIT;  

  21.     }  

  22.   

  23.     /* Reset CRC generator */  

  24.     CRC->CR = CRC_CR_RESET;  

  25.         

  26.     while(uIndex--)  

  27.     {  

  28. #ifdef USED_BIG_ENDIAN    

  29.         uData = __REV((u32*)pData);  

  30. #else  

  31.         memcpy((u8*)&uData,pData,4);  

  32. #endif        

  33.         pData += 4;  

  34.         uData = revbit(uData);  

  35.         CRC->DR = uData;  

  36.     }  

  37.     uData = revbit(CRC->DR);  

  38.     uIndex = uLen & 0x03;  

  39.     while(uIndex--)  

  40.     {  

  41.         uData ^= (u32)*pData++;  

  42.         for(i = 0;i < 8;i++)  

  43.           if (uData & 0x1)  

  44.             uData = (uData >> 1) ^ CRC32_POLYNOMIAL;  

  45.           else  

  46.             uData >>= 1;  

  47.     }  

  48.     return uData^0xFFFFFFFF;  

  49. }  


测试一下,"Hello World"得到的结果为0x4A17B156,确认与PC的软件一致.


难道CRC32这样就结束了吗?非也,还有问题.

那就是数据大小端的问题.从我的代码中,我认为如果大端的话需要将数据反一下,然后再送入到STM32 CRC32的硬件里面做运算.这样就可以得到跟PC同样的结果.

但是由于我用keil的gcc编译器,目前这个无法支持大端.所以只能当作留给有心人去帮手做剩下我结论的验证。

keil的gcc编译器编译出来的错误信息也贴上,看看有没有高手支持解决一下:



我认为目前该编译器不支持大端编译的原因是以下链接:讨论gcc大端问题 也许是支持的,自己鸡肠不够好理解错了,欢迎大家纠正.


关键字:STM32  硬件CRC32 引用地址:STM32的硬件CRC32使用

上一篇:STM32F030 WWDG使用结论
下一篇:Keil5.15使用GCC编译器编译STM32工程

推荐阅读最新更新时间:2024-03-16 15:33

基于stm32的精确延时利用系统滴答systick
利用系统滴答定时器来实现精确延时,需要以下五步: 1、设置滴答定时器的时钟,通过设置其控制寄存器,选择外部时钟,即为系统时钟的八分之一,若系统时钟为72M,则滴答定时器时钟为9M。即定时一秒需要9M个时钟周期。 2、设置滴答定时器的重装载寄存器的数值,即需要延时的时钟周期数。如:若需要延时20微秒,则重装载值为20*9.若要延时20毫秒,则设置重装载值为20*9000. 3、清空滴答定时器当前值寄存器的值,使之为零,以便使能计数时能够从设定值开始倒数计时。 4、设置滴答定时器的控制寄存器,开始倒计数。 5、查询滴答定时器的状态位,定时时间到,关闭定时器,清空定时器当前值。 void delay_init(u8 SYSC
[单片机]
STM32学前班教程之二:怎么开发-入门需知
该产品为简易STM32调试器和DEMO板一体化的调试学习设备,价格在一百多块。 2、硬件配置 仿真部分:USB口,reset,指示灯,JTAG DEMO部分:4按键(IO),4LED(IO),一个串口,启动方式跳线,所有引脚的焊盘(可自行焊接插针进行扩展) DEMO芯片:STM32F103C8T6(程序空间64K) 参数和扩展: 注:学习的目标芯片是STM32F103CBT6(7 7mm,128K flash,16K RAM)以及STM32F103RET6(10 10mm,512K flash,64K RAM)。 STM32-SK的硬件连接方法(用板载调试器调试板载DEMO): JP3、JP5 须全部短接 USB通
[单片机]
成本低、易于编程控制的DLP投影STM32单片机驱动电路研究设计
DLP投影技术是应用美国德州仪器公司开发的数字微镜元件--DMD(Digital Micromirror Device)作为主要关键处理元件以实现数字光学处理过程的技术。DLP显示的色彩清晰度高、艳丽、细腻、逼真,且为全数字显示即可靠性极高,能在各类产品(如大屏幕数字电视、公司/家庭/专业会议投影机和数码相机(DLP Cinema))中提供最佳图像效果。目前,大部分的家用或商用DLP投影机都采用了单片结构,使得其便于移动携带,因而得到越来越广泛的应用。在目前应用发展的基础上,又对其结构的精简性、携带的方便性提出了更高的要求。传统的DLP投影仪是通过DVI接口接收外部信号,并且经过信号转换传送给DLP控制器来控制DLP的显示,占用的
[单片机]
成本低、易于编程控制的DLP投影<font color='red'>STM32</font>单片机驱动电路研究设计
STM32直接驱动RGB接口的TFT数字彩屏设计
引言     随着工业技术的不断发展,人机界面的开发及应用空前火热,为了具有比较友好的人机界面,TFT数字彩屏被广泛的应用,但是TFT彩屏通常都不带有控制器,所以现在驱动彩屏的方案大致有2种:     ①采用ARM9或者更高级别的平台,芯片上带有TFT控制器,可以直接挂接TFT数字屏。     ②采用低端CPU处理器平台,外加TFT控制器模块,再挂接TFT数字屏。     对于方案①来说,系统的复杂度会莫名地增加,再加上该类的平台中主MCU多为BGA封装,对于需求很多小量多样化产品的客户来说,较难以接受这样的方案;而 ②方案平白无故添加了一个LCD控制器。这两种方案无论哪一种都增加了硬件成本,本文提出了一种由STM32的FSMC总线
[嵌入式]
STM32 KEIL下的堆栈设置问题
刚接手 STM32 时,你只编写一个 int main() { while(1); } BUILD://Program Size: Code=340 RO-data=252 RW-data=0 ZI-data=1632 编译后,就会发现这么个程序已用了1600多的RAM,要是在51单片机上,会心疼死了,这1600多的RAM跑哪儿去了,分析map,你会发现是堆和栈占用的 在startup_stm32f10x_md.s文件中,它的前面几行就有以上定义,这下该明白了吧。 Stack_Size EQU 0x00000400 Heap_Size EQU 0x00000200 顺便记号,关注此帖:
[单片机]
STM32 TIM1 输出脉冲范例
TIM模块定时器向上溢出 & 输出比较 首先我们必须肯定ST公司的实力,也承认STM32的确是一款非常不错的Cortex-M3核单片机,但是,他的手册实在是让人觉得无法理解,尤其是其中的TIM模块,没有条理可言,看了两天几乎还是不知所云,让人很是郁闷。同时配套的固件库的说明也很难和手册上的寄存器对应起来,研究起来非常费劲!功能强大倒是真的,但至少也应该配套一个让人看的明白的说明吧~~ 两天时间研究了STM32定时器的最最基础的部分,把定时器最基础的两个功能实现了,余下的功能有待继续学习。 首先有一点需要注意:FWLib固件库目前的最新版应该是V2.0.x,V1.0.x版本固件库中,TIM1模块被独立出来,调用的函数与其他定时器不同
[单片机]
stm32定时器主从模式
TIM2作master;TIM3,TIM4作slave 定时器2事件更新被用作触发输出TRGO 从定时器TIM3,TIM4工作在从模式:门控模式 触发选择设为:ITR1,这样TIM2的TRGO就连到了TIM3和TIM4的内部触发输入ITR1上,经过一系列选择器之后TIM2的TRGO就是TIM3和tim4的TRGI; 这样一来就可以通过控制TIM2的period和Pulse来控制TIM3和TIM4输出一定的脉冲个数;
[单片机]
<font color='red'>stm32</font>定时器主从模式
基于STM32+OV7670的低端视频监控系统设计
1 芯片简介 1.1 STM32F407简介 本系统采用的处理器是意法半导体公司的STM32F407,该处理器以32位Cortex—M4为内核,具有浮点运算功能的低端高速ARM,其内部集成了大量可供立即使用的资源,如TFT液晶显示器接口(Flexible Stactie Memory Control,FSMC)、摄像头接口(Camera Inter face)、DMA控制器等,方便且实用。 1.2 OV7670简介 OV7670是OmniVision公司基于CMOS VGA的图像传感器,可通过SCCB总线控制输出整帧、子采集、取窗口等操作,其VGA图像最高可达到30 fps。其对外重要接口有:XCLK(时钟输入)、HREF(输出行
[单片机]
基于STM32+OV7670的低端视频监控系统设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved