计算CRC16 MCRF4XX超过1字节的问题
我一直试图在我的代码中执行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
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 ;
}