一、概叙:

1、本文主要是针对常用的crc32的实现方式进行说明
2、crc32的软件方式和硬件方式使用时间的实测结果表,方便大家在开发中考虑使用哪种方式更合适。

二、实现:

1、软件实现代码1

/**
 * @brief 软件crc32计算
 */
u32 crc32(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 = 1 << 31;
        data = ptr[i];
        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;
}

2、软件实现方式2

void xx_cacul_crc32_u32(uint32_t *crc,uint32_t value)  
{                       
        uint32_t xbit = 1 << 31;                                
        int32_t bits = 0;                                   
        uint32_t dwPolynomial = 0x04c11db7;                 
        for (bits = 0; bits < 32; bits++) {                 
                if (*crc & 0x80000000) {                        
                    *crc <<= 1;                             
                    *crc ^= dwPolynomial;                       
                    }                                               
                else {                                          
                    *crc <<= 1;                                 
                    }                                               
                if (value & xbit) {                             
                    *crc ^= dwPolynomial;                       
                }                                               
                xbit >>= 1;                                     
        }                                                   
}
/**
 * @brief 
 * @param  crc               计算出的CRC值,初值要置位为0xffffffff
 * @param  block             要计算的8位数组 
 * @param  dataLength        数组长度  byte为单位
 */
void xx_cacul_crc32_frame(uint32_t *crc, uint8_t *block,uint32_t dataLength) 
{                                           
    uint32_t dlength = ((dataLength) >> 2);                                                             
    uint32_t value = 0;                                                                                 
    for (uint32_t i = 0; i < dlength; ++i) 
    {                                                               
        memcpy(&value, (uint8_t*)(block) + (i << 2), 4);                                                                                                                                            
        xx_cacul_crc32_u32(crc, value);                                                                                                                                                     
    }                                                                                                   
    value = 0;                                                                                          
    uint32_t end = dlength << 2;                                                                            
    if (end != (dataLength)) //数据不够4字节的整数倍
        {                                                                           
        memcpy(&value, (uint8_t*)(block)  + end, (dataLength) - end);                                                                                                                               
        xx_cacul_crc32_u32(crc, value);                                                             
        }                                                                                               
    }

3、硬件实现:

(1)cubemx配置硬件crc,如下图:
在这里插入图片描述
在这里插入图片描述

(2)调用HAL库

u32 calculate_crc32(u8 *pdata, u16 len)
{
  u32 crc=0;
  crc = HAL_CRC_Calculate(&hcrc, (u32 *)pdata, len)^0xffffffff;
  return crc;
}

三、测试结果

本选项也是本博文的重点,结果真实有效,供大家设计时参考使用哪种方式
本文档旨在使用STM32软件CRC32和硬件CRC32计算的值一样,测试硬件平台为STM32F105
使用需要注意一点:CRC32按照四字节进行计算,无论软件实现还是硬件实现,统一按照不足4字节的位数补0来进行计算。
在这里插入图片描述

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐