【STM32】CRC 校验函数

先上一下 CRC校验 的源代码:

c 复制代码
void crc_check(unsigned char *ptr,unsigned int len) //crc为开源函数
{
  unsigned long wcrc=0XFFFF;//预置16位crc寄存器,初值全部为1
  unsigned char temp;//定义中间变量
  int i=0,j=0;//定义计数
  for(i=0;i<len;i++)//循环计算每个数据
  {
    temp=*ptr&0X00FF;//将八位数据与crc寄存器亦或
    ptr++;//指针地址增加,指向下个数据
    wcrc^=temp;//将数据存入crc寄存器
    for(j=0;j<8;j++)//循环计算数据的
    {
      if(wcrc&0X0001)//判断右移出的是不是1,如果是1则与多项式进行异或。
      {
        wcrc>>=1;//先将数据右移一位
        wcrc^=0XA001;//与上面的多项式进行异或
      }
      else//如果不是1,则直接移出
      {
        wcrc>>=1;//直接移出
      }
    }
  }
  temp=wcrc;//crc的值
  L_CRC=wcrc;//crc的低八位
  H_CRC=wcrc>>8;//crc的高八位
}

这个函数通常用于执行 CRC 校验 ,即对输入的数据指针 ptr 和长度 len 进行 循环冗余校验(Cyclic Redundancy Check)。CRC 是一种非常常见且高效的数据完整性校验算法,广泛应用于:

  • 通信协议(如 Modbus、CAN、USB)
  • 存储设备(校验文件完整性)
  • 嵌入式系统(数据包校验)

CRC 校验概念

CRC 校验的作用:检测数据在传输或保存过程中是否被篡改或损坏

原理:将数据看作一个二进制多项式,除以一个"生成多项式",取余数作为CRC校验码


常见类型:

CRC8

CRC16(如 Modbus)

CRC32(如以太网、ZIP)

我们这里以标准的 Modbus CRC16 为例,对详细代码进行解析:
c 复制代码
uint16_t CRC16_Modbus(uint8_t *data, uint16_t len) {
    uint16_t crc = 0xFFFF;  // 初始值
    for (uint16_t i = 0; i < len; i++) {
        crc ^= data[i];  // 将每个字节与 CRC 当前值异或
        for (uint8_t j = 0; j < 8; j++) {
            if (crc & 0x0001) {
                crc >>= 1;
                crc ^= 0xA001;  // 多项式:0x8005 反转为 0xA001
            } else {
                crc >>= 1;
            }
        }
    }
    return crc;
}
逐步解析:
  1. 初始化 CRC:

Modbus协议规定初始值为 0xFFFF

c 复制代码
uint16_t crc = 0xFFFF;
  1. 遍历整个数据区:

每个字节与当前 CRC 值低字节异或:

c 复制代码
for (i = 0; i < len; i++) {
    crc ^= data[i];
    ...
}
  1. 对每个字节进行 8 次移位处理:

如果最低位是1,就右移并异或"生成多项式";

否则直接右移。

c 复制代码
for (j = 0; j < 8; j++) {
    if (crc & 0x0001) {
        crc >>= 1;
        crc ^= 0xA001;
    } else {
        crc >>= 1;
    }
}

需要注意的是:

CRC 校验是 无错误纠正能力 的,只能检测错误

必须和接收端使用相同的 CRC 算法、多项式、初始值

对于不同协议(如 Modbus、CAN),CRC 实现略有不同,例如,本文最初提供的便是 Modbus 协议的 CRC校验。

CRC 的多项式
CRC类型 多项式 初始值 结果异或 应用
CRC-8 0x07 0x00 0x00 SMBus
CRC-16 0x8005 0xFFFF 0x0000 Modbus
CRC-CCITT 0x1021 0xFFFF 0x0000 XMODEM
CRC-32 0x04C11DB7 0xFFFFFFFF 0xFFFFFFFF Ethernet, ZIP

简单来说,函数 crc_check(unsigned char *ptr, unsigned int len) 是用来对指定内存块执行 CRC 校验的工具函数, 常用于嵌入式通信中验证数据完整性。

以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!

相关推荐
bu_shuo15 分钟前
STM32中SystemCoreClockUpdate函数解读
stm32·单片机·嵌入式硬件
学生董格16 分钟前
[嵌入式embed]ST官网-根据指定固件名下载固件库-STSWSTM32054[STM32F10x_StdPeriph_Lib_V3.5.0]
stm32·单片机·嵌入式硬件·stm32054_v3-5-0·stm32f10x
深圳安凯星单片机开发方案公司2 小时前
51单片机是怎么驱动直流电机的
单片机·51单片机
猫猫的小茶馆2 小时前
【STM32】FreeRTOS 任务的创建(二)
stm32·单片机·嵌入式硬件·mcu·c#·智能硬件
无为扫地僧3 小时前
stm32内存分析
stm32·单片机·嵌入式硬件
YONYON-R&D4 小时前
LAYOUT 什么时候需要等长布线?
嵌入式硬件·fpga开发
学习日记hhh4 小时前
基于江科大标准库的编码器测速
单片机·嵌入式硬件
Tracy9734 小时前
A316-LS-MIC-V2:USB AI直播麦克风评估板技术解析
人工智能·嵌入式硬件·音视频·xmos 模组
社牛超靓的铁蛋儿7 小时前
美光MTFC8GAKAJCN-4M_IT型eMMC应用介绍
嵌入式硬件
熬夜的猪仔7 小时前
第四章 Freertos物联网实战DHT11温湿度模块
物联网·freertos·dht11温湿度模块