【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 校验的工具函数, 常用于嵌入式通信中验证数据完整性。

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

相关推荐
小岐AI观16 小时前
智赋岐黄适合养生馆吗?
大数据·人工智能·物联网
wuyk55517 小时前
98.C语言易混难点:字符数组与字符串指针的底层差异
c语言·开发语言·c++·stm32·嵌入式硬件·算法
恒锐丰-罗生18 小时前
国产 H 桥驱动 SS6289|18V/4A 有刷电机驱动芯片性与应用分析 内置采样 + 多保护,门锁 / 机器人优选器件
驱动开发·嵌入式硬件·硬件工程
数字新视界20 小时前
动环监控信创适配助力机房管理智能化转型
物联网·数据中心·动环监控·微模块机房·模块化机房
zcmodeltech1 天前
工程机械与矿山机械沙盘模型多系统协同控制系统设计:基于STM32与Modbus RTU的露天开采-井下掘进-智慧矿山全场景联动方案
数据库·stm32·单片机·嵌入式硬件·制造·多分类
电子制造自留地1 天前
光伏MPPT控制板PCB高频EMI挑战与应对策略
科技·制造·pcb工艺·光伏
云泽8081 天前
深入浅出 STM32(十五):多通道GPIO驱动的软件抽象与实现
stm32·单片机·嵌入式硬件
嵌入式阿蔡1 天前
OTA 实战五(收官):量产落地 Checklist —— 版本号 / 防回滚 / 灰度 / 断点续传
网络·stm32·单片机·嵌入式硬件·嵌入式实时数据库
乐橙开放平台1 天前
物业 SaaS 笔记:子账号 Policy 按通道隔离,At_ 管控面 / St_ 数据面治理 accessToken
后端·物联网·音视频
碧海银沙音频科技研究院1 天前
基于杰理AC7016C的GTCRN门控卷积神经网络语音增强方法
人工智能·嵌入式硬件·语音识别