我一直在尝试在代码中执行 CRC16 MCRF4XX,但我只成功地在 1 个字节上正确执行了该操作。
我按照这个指南,具体方法:http://www.piclist.com/techref/method/error/quickcrc16.htm 我已经在 https://crccalc.com/ 中测试了相同的字节
代码如下:
register uint32_t i;
uint16_t Crc = 0;
for ( i = 0; i < Len; i++ )
Crc = Utils_CRC16_MCRF4XX(Crc,pData[i]);
return ( Crc );
函数“Utils_CRC16_MCRF4XX”:
uint8_t i;
uint16_t TempByte, CurrentCRC = 0xFFFF;
//make byte 16 bit format
TempByte = (uint16_t)Byte;
for ( i = 0; i < 8; i++ )
{
if ( (CurrentCRC & 0x0001) == (TempByte & 0x0001) )
{
//right shift crc
CurrentCRC >>= 1;
//right shift data
TempByte >>= 1;
}
else
{
CurrentCRC >>= 1;
TempByte >>= 1;
CurrentCRC = CurrentCRC ^ 0x8408; /* 1000 0100 0000 1000 = x^16 + x^12 + x^5 + 1 */
}
}
return ( Crc ^ CurrentCRC);
字节 0x54 的输出将为 0x1B26。 我已尝试将输出与插入的 Crc 进行异或,但加起来不正确。
现在,当我尝试向函数提供超过 1 个字节的数据时,我的问题就开始了。
如果假设我会发送它:0x54 0xFF。 它会给我一个与计算器给出的完全不同的计算结果。
我假设我的错误是在对每个字节执行操作后将字节加在一起。
感谢您的帮助!
最佳答案
您的函数Utils_CRC16_MCRF4XX
应该更新 Crc,但保留其自己的CurrentCRC
变量,该变量与当前CRC值没有关系并重新初始化每次调用时为 0xFFFF。 传入的Crc
参数是当前的CRC,应该更新。
以最小的改变来调整你的函数:
uint16_t Utils_CRC16_MCRF4XX( uint16_t Crc, uint8_t Byte )
{
//make byte 16 bit format
uint16_t TempByte = (uint16_t)Byte;
for( uint8_t i = 0; i < 8; i++ )
{
if( (Crc & 0x0001) == (TempByte & 0x0001) )
{
//right shift crc
Crc >>= 1;
//right shift data
TempByte >>= 1;
}
else
{
Crc >>= 1;
TempByte >>= 1;
Crc = Crc ^ 0x8408;
}
}
return Crc ;
}
在调用此函数的代码中,Crc
必须初始化为 0xFFFF,而不是零:
uint16_t crc( uint8_t* pData, uint32_t Len )
{
uint16_t Crc = 0xffffu ;
for( uint32_t i = 0; i < Len; i++ )
{
Crc = Utils_CRC16_MCRF4XX( Crc, pData[i] );
}
return (Crc);
}
以下测试代码产生与 https://crccalc.com/ 一致的结果 0x6F91:
int main()
{
uint8_t test[] = "123456789" ;
uint16_t c = crc( test, sizeof(test) - 1 ) ;
printf( "%X", (int)c ) ;
return 0 ;
}
应用&
运算符时发生的隐式转换使TempByte
变得多余,因此可以进一步简化:
uint16_t Utils_CRC16_MCRF4XX( uint16_t Crc, uint8_t Byte )
{
for( uint8_t i = 0; i < 8; i++ )
{
if( (Crc & 0x0001) == (Byte & 0x0001) )
{
Crc >>= 1;
Byte >>= 1;
}
else
{
Crc >>= 1;
Byte >>= 1;
Crc = Crc ^ 0x8408;
}
}
return Crc ;
}
调整 https://gist.github.com/aurelj/270bb8af82f65fa645c1 处的解决方案会产生更简洁的解决方案:
uint16_t Utils_CRC16_MCRF4XX( uint16_t Crc, uint8_t Byte )
{
Crc ^= Byte ;
for( uint8_t i = 0; i < 8; i++ )
{
Crc = (Crc & 0x0001) != 0 ? (Crc >> 1) ^ 0x8408 :
Crc >> 1 ;
}
return Crc ;
}
关于c - 计算超过 1 个字节的 CRC16 MCRF4XX 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59486262/