CRC校验函数(自己编写的软件校验方法)__代码

CRC_user.h

#ifndef __CRC_user_H__
#define __CRC_user_H__

#include <cstdint>

uint32_t CRC32(uint8_t *, uint16_t, uint32_t);
uint8_t InverUint8(uint8_t data);
uint32_t InverUint32(uint32_t data);
uint16_t CRC16(uint8_t *data, uint16_t len, uint16_t init);
uint8_t CRC8(uint8_t *data, uint16_t len, uint8_t init);

#endif

CRC_user.c

#include "stm32g4xx_hal.h"
#include "CRC_user.h"

uint32_t CRC32(uint8_t *data, uint16_t len, uint32_t init)
{
    uint32_t poly = 0x04C11DB7;
    
    while(len--)
    {
        init = init ^(InverUint8(*data) << 24);
        for(uint8_t i = 0; i<8;i++)
        {
            if(init&0x80000000)    // if成立,该二进制位是1
            {
                init = (init<<1)^poly;
            }
            else                   // else成立,该二进制位是0
            {
                init = init<<1;
            }
        }
        data++;
    }
    
    return InverUint32(init);
}
/*   CRC校验计算原理
本节实验我们利用程序自己编写CRC32校验计算,多项式初值都可以自由设定,灵活性比硬件CRC32高。
注意:按字节进行计算,利用while循环个字节一个字节计算。
(1)取一个字节数据,因为是CRC32,将该字节左移到最高处。
(2)左移到最高处后和初值异或,结果变为新初值。
(3)利用for循环,循环8次,处理新初值中每个二进制位,如果是1,新初值左移1位后和多项式异或,
结果是再新一次的初值,如果是0,仅左移,不同多项式异或。
(4)再去取下一个字节重复操作,直到while循环处理完所有数据,将最终的新初值作为校验结果值返回。
*/


uint16_t CRC16(uint8_t *data, uint16_t len, uint16_t init)
{
    uint16_t poly = 0x1021;
    
    while(len--)
    {
        init = init ^(*data << 8);
        for(uint8_t i = 0; i<8;i++)
        {
            if(init&0x8000)    // if成立,该二进制位是1
            {
                init = (init<<1)^poly;
            }
            else               // else成立,该二进制位是0
            {
                init = init<<1;
            }
        }
        data++;
    }
    
    return init;
}

uint8_t CRC8(uint8_t *data, uint16_t len, uint8_t init)
{
    uint8_t poly = 0x31;
    
    while(len--)
    {
        init = init ^(InverUint8(*data) << 0);
        for(uint8_t i = 0; i<8;i++)
        {
            if(init&0x80)    // if成立,该二进制位是1
            {
                init = (init<<1)^poly;
            }
            else               // else成立,该二进制位是0
            {
                init = init<<1;
            }
        }
        data++;
    }
    
    return InverUint8(init);
}




uint8_t InverUint8(uint8_t data)
{
    uint8_t temp = 0;
    
    for(uint8_t i=0; i<8; i++)
    {
        if(data&(1<<i))
        {
            temp |= 1<<(7-i);
        }
    }
    return temp;
}

uint16_t InverUint16(uint16_t data)
{
    uint16_t temp = 0;
    
    for(uint8_t i=0; i<16; i++)
    {
        if(data&(1<<i))
        {
            temp |= 1<<(15-i);
        }
    }
    return temp;
}

uint32_t InverUint32(uint32_t data)
{
    uint32_t temp = 0;
    
    for(uint8_t i=0; i<32; i++)
    {
        if(data&(1<<i))
        {
            temp |= 1<<(31-i);
        }
    }
    return temp;
}


/*
本节实验我们在上一节软件CRC32校验计算程序基础上,增加数据反转函数,适用于更多种情形下的CRC32校验方式。
注意:数据翻转包含:(1)待校数据,先反转后再参与计算            ----输入数据反转(REFIN)
                   (2)校验后的结果数据,先反转后再return返回  ----输出数据反转(REFOUT)
注意:反转指的是低位变高位,高位变低位,比如按字节翻转,原来的位0成为了位7,位1变成位6,
     位1成为位6,原来高位的位7成为位0,位6变位1,以此类推。
*/

main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "crc.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
#include <stdio.h>

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "CRC_user.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
//uint32_t buff[4]   = {0x01020304, 0x05060708,  0x090a0b0c, 0x0d0e0f00};
uint8_t  buff2[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
char buff_send[100];
char buff_send2[100];
char buff_send3[100];
char buff_send4[100];
uint8_t buff_receive[100] = {0};
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if(huart->Instance == LPUART1)
    {
//        HAL_UART_Transmit_DMA(huart, (uint8_t*)buff_send, sizeof(buff_send));
        HAL_UART_Transmit_DMA(huart, (uint8_t*)buff_send2, sizeof(buff_send2));
        
        HAL_UARTEx_ReceiveToIdle_DMA(huart, buff_receive, sizeof(buff_receive));
        __HAL_DMA_DISABLE_IT(huart->hdmarx, DMA_IT_HT);
    }
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_LPUART1_UART_Init();
  MX_CRC_Init();
  /* USER CODE BEGIN 2 */
  HAL_UARTEx_ReceiveToIdle_DMA(&hlpuart1, buff_receive, sizeof(buff_receive));
  __HAL_DMA_DISABLE_IT(hlpuart1.hdmarx, DMA_IT_HT);
  
//  sprintf(buff_send, "CRC_Value: %x\n", HAL_CRC_Calculate(&hcrc, buff, 4));

//  HAL_CRC_Calculate(&hcrc,  &buff[0], 1);
//  HAL_CRC_Accumulate(&hcrc, &buff[1], 1);
//  HAL_CRC_Accumulate(&hcrc, &buff[2], 1);
//  sprintf(buff_send2,"CRC_continuous_calculate_Value: %x\n", HAL_CRC_Accumulate(&hcrc, &buff[3], 1));
  
  sprintf(buff_send3, "CRC_user_calculate_Value:%x\n", CRC16(buff2, 16, 0x0000));
  HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)buff_send3, sizeof(buff_send3));
  
  sprintf(buff_send3, "CRC_user_calculate_Value:%x\n", CRC8(buff2, 16, 0x00));
  HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)buff_send3, sizeof(buff_send3));
  
//  uint32_t res;
//  res = CRC32(buff2, 5, 0xFFFFFFFF);
//  res = CRC32(&buff2[5], 3, res);
//  res = CRC32(&buff2[8], 4, res);
//  sprintf(buff_send4, "CRC_user_continue_calculate_Value:%x\n", CRC32(&buff2[12],4,res));
//  HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *) buff_send4, sizeof(buff_send4));
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
  RCC_OscInitStruct.PLL.PLLN = 85;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值