STM32硬件CRC32问题记录

前言:STM32硬件本身没有问题,只是其中的校验值计算方式跟平常的不太一样

  1. 硬件平台
    1. 我使用的是STM32F103ZET6单片机,用cubeMX新建的工程(使能crc即可加载\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_crc.c文件)
    2. CRC特性介绍(文档内容来自STM32中文参考手册)
    3. CRC32详细介绍请查看文档
  2. 软件平台

     

    1. 方法一:使用cubeMX初始化硬件CRC
    2. 方法二:手动添加文件并初始化硬件CRC

       

       

      1. 打开#define HAL_CRC_MODULE_ENABLED,在.\Core\Inc\stm32f1xx_hal_conf.h中第42行
      2. 添加源文件stm32f1xx_hal_crc.c到工程中
      3. 再主函数添加初始化程序
    CRC_HandleTypeDef hcrc;
    
    /* CRC32初始化函数 */
    static void MX_CRC_Init(void);
    
    /* 软件方式计算CRC32-STM32 */
    uint32_t uiCRC32_STM32(uint32_t *puiInitCRC, uint32_t *pucDataBuff, uint32_t uiLength)
    {
        uint32_t uiPolynomial = 0x04C11DB7, uiInputCRC = 0xFFFFFFFF, i = 0, xbit = 0x80000000, uiMask = 0, uiDataTemp = 0;
    
        if(puiInitCRC != NULL)
            uiInputCRC = *puiInitCRC;
    
        for(i = 0; i < uiLength; ++i)
        {
            uiDataTemp = *pucDataBuff++;
            xbit = 0x80000000;
    
            for(uiMask = 1; uiMask; uiMask <<= 1)
            {
                if(uiInputCRC & 0x80000000)
                    uiInputCRC = (uiInputCRC << 1) ^ uiPolynomial;
                else
                    uiInputCRC <<= 1;
    
                if(uiDataTemp & xbit)
                    uiInputCRC ^= uiPolynomial;
    
                xbit >>= 1;
            }
        }
    
        return uiInputCRC;
    }
    
    uint32_t CRC32 = 0, blen = 0, uiCRC32 = 0; 
    void HAL_CRC32_Test(void)
    {
        /* 第一步,必须使能硬件CRC32 */
    	__HAL_RCC_CRC_CLK_ENABLE();
    
        /* 第二步,使用硬件CRC计算CRC32值 */
    	char *pbuf = "SET,123456,50,000164,";
    	blen = strlen(pbuf);
    	CRC32 = HAL_CRC_Calculate(&hcrc, (uint32_t *)pbuf, blen);
    
        /* 第三步,对比软件方式去计算CRC32 */
    	uiCRC32 = uiCRC32_STM32(NULL, (uint32_t *)pbuf, blen);
    
        /* 第四步, 对比CRC32与uiCRC32, 结果发现值相等 */
    }
    
    int main(void)
    {
        ...
        MX_CRC_Init();
        /* 计算CRC32 */
        HAL_CRC32_Test():
        ...
    }
    
    /**
      * @brief CRC Initialization Function
      * @param None
      * @retval None
      */
    static void MX_CRC_Init(void)
    {
    
      /* USER CODE BEGIN CRC_Init 0 */
    
      /* USER CODE END CRC_Init 0 */
    
      /* USER CODE BEGIN CRC_Init 1 */
    
      /* USER CODE END CRC_Init 1 */
      hcrc.Instance = CRC;
      if (HAL_CRC_Init(&hcrc) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN CRC_Init 2 */
    
      /* USER CODE END CRC_Init 2 */
    
    }

备注:常用CRC32与CRC32-MPEG2.0计算代码如下

/* 常用CRC32校验算法 */
uint32_t uiReflect(uint32_t uiData, uint8_t ucLength)
{
    uint32_t uiMask = 1 << (ucLength - 1), uiMaskRef = 1, uiDataReturn = 0;

    for(; uiMask; uiMask >>= 1)
    {
        if(uiData & uiMask)
            uiDataReturn |= uiMaskRef;

        uiMaskRef <<= 1;
    }

    return uiDataReturn;
}

uint32_t uiCRC32(uint32_t *puiInitCRC, uint8_t *pucDataBuff, uint32_t uiLength)
{
    uint32_t uiPolynomial = 0x04C11DB7, uiInputCRC = 0xFFFFFFFF, i = 0;
    uint8_t ucMask = 0;

    if(puiInitCRC != NULL)
        uiInputCRC = *puiInitCRC;

    uiPolynomial = uiReflect(uiPolynomial, 32);

    for(i = 0; i < uiLength; ++i)
    {
        uiInputCRC ^= *pucDataBuff++;

        for(ucMask = 1; ucMask; ucMask <<= 1)
        {
            if(uiInputCRC & 1)
                uiInputCRC = (uiInputCRC >> 1) ^ uiPolynomial;
            else
                uiInputCRC >>= 1;
        }
    }

    return ~uiInputCRC;
}
/* CRC32-MPEG2.0校验算法 */
uint32_t uiCRC32_MPEG2(uint32_t *puiInitCRC, uint8_t *pucDataBuff, uint32_t uiLength)
{
    uint32_t uiPolynomial = 0x04C11DB7, uiInputCRC = 0xFFFFFFFF, i = 0;
    uint8_t ucMask = 0;

    if(puiInitCRC != NULL)
        uiInputCRC = *puiInitCRC;

    for(i = 0; i < uiLength; ++i)
    {
        uiInputCRC ^= (uint32_t)(*pucDataBuff++) << 24;

        for(ucMask = 1; ucMask; ucMask <<= 1)
        {
            if(uiInputCRC & 0x80000000)
                uiInputCRC = (uiInputCRC << 1) ^ uiPolynomial;
            else
                uiInputCRC <<= 1;
        }
    }

    return uiInputCRC;
}

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值