在超过1个字节的情况下计算CRC16 MCRF4XX时出现问题 [英] Issues calculating CRC16 MCRF4XX for more than 1 byte
问题描述
我一直在尝试在我的代码中执行CRC16 MCRF4XX,但是我设法仅对1个字节正确地执行了此操作.
I've been trying to perform CRC16 MCRF4XX in my code however I've managed to do it correctly for only 1 byte.
对于特定的方法,我已遵循本指南: http://www.piclist.com/techref/method/error/quickcrc16.htm 并且我已经在 https://crccalc.com/
I've followed this guide, for the specific method: http://www.piclist.com/techref/method/error/quickcrc16.htm and i've tested the same byte in 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":
the function "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进行XOR运算,但结果加起来不正确.
the output for byte 0x54 would be 0x1B26. I've tried XORing the output with the inserted Crc, but it doesn't add up right.
现在,当我尝试提供1个字节以上的函数时,我的问题就开始了.
now my issue starts when I'm trying to feed the function more than 1 byte.
如果让我发送:0x54 0xFF.它将给我与计算器提供的完全不同的计算.
if let's say i would send it : 0x54 0xFF. it would give me a totally different calculation than the calculator gives.
我假设我的错误是在对每个字节执行操作之后我将这些字节加起来.
I'm assuming my error is where i add up the bytes together, after performing the action on each byte.
感谢帮助!
推荐答案
您的函数 Utils_CRC16_MCRF4XX
应该更新 Crc,但保留其自己的 CurrentCRC
与当前CRC值没有任何关系的变量,并且在每次调用时都重新初始化为0xFFFF.传入的 Crc
参数是当前的CRC,应该对其进行更新.
Your function Utils_CRC16_MCRF4XX
should update the Crc, but keeps its own CurrentCRC
variable that bares no relationship to the current CRC value and is reinitialised to 0xFFFF on each call. The Crc
parameter passed in is teh current CRC and that should be updated.
以最小的更改适应您的功能:
Adapting your function with minimal changes:
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,而不是零:
In the code that calls this, the Crc
must be initialised to 0xFFFF, not zero:
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);
}
以下测试代码产生的结果0x6F91与 https://crccalc.com/一致:
The following test code, produces the result 0x6F91 which concurs with https://crccalc.com/:
int main()
{
uint8_t test[] = "123456789" ;
uint16_t c = crc( test, sizeof(test) - 1 ) ;
printf( "%X", (int)c ) ;
return 0 ;
}
应用&
运算符时发生的隐式转换使 TempByte
变得多余,因此可以进一步简化:
The implicit conversion that occurs when applying the &
operator make TempByte
redundant so further simplification is possible:
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 ;
}
在
Adapting the solution at https://gist.github.com/aurelj/270bb8af82f65fa645c1 yields the somewhat more succinct solution:
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 ;
}
这篇关于在超过1个字节的情况下计算CRC16 MCRF4XX时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!