打印
[STM32L5]

STM32L4R5板子CRC程序的问题

[复制链接]
488|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
代码:
#include "main.h"

/** @addtogroup STM32L4xx_HAL_Examples
  * @{
  */

/** @addtogroup CRC_UserDefinedPolynomial
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* aDataBuffer is 32 bit long*/
#define BUFFER_SIZE 1

/* The user defined polynomial*/
#define CRC_POLYNOMIAL_8B 0x9B /* X^8 + X^7 + X^4 + X^3 + X + 1 */

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* CRC handler declaration */
CRC_HandleTypeDef   CrcHandle;

/* Used for storing CRC Value */
__IO uint32_t uwCRCValue = 0;

/* Buffer containing the data on which the CRC will be calculated
  (one-word buffer in this example) */
static const uint32_t aDataBuffer = 0x1234;

/* Expected CRC Value */
uint32_t uwExpectedCRCValue = 0xEF;

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void Error_Handler(void);

/* Private functions ---------------------------------------------------------*/

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  
  /* STM32L4xx HAL library initialization:
       - Configure the Flash prefetch
       - Systick timer is configured by default as source of time base, but user
         can eventually implement his proper time base source (a general purpose
         timer for example or other time source), keeping in mind that Time base
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
       - Low Level Initialization
     */
  HAL_Init();
  
  /* Configure the system clock to 120 MHz */
  SystemClock_Config();

  /* Configure LED1 and LED3 */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED3);

  /*##-1- Configure the CRC peripheral #######################################*/
  CrcHandle.Instance = CRC;

  /* The default polynomial is not used. It is required to defined it in CrcHandle.Init.GeneratingPolynomial*/  
  CrcHandle.Init.DefaultPolynomialUse    = DEFAULT_POLYNOMIAL_DISABLE;
  
  /* Set the value of the polynomial */
  CrcHandle.Init.GeneratingPolynomial    = CRC_POLYNOMIAL_8B;
  
  /* The user-defined generating polynomial generates a
     8-bit long CRC */
  CrcHandle.Init.CRCLength               = CRC_POLYLENGTH_8B;

  /* The default init value is used */
  CrcHandle.Init.DefaultInitValueUse     = DEFAULT_INIT_VALUE_ENABLE;

  /* The input data are not inverted */
  CrcHandle.Init.InputDataInversionMode  = CRC_INPUTDATA_INVERSION_NONE;

  /* The output data are not inverted */
  CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;

  /* The input data are 32-bit long */
  CrcHandle.InputDataFormat              = CRC_INPUTDATA_FORMAT_WORDS;

  if (HAL_CRC_Init(&CrcHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /*##-2- Compute the CRC of "aDataBuffer" ###################################*/
  uwCRCValue = HAL_CRC_Calculate(&CrcHandle, (uint32_t *)&aDataBuffer, BUFFER_SIZE);

  /*##-3- Compare the CRC value to the Expected one ##########################*/
  if (uwCRCValue != uwExpectedCRCValue)
  {
    /* Wrong CRC value: Turn LED3 on */
    Error_Handler();
  }
  else
  {
    /* Right CRC value: Turn LED1 on */
    BSP_LED_On(LED1);
  }

  /* Infinite loop */
  while (1)
  {
  }
}
我想知道怎么算出来的。于是我写了一个C程序验证
#include "stdio.h"

#define uint32_t unsigned  int
#define uint16_t unsigned short
#define uint8_t  unsigned char

#define BUFFER_SIZE    1

uint32_t  temp;

static const uint32_t aDataBuffer = 0x1234;

/******************************************************************************
* Name:    CRC-32/MPEG-2  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
* Poly:    0x4C11DB7
* Init:    0xFFFFFFF
* Refin:   False
* Refout:  False
* Xorout:  0x0000000
*****************************************************************************/
uint32_t crc32_mpeg_2(uint32_t *data, uint16_t length)
{
    uint8_t i;
    uint32_t crc = 0xffffffff;  // Initial value
    while(length--)
    {
        crc ^= (*data++) << 0;
        for (i = 0; i < 32; ++i)
        {
            if ( crc & 0x80000000 )
                crc = (crc << 1) ^ 0x0000009b;
            else
                crc <<= 1;
        }
    }
    return crc;
}


void main(void)
{
        temp=crc32_mpeg_2(&aDataBuffer, BUFFER_SIZE);
        printf("crc32 value=:%x\r\n",temp);
}
结果得到结果:

得到的值是0xfff75e7f
不是0xef.
请高手指教,谢谢!

使用特权

评论回复
沙发
Stahan| | 2023-6-6 18:06 | 只看该作者
写的程序有问题吧

使用特权

评论回复
板凳
比神乐|  楼主 | 2024-9-20 16:36 | 只看该作者
是程序有问题
现在搞好了
#include <stdio.h>  
#include <stdint.h>  
  
// CRC-8 计算函数,使用多项式0x9B  
uint8_t crc8_0x9b(uint8_t *data, size_t len) {  
    uint8_t crc = 0xFF; // 初始CRC值  
    while (len--) {  
        crc ^= *data++; // 将当前字节的数据与CRC寄存器进行异或  
        for (int i = 0; i < 8; i++) {  
            if (crc & 0x80) { // 如果最高位是1  
                crc = (crc << 1) ^ 0x9B; // 左移一位,并与多项式进行异或  
            } else {  
                crc = crc << 1; // 左移一位  
            }  
        }  
    }  
    return crc;  
}  
  
int main() {  
    uint8_t data[4] = {0,0,0x12,0X34};  
    //uint8_t *data_bytes = (uint8_t *)&data; // 将16位数据转换为字节数组  
  
    // 计算CRC,因为data是16位,但CRC是针对8位(字节)计算的,  
    // 这里我们假设只计算低8位(即0x34)的CRC,因为高位(0x12)对CRC的贡献取决于具体应用场景  
    // 如果你需要同时处理两个字节,你可能需要调整循环或处理逻辑  
    uint8_t crc = crc8_0x9b(data, 4); // 只计算低8位(即0x34)的CRC  
  
    printf("CRC-8 (0x9B) for 0x%02X is 0x%02X\n", data, crc);  
  
    // 注意:如果你的预期结果是0xEF,并且这与上面的代码不匹配,  
    // 那么可能需要调整初始值、处理顺序、多项式或考虑同时处理两个字节的数据。  
    // 但根据常见的CRC-8实现,上面的代码应该为0x34计算出一个合理的CRC值。  
  
    return 0;  
}
运行

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

436

主题

3421

帖子

7

粉丝