在超过1个字节的情况下计算CRC16 MCRF4XX时出现问题 [英] Issues calculating CRC16 MCRF4XX for more than 1 byte

查看:188
本文介绍了在超过1个字节的情况下计算CRC16 MCRF4XX时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试在我的代码中执行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 ;
}

https://gist.github.com/aurelj/270bb8af82f65fa645c1 产生更简洁的解决方案:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆