MM32F0140学习笔记——CRC

cathy的头像
cathy 发布于:周一, 08/08/2022 - 14:14 ,关键词:

CRC校验(循环冗余校验Error Correcting Code)是数据通讯中最常采用的校验方式之一,它是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误,它是利用除法及余数的原理来作错误侦测的。

MM32F0140系列MCU带有一个硬件CRC计算单元,它采用一个固定的多项式发生器来计算8位、16位或者是32位数据的CRC校验值,对数据传输或数据存储的一致性、完整性进行验证。

主要特性如下所示:

● 固定计算多项式 0x04C11DB7:

X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X + 1

● 支持8、16、32位宽的数据输入寄存器、32位宽的数据输出寄存器

● 硬件计算时间为3个HCLK周期

● 带有可存放中间计算过程的32位宽的数据寄存器

● 支持CRC-32和CRC-32/MPEG-2两种算法

● 支持输入数据和输出数据的大小端选择

功能框图

“MM32F0140学习笔记——CRC"

硬件CRC计算操作步骤

STEP1、使能CRC模块时钟,并复位CRC模块

STEP2、配置CRC_CR寄存器,选择CRC-32或者CRC-32/MPEG-2算法,配置输入数据位宽为8位、16位或者是32位,选择输入、输出数据的大小端

STEP3、通过配置CRC控制寄存器的RST位,将CRC恢复到初始状态

STEP4、依次将数据写入CRC数据寄存器中,MCU自动完成CRC计算过程

STEP5、读取CRC数据寄存器,得到CRC计算结果

硬件CRC示例程序

/* 使能CRC模块时钟,并复位CRC模块 */

RCC->AHBENR  |=  RCC_AHBENR_CRC;
RCC->AHBRSTR |=  RCC_AHBENR_CRC;
RCC->AHBRSTR &= ~RCC_AHBENR_CRC;

/* 配置输入输出数据跟随MCU小端,输入数据选择32位宽,使用CRC-32/MPEG-2算法 */

CRC->CR = 0;

/* 将CRC恢复到初始状态 */

CRC->CR |= CRC_CR_RESET;

/* 计算CRC */

for(uint8_t i = 0; i < length; i++)
{
    CRC->DR = buffer[i];
}

/* 读取CRC计算结果 */

return CRC->DR;

软件CRC的实现是将硬件CRC的计算过程用软件代码的形式体现出来,通过MCU运行功能代码实现CRC的计算过程,与硬件CRC相比,需要根据多项式产生CRC表,在计算过程中还需要考虑数据的大小端选择等参数,实现过程相比硬件CRC要复杂很多、计算速度相比硬件CRC要慢很多。

软件CRC示例程序

/* 根据多项式产生查表数据 */

void CRC_MPEG2_GenerateCRCTable(void)
{
    uint32_t i = 0, j = 0, Data = 0, Temp = 0;
    for(i = 0; i < 256; i++) 
    {
        Data = 0; 
        Temp = (i << 24); 
        for(j = 0; j < 8; j++) 
        { 
            if((Data ^ Temp) & 0x80000000)
            {
                Data = ( Data << 1 ) ^ 0x04C11DB7;
            }
            else
            {
                Data <<= 1;
            }
            Temp <<= 1;
        }
        CRC_MPEG2_Table[i] = Data; 
    }
}

/* 大小端处理 */

uint32_t CRC_MPEG2_SwapEndian(uint32_t data)
{
    return (((data << 24) & 0xFF000000) | 
            ((data <<  8) & 0x00FF0000) | 
            ((data >>  8) & 0x0000FF00) | 
            ((data >> 24) & 0x000000FF));
}

/* 软件CRC计算过程 */

uint32_t CRC_MPEG2_CalcCRC(uint32_t *Buffer, uint16_t Length)
{
    uint8_t i = 0;
    uint32_t Temp = 0, Result = 0xFFFFFFFF;
    uint32_t *pData;

    /* Dynamic generate CRC-32/MPEG-2 table */
    CRC_MPEG2_GenerateCRCTable();

    while(Length--)
    {
        Temp = CRC_MPEG2_SwapEndian(*Buffer++);
        pData = &Temp;

        for(i = 0; i < 4; i++)
        {
            Result = (Result << 8) ^ CRC_MPEG2_Table[((Result >> 24) ^ *((uint8_t *)pData + i)) & 0xFF];
        }
    }

    return Result;
}

对于同一组32位114个数值数据分别进行软件CRC和硬件CRC计算,在不考虑软件CRC自动生成查表数据所消耗时间的情况下,软件CRC与硬件CRC在运算执行时间对比如下图所示:

“MM32F0140学习笔记——CRC"

“MM32F0140学习笔记——CRC"

软件CRC相比于硬件CRC在执行速度上最少有5倍的差距,软件CRC的代码量以及占用SRAM的空间也比硬件CRC要多;所以在MCU带有硬件CRC功能时,通过硬件CRC的计算方式可以大大节省MCU的资源、提升CRC的运算速度,给实际应用带来流畅的检验。

来源:灵动MM32MCU
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 73