c - 这个 CRC6 片段给出了错误的结果
问题描述
生成 CRC6 的代码片段没有给出正确的值。代码片段中的问题可能是什么?
SPI_CRC6 = X6 + X4 + X3 + X + 1
初始种子值为0x3F
Input data: 24 bit。
一些经过测试的示例值:(不是来自代码片段)
24b input: 0xAE0000, CRC6: 0x11
24b input: 0x950055, CRC6: 0x22
/* CRC6 calculation */
Uint16 crc2(Uint32 datin)
{
Uint16 byte_idx, bit_idx, crc = (0x3F << 2);//CRC_INITSEED = 0x3f
/* byte by byte starting from most significant (3-2-1) */
for (byte_idx = 3; byte_idx >= 1; byte_idx--)
{
/* XOR-in new byte from left to right */
crc ^= ((datin >> (byte_idx << 3)) & 0x000000FF);
/* bit by bit for each byte */
for (bit_idx = 0; bit_idx < 8; bit_idx++)
{
crc = crc << 1 ^ (crc & 0x80 ? (0x5B << 2) : 0);//CRC Polynom: 0x5B
}
}
return (crc >> 2 & 0x3F); /*restore two bit offset */
}
解决方案
user3386109 的答案显示了您的代码的更正版本,但在这种情况下,无需将 datain 拆分为 6 位字段。
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
uint16_t crc1(uint32_t datin)
{
int i;
uint32_t crc = datin ^ (0x3f << 18);
for (i = 0; i < 24; i++)
crc = (crc << 1) ^ ((crc & 0x800000) ? (0x5B << 18) : 0);
return crc >> 18;
}
以下示例假定使用二进制补码数学,使用 (-0) = 0x00000000 或 (-1) = 0xffffffff 作为掩码以避免使用条件代码(十进制 ? : )。请注意,优化编译器也可以使用数学来避免上述示例的条件代码(Visual Studio 会这样做)。
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
uint16_t crc1(uint32_t datin)
{
int i;
uint32_t crc = datin ^ (0x3f << 18);
for (i = 0; i < 24; i++)
crc = (crc << 1) ^ ((-(crc >> 23)) & (0x5B << 18));
return crc >> 18;
}
编译器经常使用掩码技巧,一般顺序是:
... ;eax is zero or non-zero
neg eax ;sets borrow bit if eax != 0
sbb eax,eax ;eax = 0x00000000 or 0xffffffff
and eax,... ;use eax as mask
推荐阅读
- ios - iOS中的Firebase身份验证重新发送验证码
- python - 在 Python 中列出删除重复项
- html - [src]="sermon?.sermonVideo" 不工作。虽然它适用于图片
- java - 如何找到树中两个节点之间的路径?
- c - Scala 的 Option 或 Rust 的 C 中的 Result 错误处理
- font-size - 如何增加 xy 图点的大小
- pandas - DataFrame中缺失记录的可视化
- javascript - 对 Docusaurus 进行上游操作并确保文件加载顺序正确
- javascript - 如何查找 ReactInstance 的所有子图像
- php - html-php 在同一页面上发布表单 - iframe 问题