由于STM32的硬件CRC32模块计算的特点,结果与网上主流的CRC-32结果有出入,因此为了兼容ST CRC32与CRC-32 IEEE802.3主流。
特编写下面的程序,用到了STM32的位取反指令来加速,网上也有实现的同类代码。
http://bbs.21ic.com/club/bbs/bbsView.asp?boardid=11
如果要非典(主流)就把下面的FALSE 设为TRUE
要ST的就都设为FALSE
ST的CRC 最后还要异或FINAL_XOR_VALUE
typedef unsigned long crc_16_32;
#define CRC_NAME "CRC-32"
#define POLYNOMIAL 0x04C11DB7L
#define INITIAL_REMAINDER 0xFFFFFFFF
#define FINAL_XOR_VALUE 0xFFFFFFFF
//--------------------------------------------------------
#define REFLECT_DATA FALSE
#define REFLECT_REMAINDER FALSE
//--------------------------------------------------------
#define WIDTH (8 * sizeof(crc_16_32))
#define TOPBIT ((crc_16_32)1 << (WIDTH - 1))
#if (REFLECT_DATA == TRUE)
#undef REFLECT_DATA
//#define REFLECT_DATA(X) (crc_16_32)reflect((X), 8))
//#define REFLECT_DATA(X) ((crc_16_32)reflect((X), WIDTH))
#define REFLECT_DATA(X) ((crc_16_32)revbit(X))
#define reflect_data(X) (crc_16_32)revbit(X))
//#define reflect_data(X) ((crc_16_32)reflect((X),WIDTH))
#else
#undef REFLECT_DATA
#define REFLECT_DATA(X) (X)
#define reflect_data(X) (X)
#endif
#if (REFLECT_REMAINDER == TRUE)
#undef REFLECT_REMAINDER
//#define REFLECT_REMAINDER(X) ((crc_16_32)reflect((X), WIDTH) ^ FINAL_XOR_VALUE)
#define REFLECT_REMAINDER(X) ((crc_16_32)revbit(X)^FINAL_XOR_VALUE)
#define reflect_rmder(X) ((crc_16_32)revbit(X)^FINAL_XOR_VALUE)
//#define reflect_rmder(X) ((crc_16_32)reflect((X), WIDTH) ^ FINAL_XOR_VALUE)
#else
#undef REFLECT_REMAINDER
#define REFLECT_REMAINDER(X) (X)
#define reflect_rmder(X) (X)
#endif
unsigned long reflect(unsigned long data, unsigned char nBits)
{
return(revbit(data));//网上有reflect的通用代码
};
crc_16_32 revbit(crc_16_32 data)
{
asm("rbit r0,r0");
return data;
};
crc_16_32 cal_crc(crc_16_32 *ptr, int len)
{
crc_16_32 xbit;
crc_16_32 data;
crc_16_32 CRC = INITIAL_REMAINDER;
while (len--)
{
xbit = (crc_16_32)1 << 31;//
data = *ptr++;// 下一个数
// data=revbit(data);//输入位序颠倒一下
data=reflect_data(data);
for ( int bits = 0; bits < 32; bits++)// 主流是从( 32 到 0 )
{
if (CRC & TOPBIT)
{
CRC = (CRC<<1)^POLYNOMIAL;
}
else
{
CRC = (CRC<<1);
}
if (data & xbit)
{
CRC ^= POLYNOMIAL;
}
xbit >>= 1;
}//end bit
}
// CRC=revbit(CRC);
// CRC^=0xFFFFFFFF;//输出位序颠倒一下
// return(CRC);
return (reflect_rmder(CRC));
}//end sub
文章评论(0条评论)
登录后参与讨论