CRC16如何使用字节数据?(用于CAN总线实施)



我在为can消息实现CRC16时遇到了一些问题,我遵循了本网站给出的说明https://barrgroup.com/embedded-systems/how-to/crc-calculation-c-code和http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html#ch5,加上我在这里看到的其他含义(例如计算CRC16校验和的函数(。

我不明白它是如何处理的。我在这里的消息是字节形式的,例如char message[4] = {0x12, 0x34, 0x56, 0x78}。当我经历第一个循环时,我只取第一个字节,将其移位8,然后计算remainderPOLYNOME16 bits。这意味着我们有0x1200,我们用它进行第二个循环,这意味着我用存储在remainder中的POLYNOME进行XOR,但我不太明白为什么这样做,尤其是当我看这段代码时,我的消息的2nd3rd4thbytes在某些时候应该通过POLYNOME8 first bits获得XORed,但它们根本没有经过。根据维基百科的解释https://en.wikipedia.org/wiki/Cyclic_redundancy_check多项式一次遍历整个消息,而不是逐字节遍历。我不知道这是如何一个字节一个字节地进行0x12345678的CRC的。

uint16_t Compute_CRC16_Simple(char* message, int nbOfBytes)
{
uint16_t POLYNOME = 0xC599; 
uint16_t remainder = 0; 
for (int byte = 0;byte < nbOfBytes; byte++)
{
remainder ^= (message[byte] << 8); 
for (int i = 0; i < 8; i++)
{
if (remainder  & 0x8000) 
{
remainder = (remainder << 1) ^ POLYNOME ;
}
else
{
remainder <<= 1;
}
}
}
return remainder;
}

我不明白它是如何处理的。

也许它将有助于描述8位数据的逐位操作:

crc[bit15] ^= data[bit7]
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
crc[bit15] ^= data[bit6]
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
...
crc[bit15] ^= data[bit0]
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1

请注意,if语句仅取决于crc[bit15]中的位值,因此与数据的XOR的固定部分可以在一个步骤中完成:

crc[bit15 .. bit8] ^= data[bit7 .. bit0]
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1
...
if(crc[bit15] == 1) crc = (crc << 1) ^ poly
else crc = crc << 1

CRC的循环8次使用那些如果。。。则可以针对crc[bit15.bit8]中的所有256个可能值预先计算(移位+xor-poly(else(仅移位(,并将其存储在用于表查找的表中以将crc循环8次。

相关内容

  • 没有找到相关文章

最新更新