如何利用Nucleo L053R8 CRC计算单元实现指定多项式的CRC24计算?
用Nucleo L053R8的32位CRC单元计算目标24位CRC的解决方案
我来帮你搞定这个问题——其实核心是把24位CRC的计算逻辑映射到32位CRC单元上,通过配置参数、处理输入和调整结果来实现。以下是具体的分步操作,都是针对STM32 L0系列CRC外设的:
1. 先明确目标CRC的核心参数
你提到的多项式g(X)=x^24 + x^10 + x^9 + x^6 + x^4 + x^3 + x + 1对应的是CRC24/OPENPGP标准,它的关键参数是:
- 宽度:24位
- 初始值:
0xFFFFFF(全1) - 输入位序:无反转(MSB先入)
- 输出位序:反转(LSB先出)
- 最终异或值:
0x000000(无额外异或)
2. 配置CRC外设的寄存器
STM32 L0的CRC单元是32位的,但我们可以通过配置让它适配24位CRC的计算:
- 复位CRC单元:先重置CRC寄存器到初始值,确保每次计算环境干净:
CRC->CR |= CRC_CR_RESET; while (CRC->CR & CRC_CR_RESET); // 等待复位完成 - 设置多项式寄存器:STM32的CRC寄存器存储的是多项式去掉最高次项(这里是
x^24)后的系数,所以我们要写入0x0000065B:CRC->POL = 0x0000065B; - 设置初始值:把目标24位初始值
0xFFFFFF填充到32位初始寄存器的低24位:CRC->INIT = 0xFFFFFF; - 配置输入位序:设置为无反转(MSB先入),匹配目标CRC的输入要求:
CRC->CR &= ~CRC_CR_REV_IN_Msk; // 清除原有位序设置 CRC->CR |= 0x0 << CRC_CR_REV_IN_Pos; // 选择无反转模式 - 配置输出位序:开启输出反转,匹配目标CRC的输出要求:
CRC->CR |= CRC_CR_REV_OUT; - 关闭输出异或:目标CRC不需要最终异或操作,所以关闭这个功能:
CRC->CR &= ~CRC_CR_XOR_OUT;
3. 输入待计算的3字节数据
直接按顺序将每个字节写入CRC的数据寄存器(CRC->DR)即可,外设会自动按配置的位序处理每个字节:
// 假设待计算的3字节数据存在byte0、byte1、byte2中 CRC->DR = byte0; CRC->DR = byte1; CRC->DR = byte2;
注意:如果你的数据是按32位变量存储的(比如低24位是有效数据),也可以直接写入一次32位值,但要确保高8位填0,结果是一致的。
4. 获取并提取正确的24位CRC结果
计算完成后,读取CRC->DR的32位值,只需要保留低24位就是我们要的CRC24结果:
uint32_t crc32_result = CRC->DR; uint32_t crc24_result = crc32_result & 0xFFFFFF; // 提取低24位
因为我们配置的多项式高8位系数都是0,计算过程中CRC寄存器的高8位会始终保持初始的0,所以直接截断低24位就得到了正确结果。
验证小技巧
你可以用已知测试数据验证:比如输入字节0x00 0x00 0x00,对应的CRC24/OPENPGP结果是0xB704CE;输入0x01 0x02 0x03,结果是0x8F09D6。用上面的代码计算,应该能得到一致的结果。
内容的提问来源于stack exchange,提问作者Abyr
相关产品推荐
相关产品推荐

