完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 MMCU5721167 于 2019-1-3 15:22 编辑 来源 灵动微电MMCU 上一章节中已经教大家如何使用MM32SPIN2x的UARTBit9模式,本章节将与大家一起使用CRC模块进行数据校验。 在数据传输过程中,无论传输系统的设计再怎么完美,差错总会存在,这种差错可能会导致在链路上传输的一个或者多个帧被破坏(出现比特差错,0变为1,或者1变为0),从而接受方接收到错误的数据。为尽量提高接受方收到数据的正确率,在接受方接收数据之前需要对数据进行差错检测,当且仅当检测的结果为正确时接收方才真正收下数据。检测的方式有多种,常见的有奇偶校验、因特网校验和循环冗余校验等。 其中循环冗余校验(CRC)原理实际上就是在一个p位二进制数据序列之后附加一个r位二进制检验码(序列),从而构成一个总长为n=p+r位的二进制序列;附加在数据序列之后的这个检验码与数据序列的内容之间存在着某种特定的关系。如果因干扰等原因使数据序列中的某一位或某些位发生错误,这种特定关系就会被破坏。因此,通过检查这一关系,就可以实现对数据正确性的检验。只要经过严格的挑选,并使用位数足够多的除数 P,那么出现检测不到的差错的概率就很小很小。CRC是一种常用的检错码,无法检测出错误在哪里,因此并不能用于自动纠错,一般的做法是丢弃接收的数据。 从上面的程序框图,我们可以发现,多项式的幂次越高,校验效果越好,但所花费的时间也越长。因此常用查表法或专用的硬件CRC模块来提高效率。 其中查表法,是事先根据特定的校验多项式,算出1字节数据范围所对应的256个余数,将其作为表格,编程写到程序存储器中查询而避免在线运算,已是非常通用的做法。但如果是CRC16校验,存储表格要占512字节(CRC32则需要1 KB),对于有限的单片机ROM资源来说所占比例不小,往往只因为多装了此表,就不得不升级单片机的型号。 在SPIN2x系列MCU中,加入了一个CRC计算单元,使用1个32位数据寄存器作为输入和输出,在执行写操作时输入CRC计算的新数据,在执行读操作时返回上一次CRC计算的结果。每一次写入数据寄存器,都会对整个32位字进行CRC计算,而不是逐字节地计算,从而节省大量的时间。
图2 CRC计算单元框图 下面我们来看一下在程序中软件CRC与硬件CRC的配置。 CRC模块的配置步骤如下:
程序中配置如下: uint32_t Hardware_CRC(u32*addr, int num) { CRC->CR|=1; //复位 for (; num > 0; num--) CRC->DR = (*addr++); return CRC->DR; } 我们可以使用软件算法来检验计算结果,对比两种方式花费的时间。 软件算法如下: u32 Software_CRC (u32 *ptr,u32 len) { u32 xbit; u32 data; u32 CRC32 = 0xFFFFFFFF; u32 bits; const u32 dwPolynomial =0x04C11DB7 ; u32 i; for(i = 0;i < len;i++) { xbit = (unsigned)1 <<31; data = ptr; for (bits = 0; bits < 32;bits++) { if (CRC32 & 0x80000000) { CRC32 <<= 1; CRC32 ^= dwPolynomial; } else CRC32 <<= 1; if (data & xbit) CRC32 ^= dwPolynomial; xbit >>= 1; } } return CRC32; } 下面我们用两个简单的数组,一个数组从0x00递增到0x7F,另一个数组从0x7F递减到0x00,分别使用硬件CRC和软件CRC计算,同时使用tiM1进行计时,最后通过UART输出得到的校验码和花费的时间。 计算和输出程序:void CRCTest() { unsigned int i; u32 CRCtime,CRCresault; u32 crc1[128]; for(i=0;i<128;i++) crc1 = i; printf("CRC_testrn"); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE);//使能CRC时钟 CRC->CR|=1; //复位 printf("rnCRC_DR=%xtrn",CRC->DR);//输出复位值 TIM1->CNT &= 0; CRCresault=Hardware_CRC(crc1,128); CRCtime =TIM1->CNT; printf("Hardware_CRC1:resault=%08xttime=%drn",CRCresault,CRCtime); TIM1->CNT &= 0; CRCresault=Software_CRC(crc1,128); CRCtime =TIM1->CNT; printf("Software_CRC1:resault=%08xttime=%drn",CRCresault,CRCtime); for(i=0;i<256;i++) crc1 = 0xFF-i; TIM1->CNT &= 0; CRCresault=Hardware_CRC(crc1,128); CRCtime =TIM1->CNT; printf("Hardware_CRC2:resault=%08xttime=%drn",CRCresault,CRCtime); TIM1->CNT &= 0; CRCresault=Software_CRC(crc1,128); CRCtime =TIM1->CNT; printf("Software_CRC2:resault=%08xttime=%drn",CRCresault,CRCtime); } 定时器配置程序: void Tim1_UPCount_test(u16Prescaler,u16 Period) { TIM_TimeBaseInitTypeDefTIM_StructInit; /*使能TIM1时钟,默认时钟源为PCLK2(PCLK2未分频时不倍频,否则由PCLK2倍频输出),可选其它时钟源*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); TIM_StructInit.TIM_Period=Period; //ARR寄存器值 TIM_StructInit.TIM_Prescaler=Prescaler; //预分频值 /*数字滤波器采样频率,不影响定时器时钟*/ TIM_StructInit.TIM_ClockDivision=TIM_CKD_DIV1; //采样分频值 TIM_StructInit.TIM_CounterMode=TIM_CounterMode_Up; //计数模式 TIM_StructInit.TIM_RepetitionCounter=0; TIM_TimeBaseInit(TIM1,&TIM_StructInit); TIM_Cmd(TIM1, ENABLE); /*更新定时器时会产生更新时间,清除标志位*/ TIM_ClearFlag(TIM1,TIM_FLAG_Update); } Main函数: int main(void) { Tim1_UPCount_test(48-1,0xffff); //APB2时钟为48M,48分频后TIM1时钟为1MHz delay_init(); uart_initwBaudRate(9600); //初始化UART CRCTest(); while(1) { } } 图3 软件CRC与硬件CRC计算结果 从结果中,我们可以看到,对于这两个数组,硬件CRC与软件CRC所得到的结果一致,但是硬件CRC每个数组只花费了52us,远小于软件CRC的2.5ms,由此可见,在进行大量数据处理的时候,使用硬件CRC模块可以节省大量的时间,同时保证了计算结果的正确。 关于灵动微电子 灵动微电子股份有限公司(股票代码:833448,股票简称:灵动微电)是国内专注于MCU产品与MCU应用方案的领先供应商,是中国工业及信息化部和上海市信息化办公室认定的集成电路设计企业,同时也是上海市认定的高新技术企业。自2011年3月成立至今,灵动微电子已经成功完成数百余MCU产品的设计及推广,灵动微电子目前已批量供货的基于ARMCortex-M0及Cortex-M3 内核的MCU产品包括:针对通用高性能市场的MM32F系列,针对超低功耗及安全应用的MM32L系列,具有多种无线连接功能的MM32W系列,电机驱动及控制专用的MM32SPIN系列,以及针对超小尺寸及超高集成度的MM32P系列等,以满足客户及市场多领域、多层次的丰富应用场景需求。 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2252个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11794 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5968 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
11055 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4591 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4323 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
1222浏览 1评论
842浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 12:15 , Processed in 0.645107 second(s), Total 65, Slave 49 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号