我尝试从编码器计算数据的 CRC6,但无法获得正确的 CRC。 传感器使用的 CRC 具有多项式 0x43,我尝试实现如下 C 函数:
//CRC6 calculation
static uint8_t crc6(uint8_t *data, uint8_t len)
{
uint8_t i = 0;
uint8_t j = 0;
uint8_t crc = 0;
for(i = 0; i < len; i++) {
crc ^= data[i]; // Initial XOR with input data
for(j = 0; j < 8; j++) { // Process each bit of the current byte
if (crc & 0x20) // Check the MSB of the crc
{
crc = (crc << 1) ^ CRC6_POLY; // Shift left and XOR with polynomial if the bit is set
}
else
{
crc <<= 1; // Just shift left
}
crc &= 0x3F; // Ensure crc remains 6-bit
}
}
return crc;
}
我可以提取一些样本数据,其中给出计算出的 CRC 和传感器发回的实际 CRC:
知道我做错了什么吗?
CRC 不一样,我不知道为什么。
编辑:按照datasheet对CRC数据进行了反相,但这仍然没有解决问题。
我这样调用CRC函数:
uint8_t crc1 = crc6(enc1_data, 3);
uint8_t crc2 = crc6(enc2_data, 3);
uint8_t crc1_is = ~(enc1_data[3] >> 2) & 0x3F; //crc is inverted!
uint8_t crc2_is = ~(enc2_data[3] >> 2) & 0x3F; //crc is inverted!
Edit2:我还添加了数据表(第49页是CRC6): https://www.ichaus.de/product/ic-pz-series/#documents
需要在寄存器的高六位计算CRC,而不是低六位。您还需要初始值,可以在
SPI_CRCS
寄存器中找到。它可能会改变,所以如果可能的话你应该阅读它。对于您的示例,初始 CRC 为 0x24
,它向上移动两位以获得初始寄存器值。
static uint8_t crc6(uint8_t const *data, size_t len) {
uint8_t crc = (uint8_t)(0x24 << 2);
for (size_t i = 0; i < len; i++) {
crc ^= data[i];
for (int j = 0; j < 8; j++)
crc = crc & 0x80 ? (crc << 1) ^ (3 << 2) : crc << 1;
}
return crc;
}
这将返回上移两位的 CRC,与 CRC/ERR/WRN 列中的内容相匹配。消息中该值的低两位需要清零,例如
msg[3] & 0xfc
,在与计算出的 CRC 进行比较之前,因为 ERR 和 WRN 位可能不为零,即使它们出现在您的示例中。