国产MCU学习Day16——CW32F030C8T6 深入解析CRC校验算法与应用

每日更新教程,评论区答疑解惑,小白也能变大神!"

目录

一.循环冗余校验(CRC)

二.案例-10种不同CRC算法

关键点

一.循环冗余校验(CRC)

1.1 概述

循环冗余校验 (CRC) 主要应用于核实数据传输或数据存储的正确性和完整性。

CW32x030 内部集成 CRC 计算单元, 支持采用多种 CRC 算法对输入数据进行 CRC 计算。

1.2 主要特性

  •         3 种输入数据位宽:8bit、16bit、32bit
  •         3 种多项式: ‒ CRC-16
  •                 多项式 1:x16 + x15 + x2 + 1 ‒ CRC-16
  •                 多项式 2:x16 + x12 + x5 + 1 ‒ CRC-32
  •                 多项式:x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x +1
  •         10 种常用的算法 基于多项式,初始值,结果异或值,输入 / 输出反转的组合。

1.3 功能描述

  • CRC 单元通过对输入数据 ( 或输入数据的反转 ) 和选定的多项式值进行‘除’运算,得到的余数再进行反转或者 不反转,以及异或处理,得到 CRC 计算结果。
  • CRC 单元在使用之前,需要设置 SYSCTRL_AHBEN.CRC 为 1,打开 CRC 单元的配置时钟及工作时钟,一般在系 统初始化时进行设置。

1.4 算法模式

  • CW32x030的 CRC单元支持多种算法模式。不同的 CRC算法,对应的多项式、初始值、输入数据反转、输出数据反转、 结果异或值等参数不同,如下表所示:
  • 各参数含义如下:
  • 多项式值
    • 多项式是码组的描述,如 CRC-16 多项式 2:x16 + x 12 + x 5 + 1,对应的码组是 1 0001 0000 0010 0001。因为 多项式码组的最高位固定为 1,且最高位的位置已知,因此一般将最高位 1 去掉后的码组称为多项式值,如 CRC-16 多项式 2 的值为 0001 0000 0010 0001,即 0x1021。
  • 初始值
    • 在计算 CRC 校验值之前,CRC 寄存器的初始值。
  • 输入数据反转 即在计算开始前,将需要计算 CRC 校验值的数据进行高低序位反转,如数据位 1011,反转后为 1101。
  • 输出数据反转 在 CRC 计算结束后,与结果异或值进行异或之前,将计算值进行高低序位反转,如计算结果为 1011,反转 后为 1101。
  • 结果异或值 在 CRC 计算结束后,得到的 CRC 计算值与结果异或值进行异或操作,就得到了最终的 CRC 校验值。

1.5输入数据位宽

CRC 计算单元支持三种输入数据位宽:8bit、16bit、32bit。输入数据位宽和算法没有对应关系,但和写入的寄 存器位宽要保持一致。为保证同样一组数据采用不同的输入数据位宽计算得到的 CRC 校验码相同,需要遵循如下 原则:

● 每次输入的数据类型应与寄存器位宽一致

● 先输入低字节再输入高字节

例如,用户需要计算 0x00, 0x11, 0x22 , 0x33, 0x44, 0x55, 0x66, 0x77 这一组数据的 CRC 校验值,对应不同输入数 据位宽示例如下:

1. 8bit 输入数据位宽时,写入顺序:0x00, 0x11, 0x22 , 0x33, 0x44, 0x55, 0x66, 0x77

代码示例:

CW_CRC -> DR8 = 0x00 ;

CW_CRC -> DR8 = 0x11 ;

CW_CRC -> DR8 = 0x22 ;

CW_CRC -> DR8 = 0x33 ;

CW_CRC -> DR8 = 0x44 ;

CW_CRC -> DR8 = 0x55 ;

CW_CRC -> DR8 = 0x66 ;

CW_CRC -> DR8 = 0x77 ;

2. 16bit 输入数据位宽时,写入顺序:0x1100, 0x3322, 0x5544, 0x7766

代码示例:

CW_CRC -> DR16 = 0x1100 ;

CW_CRC -> DR16 = 0x3322 ;

CW_CRC -> DR16 = 0x5544 ;

CW_CRC -> DR16 = 0x7766 ;

3. 32bit 输入数据位宽时,写入顺序: 0x3322 1100, 0x7766 5544

代码示例:

CW_CRC -> DR32 = 0x3322 1100 ;

 CW_CRC -> DR32 = 0x7755 6644 ;

1.6编程示例

CRC16_CCITT 算法模式

步骤 1:设置 CRC_CR.MODE 为 0x04,选择 CRC16_CCITT 算法模式,硬件自动配置 CRC 寄存器初始值为 0x0000;

步骤 2:将待编码的原始数据依次写入数据寄存器 CRC_DR ,输入数据位宽可选择 8bit、16bit、32bit 。请参见 10.3.2 输入数据位宽中的代码示例;

步骤 3:读取 CRC_RESULT[15:0] 获取 CRC 校验值。

代码示例:

tempdata = CW_CRC -> RESULT16 ;

1.7CRC32 算法模式

步骤 1:设置 CRC_CR.MODE 为 0x08,选择 CRC32 算法模式,硬件自动配置 CRC 寄存器初始值为 0xFFFF FFFF;

步骤 2:将待编码的原始数据依次写入数据寄存器 CRC_DR,输入数据位宽可选择 8bit、16bit、32bit 。请参见 10.3.2 输入数据位宽中的代码示例;

步骤 3:读取 CRC_RESULT[31:0] 获取 CRC 校验值。

代码示例:

tempdata = CW_CRC -> RESULT32 ;

1.8寄存器列表

二.案例-10种不同CRC算法

uint32_t tmp1, tmp2, tmp3;  // 定义三个临时变量用于存储CRC计算结果

//=========================================================================
// 主函数入口
int32_t main(void)
{
    // 定义测试数据:8位、16位、32位数组,内容相同但存储格式不同
    uint8_t  Raw08[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };  // 字节数组
    uint16_t Raw16[4] = { 0x1100, 0x3322, 0x5544, 0x7766 };                  // 半字数组(小端模式)
    uint32_t Raw32[2] = { 0x33221100, 0x77665544 };                          // 字数组(小端模式)
    
    //=========================================================================
    // 启用CRC模块时钟(通过系统控制寄存器配置)
    CW_SYSCTRL->AHBEN_f.CRC = 1;

    //=========================================================================
    // CRC16_IBM算法测试:验证不同位宽计算结果的正确性
    tmp1 = CRC16_Calc_8bit(CRC16_IBM, Raw08, 8);   // 按字节计算CRC16
    tmp2 = CRC16_Calc_16bit(CRC16_IBM, Raw16, 4);  // 按半字计算CRC16
    tmp3 = CRC16_Calc_32bit(CRC16_IBM, Raw32, 2);  // 按字计算CRC16
    __asm("BKPT  0");  // 断点调试,观察tmp1/tmp2/tmp3是否相等

    // CRC16_MAXIM算法测试(同上)
    tmp1 = CRC16_Calc_8bit(CRC16_MAXIM, Raw08, 8);
    tmp2 = CRC16_Calc_16bit(CRC16_MAXIM, Raw16, 4);
    tmp3 = CRC16_Calc_32bit(CRC16_MAXIM, Raw32, 2);
    __asm("BKPT  0");

    // CRC16_USB算法测试(同上)
    tmp1 = CRC16_Calc_8bit(CRC16_USB, Raw08, 8);
    tmp2 = CRC16_Calc_16bit(CRC16_USB, Raw16, 4);
    tmp3 = CRC16_Calc_32bit(CRC16_USB, Raw32, 2);
    __asm("BKPT  0");

    // CRC16_MODBUS算法测试(同上)
    tmp1 = CRC16_Calc_8bit(CRC16_MODBUS, Raw08, 8);
    tmp2 = CRC16_Calc_16bit(CRC16_MODBUS, Raw16, 4);
    tmp3 = CRC16_Calc_32bit(CRC16_MODBUS, Raw32, 2);
    __asm("BKPT  0");

    // CRC16_CCITT算法测试(同上)
    tmp1 = CRC16_Calc_8bit(CRC16_CCITT, Raw08, 8);
    tmp2 = CRC16_Calc_16bit(CRC16_CCITT, Raw16, 4);
    tmp3 = CRC16_Calc_32bit(CRC16_CCITT, Raw32, 2);
    __asm("BKPT  0");

    // CRC16_CCITTFALSE算法测试(同上)
    tmp1 = CRC16_Calc_8bit(CRC16_CCITTFALSE, Raw08, 8);
    tmp2 = CRC16_Calc_16bit(CRC16_CCITTFALSE, Raw16, 4);
    tmp3 = CRC16_Calc_32bit(CRC16_CCITTFALSE, Raw32, 2);
    __asm("BKPT  0");

    // CRC16_X25算法测试(同上)
    tmp1 = CRC16_Calc_8bit(CRC16_X25, Raw08, 8);
    tmp2 = CRC16_Calc_16bit(CRC16_X25, Raw16, 4);
    tmp3 = CRC16_Calc_32bit(CRC16_X25, Raw32, 2);
    __asm("BKPT  0");

    // CRC16_XMODEM算法测试(同上)
    tmp1 = CRC16_Calc_8bit(CRC16_XMODEM, Raw08, 8);
    tmp2 = CRC16_Calc_16bit(CRC16_XMODEM, Raw16, 4);
    tmp3 = CRC16_Calc_32bit(CRC16_XMODEM, Raw32, 2);
    __asm("BKPT  0");

    //=========================================================================
    // CRC32_DEFAULT算法测试:验证不同位宽计算结果的正确性
    tmp1 = CRC32_Calc_8bit(CRC32_DEFAULT, Raw08, 8);   // 按字节计算CRC32
    tmp2 = CRC32_Calc_16bit(CRC32_DEFAULT, Raw16, 4);  // 按半字计算CRC32
    tmp3 = CRC32_Calc_32bit(CRC32_DEFAULT, Raw32, 2);  // 按字计算CRC32
    __asm("BKPT  0");

    // CRC32_MPEG2算法测试(同上)
    tmp1 = CRC32_Calc_8bit(CRC32_MPEG2, Raw08, 8);
    tmp2 = CRC32_Calc_16bit(CRC32_MPEG2, Raw16, 4);
    tmp3 = CRC32_Calc_32bit(CRC32_MPEG2, Raw32, 2);
    __asm("BKPT  0");

    // 主循环(保持程序运行)
    while (1)
    {
        ;
    }
}

关键点

  1. 数据格式

    • Raw08Raw16Raw32存储相同数据,但分别以8位、16位、32位形式组织,用于测试不同位宽的CRC计算兼容性。
  2. CRC算法类型

    • 测试了多种标准CRC算法(如IBM、MODBUS、XMODEM等),每种算法通过8/16/32位接口计算,预期结果应一致。
  3. 调试机制

    • __asm("BKPT 0")为嵌入式调试断点,用于观察变量值,验证不同计算方式的结果一致性。
  4. 硬件依赖

    • CW_SYSCTRL->AHBEN_f.CRC = 1启用硬件CRC模块时钟

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值