全部例程

循环冗余校验 (CRC)

W55MH32

更新于 2026年8月12日

本篇总结

使用硬件 CRC,计算数据校验值并与软件结果对比。

🔑 KEIL MDK、UART调试、CRC

W55MH32L 内置硬件 CRC 计算单元,使用固定多项式 0x04C11DB7(与以太网 CRC-32 使用相同多项式,但不进行输入输出反转),只需向数据寄存器写入数据即可自动获得 CRC 结果,无需 CPU 参与运算。本示例演示硬件 CRC 计算并与软件实现进行对比验证。

前置工具准备

开始本例程前,请确认以下工具已安装:

  • WIZ UartTool V1.0:串口收发测试工具:点击下载

硬件连接

本例程无需外部硬件连接,CRC 计算完全在芯片内部完成。USART1 用于输出计算结果。

引脚功能方向模式
PA9USART1_TX开发板 → PC复用推挽输出 (AF_PP)
PA10USART1_RXPC → 开发板浮空输入 (IN_FLOATING)

工程结构

工程位于 SDK 内 1.SDK\ModuleDemo\CRC\,核心文件如下:

CRC/
├── USER/
│   ├── main.c            ← CRC硬件计算 + 软件对比 + printf重定向
│   ├── w55mh32_conf.h    ← 外设头文件集中包含
│   ├── w55mh32_it.c/h    ← 中断服务函数
│   ├── system_w55mh32.c/h← 系统初始化(时钟配置)
│   └── startup_w55mh32.s ← 启动文件
└── SYSTEM/
    └── delay/
        └── delay.c/h      ← SysTick 延时函数

步骤1:CRC 硬件计算与软件对比

函数:main() — 使能 CRC 时钟,复位 CRC 单元,逐字写入数据后读取硬件 CRC 结果,同时用软件方法计算 CRC 进行对比。


int main(void)
{
    RCC_ClocksTypeDef clocks;
    delay_init();
    UART_Configuration(115200);
    RCC_GetClocksFreq(&clocks);

    printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, "
           "PCLK2: %3.1fMhz, ADCCLK: %3.1fMhz\n",
           (float)clocks.SYSCLK_Frequency / 1000000,
           (float)clocks.HCLK_Frequency / 1000000,
           (float)clocks.PCLK1_Frequency / 1000000,
           (float)clocks.PCLK2_Frequency / 1000000,
           (float)clocks.ADCCLK_Frequency / 1000000);
    printf("CRC Test.\n");

    /* 使能 CRC 时钟 */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);

    /* 复位 CRC 计算单元 */
    CRC_ResetDR();

    /* 逐字写入数据计算 CRC */
    CRC_CalcBlockCRC((uint32_t *)Data_Buffer, BUFFER_SIZE);
    printf("CRC Value = 0x%08X\n", CRC_GetCRC());

    /* 软件计算 CRC 进行对比 */
    uint32_t sw_crc = 0xFFFFFFFF;
    for (uint32_t i = 0; i < BUFFER_SIZE; i++)
        sw_crc = CRC_CalcCrc_SW(sw_crc, Data_Buffer[i]);
    printf("SW  CRC Value = 0x%08X\n", sw_crc);

    while (1);
}
  

硬件 CRC 使用流程:CRC_ResetDR() 复位 → CRC_CalcBlockCRC() 写入数据 → CRC_GetCRC() 读取结果。硬件 CRC 使用固定多项式 0x04C11DB7,初始值为 0xFFFFFFFF,与软件计算结果一致。

如果你想自定义

  • 换校验数据 → 修改 Data_Buffer 数组内容和 BUFFER_SIZE
  • 逐字计算 → 使用 CRC_CalcCRC() 逐个 32 位字写入,适用于流式数据
  • 验证数据完整性 → 在数据传输前后计算 CRC,对比结果判断数据是否被篡改

编译与下载

Keil MDK 中打开 CRC.uvprojxF7 编译,确认 0 Error(s)。连接 DEBUG USB 口到 PC,F8 下载。

运行验证

打开 WIZ UartTool V1.0,波特率 115200 / 8N1。下载固件并按 RESET 后,串口打印系统时钟信息、硬件 CRC 计算结果和软件 CRC 计算结果,两者应完全一致。

CRC校验计算串口输出结果
WIZ UartTool V1.0 显示 CRC 计算结果:硬件 CRC 与软件 CRC 结果一致

常见问题

Q: 硬件 CRC 和软件 CRC 结果不一致

硬件 CRC 使用固定多项式 0x04C11DB7 和初始值 0xFFFFFFFF。确保软件实现使用相同的参数。注意硬件 CRC 每次写入 32 位字,数据需按 32 位对齐。

Q: CRC 计算结果始终为 0xFFFFFFFF

检查是否在计算前调用了 CRC_ResetDR() 复位 CRC 单元。确认 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE) 已使能 CRC 时钟。

Q: 串口无任何输出

确认 COM 口号正确、波特率 115200,下载后需按 RESET 键启动。检查 printf 重定向的 fputc 函数是否正确实现。

总结

本文基于 W55MH32L 的硬件 CRC 计算单元实现了数据校验功能:

  • 硬件 CRC 使用固定多项式 0x04C11DB7(与以太网 CRC-32 相同多项式,无输入输出反转),只需写入数据即可自动获得结果
  • 通过 CRC_ResetDR()CRC_CalcBlockCRC()CRC_GetCRC() 三步完成计算
  • 硬件计算与软件实现结果完全一致,但硬件方式无需 CPU 参与运算,速度更快
  • 适用于数据传输校验、Flash 完整性检查、配置数据验证等场景

下载本章例程

我们提供完整的工程文件以及配套开发板,方便你随时测试,快速完成产品开发:

开发环境: Keil MDK5 配套开发板