嵌入式开发--STM32软件和硬件CRC的使用

本文介绍STM32硬件CRC的工作原理及如何调整以匹配通用CRC计算标准。对比软件CRC计算方法,详细解释两者之间的差异,并提供代码示例及验证步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STM32硬件CRC的使用说明

本文对应STM32G0系列
STM32硬件的CRC不占用MCU的计算资源,和软件查表计算消耗的存储空间。但其结果与平常使用的CRC不一样,导致很多人还是在用软件计算CRC。
其实结果的差别,只是由于计算方式导致的,调整计算方式以后也可以输出普通计算的结果。

软件计算CRC16

u16 LL_crc16_calculator(u8* data, u16 len)
{ 
  u16 tmp = 0xffff;
  u16 ret1 = 0;

  for(int n = 0; n < len; n++)
  {
    tmp = data[n] ^ tmp;
    for(int i = 0; i < 8; i++)  /*此处的8 -- 指每一个char类型有8bit,每bit都要处理*/
    {
      if(tmp & 0x01)
      {
        tmp = tmp >> 1;
        tmp = tmp ^ 0xa001;   //多项式0x8005的倒序
      }   
      else
        tmp = tmp >> 1;
    }   
  } 
  return tmp;
}

软件计算CRC32

u32 LL_crc32_calculator(u8* data, u16 len)
{ 
  u32 tmp = 0xffffffff;
  u32 ret1 = 0;

  for(int n = 0; n < len; n++)
  {
    tmp = (data[n]) ^ tmp;
    for(int i = 0; i < 8; i++)  /*此处的8 -- 指每一个char类型有8bit,每bit都要处理*/
    {
      if(tmp & 0x01)
      {
        tmp = tmp >> 1;
        tmp = tmp ^ 0xedb88320;   //多项式0x04c11db7的倒序后是0xedb88320
      }   
      else
        tmp = tmp >> 1;
    }   
  } 
  tmp = ~tmp;
  return tmp;
}

软件与硬件计算的异同

与普通计算方式相同,以CRC32举例,其默认多项式也是
X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X +1,但也可以自定义。
计算的初值不同:STM32为0,普通CRC计算为0xffffffff
计算的顺序不同:STM32从最低位开始计算,普通CRC从最高位开始计算
输出结果:最高位到最低位,与普通CRC刚好相反,而且普通CRC的输出结果为计算结果与0xffffffff异或后输出,STM32就少了这个异或,或者说取反操作。

CubeMX处理

知道了不同之处,接下来的处理就很简单了。在CRC32的设置中按下图,其他系列参照上述软件计算过程,进行对应修改即可
在这里插入图片描述

编程

u8 crc_buf[6] = {0xBE, 0xEF, 0x55, 0xaa, 0xcc, 0xdd};

u32 calculate_crc32(u8 *pdata, u16 len)
{
  u32 crc=0;
 
  //因为主流CRC计算是结果与0xffffffff异或后再输出,而STM32并没有,所以这里要加上异或
  //以下2行代码等效,用自己看得惯的方式就行
  crc = HAL_CRC_Calculate(&hcrc, (u32 *)pdata, len)^0xffffffff;
  crc =~HAL_CRC_Calculate(&hcrc, (u32 *)pdata, len);
  
  return crc;
}

验证

硬件crc的结果为0x8c9792a5

打开 http://www.ip33.com/crc.html,进行结果验证
在这里插入图片描述
结果相符。

CRC16的计算方法又有区别

对于CRC16有些不同,要计算CRC16时,第1个参数选Disable,然后多项式可以自定义
而且计算方法也和CRC32不同,注意看区别
在这里插入图片描述
设置或更改的内容如下:
默认的多项式是不对的,常规应该是0x8005,按位设置好就是X15+X2+X0
默认的初值置0
输入反转,输出不反。
计算结果不异或。

  crc = HAL_CRC_Calculate(&hcrc, (u32 *)pdata, len);

结果验证:

对于0x07, 0x02, 0x00, 0x10, 0x00,硬件CRC计算结果为0x9D1D
在这里插入图片描述
结果相符

MODBUS

MODBUS一般是8个字节,其中CRC16占用最后的2个字节,正文共6个字节,在这里也示例一下
在这里插入图片描述
代码如下:

crc16 = HAL_CRC_Calculate(&hcrc, (u32*)uart2_receive_buf, 6);

在这里插入图片描述

在这里插入图片描述

当然有很多种计算CRC的参数模型,按照上面的方法套一下即可。

CubeMX使用入门教程

从私信和留言发现,很多朋友对CubeMX的使用并不熟悉,找不到CRC或相关功能,为此我专门做了一个教程,点开这里可以看:嵌入式开发–CubeMX使用入门教程,里面有使用方法。

<think>嗯,用户想了解硬件实现的循环冗余校验(CRC)的原理及应用。首先,我得回顾一下CRC的基本概念,确保自己理解正确。根据引用中的资料,CRC是一种通过生成固定位数校验码来检测数据传输或存储错误的技术。它基于多项式除法,使用模2算术运算,对吧? 接下来,硬件实现部分。用户提到的是硬件CRC,所以需要解释它软件实现的不同之处。硬件实现通常用反馈移位寄存器异或门,这样可以提高计算速度,适合高速数据传输的场景。引用中的资料提到,CRC可以通过反馈移位寄存器XOR门高效实现,这一点很重要。 然后,原理部分需要详细说明。比如,多项式表示,每个二进制位对应多项式的系数,生成多项式是关键。比如CRC-8、CRC-16这些标准生成多项式,用户可能需要例子来理解。比如CRC-8的多项式是x^8 + x^2 + x +1,对应的二进制是100000111,对吧?这样在硬件中用移位寄存器实现,每个位对应多项式的系数,有系数的地方就放一个异或门。 然后,硬件电路的结构。可能需要画一个移位寄存器的示意图,但这里只能用文字描述。比如,移位寄存器的位数等于生成多项式的次数,每个时钟周期输入数据与寄存器的某些位异或后反馈到输入端。引用中的资料提到使用反馈移位寄存器XOR门,这部分需要结合例子说明。 应用场景方面,硬件CRC常用于网络通信、存储设备、数字电视等领域,这些在引用中都有提到。比如以太网用CRC-32,USB用CRC-5CRC-16,用户可能需要具体的例子来理解不同场景下的应用。 另外,硬件实现的优势,比如速度快、低延迟,适合实时处理,这也是需要强调的。同时,可能存在的优化方法,比如并行计算,但硬件通常已经优化到位,所以可能不需要太多优化,不过用户的问题里可能有相关,所以需要准备回答相关问题。 用户的问题可能包括CRC的生成多项式选择,如何设计硬件电路,应用场景的区别,以及错误检测能力。根据引用中的资料,CRC在检测单比特多比特错误时非常可靠,这点需要提到。 最后,生成相关问题的时候,要考虑用户可能的后续疑问,比如如何选择多项式,硬件软件实现的区别,应用中的具体案例,错误检测的原理等。确保问题覆盖原理、实现、应用优化等方面。</think>### 硬件实现的循环冗余校验(CRC)原理及应用 #### 一、CRC的基本原理 循环冗余校验(CRC)是一种基于多项式除法的错误检测技术,其核心是通过对数据包进行模2除法运算生成固定长度的校验码。具体原理如下: 1. **多项式表示** 所有二进制数据可视为多项式系数。例如,数据`1011`对应多项式 $x^3 + x + 1$,而生成多项式(如CRC-8的 $x^8 + x^2 + x + 1$)决定了校验规则[^3][^4]。 2. **模2除法** 发送端将数据多项式与生成多项式进行模2除法(无进位减法),余数即为校验码;接收端重新计算并比对余数以判断数据是否出错。 #### 二、硬件实现方式 硬件CRC通过**线性反馈移位寄存器(LFSR)**实现,具有高效、低延迟的特点。以下以CRC-8为例说明电路结构: 1. **电路组成** - 移位寄存器位数 = 生成多项式最高次数(如CRC-8需8位寄存器)。 - 反馈路径:根据生成多项式的非零系数设置异或门(XOR)位置。例如,多项式 $x^8 + x^2 + x + 1$ 对应反馈路径在bit 0、1、2处插入XOR。 ```plaintext 输入数据 → XOR → [Reg7] → [Reg6] → ... → [Reg0] → XOR → 反馈至Reg7 ``` 2. **工作流程** - **初始化**:寄存器清零。 - **数据输入**:逐比特输入数据,每个时钟周期触发一次移位XOR运算。 - **输出校验码**:数据输入完成后,寄存器中存储的值即为CRC校验码。 #### 三、硬件CRC的优势 1. **高速处理**:并行计算能力适合高速通信场景(如以太网、USB)。 2. **低资源占用**:仅需移位寄存器少量逻辑门,易于集成到ASIC或FPGA中[^1][^3]。 #### 四、典型应用场景 1. **网络通信** - 以太网(CRC-32)、USB(CRC-5/CRC-16)使用硬件CRC校验数据帧完整性。 2. **存储系统** - SSD硬盘通过CRC检测存储介质的数据错误。 3. **数字广播** - 数字电视信号(如DVB标准)依赖CRC确保传输可靠性。 #### 五、硬件实现示例(Verilog代码片段) ```verilog module crc8 ( input clk, input rst, input data_in, output reg [7:0] crc_out ); always @(posedge clk or posedge rst) begin if (rst) crc_out <= 8'b0; else begin crc_out[0] <= crc_out[7] ^ data_in; crc_out[1] <= crc_out[0]; crc_out[2] <= crc_out[1] ^ crc_out[7] ^ data_in; crc_out[3] <= crc_out[2]; crc_out[4] <= crc_out[3]; crc_out[5] <= crc_out[4]; crc_out[6] <= crc_out[5]; crc_out[7] <= crc_out[6]; end end endmodule ``` 此代码对应生成多项式 $x^8 + x^2 + x + 1$,反馈逻辑通过异或操作实现。 --- ###
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老李的森林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值