灵动微电子 · 2022年08月23日 · 北京市

灵动微课堂 | MM32F0140学习笔记——CRC

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两种算法

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

功能框图

image.png

硬件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在运算执行时间对比如下图所示:

image.png

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

作者:灵动MM32
文章来源:灵动MM32MCU

推荐阅读

更多MM32F5系列资料请关注灵动MM32 MCU专栏。如想进行MM32相关芯片技术交流,请添加极术小姐姐微信(id:aijishu20)加入微信群。
推荐阅读
关注数
6144
内容数
276
灵动MM32 MCU相关技术知识,欢迎关注~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息