硬汉嵌入式论坛

 找回密码
 立即注册
查看: 488|回复: 1
收起左侧

[Lua] 使用C函数和lua函数得到和STM32 CRC32硬件算法一样的结果

[复制链接]

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
发表于 2023-12-10 01:21:28 | 显示全部楼层 |阅读模式
在其他平台如果想要得到和STM32 硬件CRC32一样的结果,需要将输入的数据按字节反转,再将字节存放次序反转,4字节为一组,然后再按常规CRC32算法计算。以0x41为例: 将 0x41 写成二进制为: 0100 0001,将其反转为: 1000 0010 ,反转后的数十六进制为: 0x82 同理,将 [0x41, 0x42, 0x43, 0x44] 依次反转便为 [0x82, 0x42, 0xC2, 0x22] ,同时字节的存放也需要反转,即 [0x22, 0xC2, 0x42, 0x82]。

c语言函数【安富莱】
[C] 纯文本查看 复制代码
// 按STM32方式计算CRC32,di是32字节整数数组,len是4字节整数的个数(字节个数/4)
uint32 t CRC32_STM32(uint32_t *di, uint32_t len)
{
  uint32_t crc_poly = 0x04C11DB7; 
  uint32_t data = 0xFFFFFFFF;

  for (uint32_t i = 0: i < len; i++)
  {
    data ^= di[i];
    for (uint8_t j = 0; j < 32; j++)
    {
          if (data & 0x80000000)
          {
            data = (data << 1) ^ crc_poly;
          }
          else
          {
            data <<= 1;
          }
    }
  }
  return (data);
}



lua 语言函数【安富莱调试通过】
[Lua] 纯文本查看 复制代码
function CRC32_STM32(di)
  local i,j
  local crc_poly = 0x04C11DB7
  local data = 0xffffffff
  local d0
  local len
 
  --不足4字节,末尾补0
  len = #di
  for i = 1, len % 4, 1 do
    di = di.."\x00"
  end
 
  len = #di
  for i = 1, len / 4, 1 do
    d0 = (string.byte(di, (i - 1) * 4 + 1) << 0) + 
         (string.byte(di, (i - 1) * 4 + 2)  << 8) + 
         (string.byte(di, (i - 1) * 4 + 3)  << 16) +
         (string.byte(di, (i - 1) * 4 + 4) << 24)
 
    data = data ~ d0
    for j = 1,32,1 do
      if ((data & 0x80000000) == 0x80000000) then
        data = ((data << 1) & 0xFFFFFFFF) ~ crc_poly
      else
        data = (data << 1) & 0xFFFFFFFF
     end
    end
  end
  return (data)
end

下面是百度的文心一言提供的 HAL库代码
问:用C语言实现STM32硬件CRC32函数
答:
STM32 微控制器通常有一个硬件 CRC 计算单元,可以高效地计算 CRC32。为了使用此硬件功能,我们需要配置相关的寄存器并启动计算。以下是一个简单的示例,展示如何使用 STM32 HAL 库来实现硬件 CRC32 的计算:
首先,确保你的 STM32 HAL 库包含了 CRC 的相关驱动。然后,你可以使用以下代码来计算一个数据缓冲区的 CRC32 值:
c复制代码

#include "stm32f4xx_hal.h"  // 根据你的 STM32 系列更改这里的头文件  

  

CRC_HandleTypeDef hcrc;  

  

void MX_CRC_Init(void)  

{  

  hcrc.Instance = CRC;  

  if (HAL_CRC_Init(&hcrc) != HAL_OK)  

  {  

    /* 初始化错误 */  

    Error_Handler();  

  }  

}  

  

uint32_t Compute_CRC32(uint32_t *data, uint32_t length)  

{  

  return HAL_CRC_Calculate(&hcrc, (uint32_t *)data, length);  

}  

  

int main(void)  

{  

  HAL_Init();  

  SystemClock_Config();  

  MX_CRC_Init();  

  

  uint32_t myData[] = {0x12345678, 0x9ABCDEF0}; // 示例数据  

  uint32_t crcResult = Compute_CRC32(myData, sizeof(myData)/sizeof(myData[0]));  

   

  while (1)  

  {  

    // 循环体  

  }  

}

在这个示例中,MX_CRC_Init 函数用于初始化 CRC 硬件。Compute_CRC32 函数则用于计算给定数据缓冲区的 CRC32 值。





回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106760
QQ
发表于 2023-12-11 07:43:38 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-5 03:30 , Processed in 0.231010 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表