Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
计算CRC16 MCRF4XX超过1字节的问题_C_Embedded_Crc_Calculation_Crc16 - Fatal编程技术网

计算CRC16 MCRF4XX超过1字节的问题

计算CRC16 MCRF4XX超过1字节的问题,c,embedded,crc,calculation,crc16,C,Embedded,Crc,Calculation,Crc16,我一直试图在我的代码中执行CRC16 MCRF4XX,但我只成功地用1个字节正确地执行了它 对于具体方法,我遵循了以下指南: 我已经测试了相同的字节 代码如下: register uint32_t i; uint16_t Crc = 0; for ( i = 0; i < Len; i++ ) Crc = Utils_CRC16_MCRF4XX(Crc,pData[i]); return ( Crc ); 寄存器uint32\u t i; u

我一直试图在我的代码中执行CRC16 MCRF4XX,但我只成功地用1个字节正确地执行了它

对于具体方法,我遵循了以下指南: 我已经测试了相同的字节

代码如下:

register uint32_t i;
    uint16_t Crc = 0;


    for ( i = 0; i < Len; i++ )
        Crc = Utils_CRC16_MCRF4XX(Crc,pData[i]);

    return ( Crc );
寄存器uint32\u t i;
uint16_t Crc=0;
对于(i=0;i
函数“Utils\u CRC16\u MCRF4XX”:

uint8\t i;
uint16_t TempByte,CurrentCRC=0xFFFF;
//生成字节16位格式
TempByte=(uint16_t)字节;
对于(i=0;i<8;i++)
{
如果((当前CRC和0x0001)==(临时字节和0x0001))
{
//右移crc
当前CRC>>=1;
//右移数据
TempByte>>=1;
}
其他的
{
当前CRC>>=1;
TempByte>>=1;
CurrentCRC=CurrentCRC^0x8408;/*1000 0100 0000 1000=x^16+x^12+x^5+1*/
}
}
返回(Crc^CurrentCRC);
字节0x54的输出为0x1B26。 我尝试过用插入的Crc对输出进行异或运算,但结果不正确

现在,当我试图向函数提供超过1字节的数据时,问题就开始了

如果我们假设我会发送它:0x54 0xFF。 它会给我一个完全不同于计算器的计算结果

我假设我的错误是在对每个字节执行操作后,将字节相加


谢谢你的帮助

已完成的代码,包括main()驱动程序


#包括
#包括
uint16_t Utils_CRC16_MCRF4XX(uint16_t crc,uint16_t字节);
int main(int argc,字符**argv){
uint32_t i;
uint16_t crc;
uint8_t数据[200]={0};
uint32_t len;
对于(len=0;len+1>=1;
字节>>=1;
如果(!samelow)crc^=0x8408;/*1000 0100 0000 1000=x^16+x^12+x^5+1*/
}
返回crc;
}

您的函数
Utils\u CRC16\u 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 ;
}
以下测试代码生成的结果0x6F91与以下结果一致:

应用
&
运算符时发生的隐式转换使
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 ;
}
uint16-Utils-CRC16-MCRF4XX(uint16-Crc,uint8-t字节)
{
对于(uint8_t i=0;i<8;i++)
{
如果((Crc&0x0001)==(字节&0x0001))
{
Crc>>=1;
字节>>=1;
}
其他的
{
Crc>>=1;
字节>>=1;
Crc=Crc^0x8408;
}
}
返回Crc;
}
以更简洁的方式调整解决方案:

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 ;
}
uint16-Utils-CRC16-MCRF4XX(uint16-Crc,uint8-t字节)
{
Crc^=字节;
对于(uint8_t i=0;i<8;i++)
{
Crc=(Crc&0x0001)!=0(Crc>>1)^0x8408:
Crc>>1;
}
返回Crc;
}

调用代码在参数中传递CRC,但函数从未使用它,而是在每次调用时设置CurrentCRC=0xffff。我明白你的意思,但正如我所提到的,我尝试了对CRC参数的返回进行XORing,但最终它返回了错误的CRC,计算了2个字节。据我所知,我需要对每个字节进行初始FFFF,如果我错了,请纠正我。你错了。CRC仅在每个字节块之前初始化一次,以计算每个字节的CRC。根据算法的不同,在计算时,您甚至需要输入0字节来代替附加的CRC以获得正确的CRC,在检查时,您将输入附加的CRC并检查结果的CRC是否为0。您可能想阅读更多详细信息。发布完整的代码,而不仅仅是函数体。这将使它更容易,更有可能有人会构建代码来复制您的问题。无论如何,参数
Crc
是当前Crc-
currentCrc
没有任何用途。当然,你不是第一个这样做的人——发明你自己的是不必要的:,不要欺骗自己,
register
做任何有用的事情。在二的补码机上,
crc=(crc>>1)^((0-(crc&1))&0x8408)(无条件)。优化编译器可能会为
生成基本相同的代码:版本。@rcgldr:当然可以,但问题在于修复代码而不是优化代码。鉴于MCRF4XX的性质,我怀疑是否有必要进行进一步优化,并将有利于清晰性。在同一链路上的替代实现甚至不使用位循环,但是如果您必须解释它,如果不需要优化,可能最好不要使用它。在优化CRC时,一次处理8位的查表更常见。我之前的评论只是关于替代?:这就消除了条件性,而且可能已经有优化编译器这样做了。查找表将以牺牲内存为代价优化速度,因此这取决于您要优化的内容。我的观点是,这些都是值得注意的“过早优化”,但考虑到MCRF4XX的低数据速率(通常为70kbps)和小数据长度(32位),可能没有必要
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);
}
int main()
{
    uint8_t test[] = "123456789" ;
    uint16_t c = crc( test, sizeof(test) - 1 ) ;
    printf( "%X", (int)c ) ;

    return 0 ;
}
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 ;
}
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 ;
}