原创 CRC-32 CALCULATE CRC32计算

2009-4-16 11:47 3950 11 11 分类: MCU/ 嵌入式

由于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

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
11
关闭 站长推荐上一条 /3 下一条