crc16.c

来自「我做的用lpc2119实现的变电站隔刀动作电流波形采样计算数据上传程序」· C语言 代码 · 共 596 行 · 第 1/2 页

C
596
字号
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
} ;


//CRC低位字节值表 
static char auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;
*/


uint16 CRC_16(uint8 * aData, uint16 aSize )
{
    uint16  i;
    uint16 nAccum = 0xffff;

    for ( i = 0; i < aSize; i++ )
        nAccum = ( nAccum << 8 ) ^ (uint16)modbus_crc16[( nAccum >> 8 ) ^ *aData++];
    return nAccum;
}

uint16 CRC_16a(uint8 * aData,SampleData1 * bData, uint16 aSize, uint16 bSize )
{
    uint16  i;
    uint16 nAccum = 0xffff;
   
    for ( i = 0; i < aSize; i++ )
        nAccum = ( nAccum << 8 ) ^ (uint16)modbus_crc16[( nAccum >> 8 ) ^ *aData++];
    for ( i = 0; i < bSize; i++ )
    {
    	nAccum = ( nAccum << 8 ) ^ (uint16)modbus_crc16[( nAccum >> 8 ) ^ bData->byte.high];
    	nAccum = ( nAccum << 8 ) ^ (uint16)modbus_crc16[( nAccum >> 8 ) ^ bData->byte.low];
    	bData++;
    }
    return nAccum;
}

uint16 CRC_16b(uint16 Data,SampleData1 * bData)
{
    uint16  i;
    uint16 nAccum = Data;
   
    nAccum = ( nAccum << 8 ) ^ (uint16)modbus_crc16[( nAccum >> 8 ) ^ bData->byte.high];
    nAccum = ( nAccum << 8 ) ^ (uint16)modbus_crc16[( nAccum >> 8 ) ^ bData->byte.low];
    
    return nAccum;
}


uint16 udf_crc(uint8 *data, uint32 size, uint16 crc)
{
	crc=0xffff;  //test
	while (size--)
		crc = modbus_crc16[(crc >> 8 ^ *(data++)) & 0xffU] ^ (crc << 8);

	return crc;
}
  
 uint16 crc16_byte(uint16 crc, uint8 data)
 {
        return (crc << 8) ^ modbus_crc16[(crc>>8 ^ data) & 0xff];
 }

 
 uint16 crc16(uint16 crc, uint8 *buffer, uint16 len)    
 {                  
 		crc=0xffff; //test                              
        while (len--)                             
                 crc = crc16_byte(crc, *buffer++);    
         return crc;                               
 }               
 
 
uint16 modbusCRC16(uint8 *puchMsg, uint16 usDataLen)	//*puchMsg 要进行CRC 校验的消息 usDataLen 消息中字节数
{
	uint8 uchCRCHi = 0xff ; 							/* 高CRC 字节初始化*/
	uint8 uchCRCLo = 0xff ; 							/* 低CRC 字节初始化*/
	uint8 temp;
	uint8 uIndex ; 									/* CRC 循环中的索引*/
	while (usDataLen--) 								/* 传输消息缓冲区*/
	{
		uIndex = uchCRCHi ^ *puchMsg++ ; 				/* 计算CRC */
		//temp=
		uchCRCHi = uchCRCLo ^ (modbus_crc16[uIndex] >>8) ;
		uchCRCLo = modbus_crc16[uIndex] & 0xff ;
		//uIndex = temp ^ *puchMsg++ ; 
		//temp=temp<<8 ^ (crc16_tablea[uIndex] & 0xff) ;
	}
	return ( uchCRCLo << 8 | uchCRCHi) ;
	//return (temp);
}

#define maskcrc 0xa001

uint16 crc16r(uint8 *ptr, uint16 len)
{
	uint8 i;
	uint16 crc=0xffff;
	while(len--!=0)
	{
		crc ^= (*ptr++);
		for(i=0;i<8;i++)
		{
			if((crc&0x0001)!=0) {crc >>= 1; crc ^= maskcrc;}
				else crc >>= 1;
			
		}
		
		
	}
	
	return(crc);
}

uint16 CRC16b(uint8 *Array,uint16 Len)
{
	uint16  IX,IY,CRCa;
	//uint8 *Rcvbuf;
	CRCa=0xffff;//set all 1
	

	if (Len==0) 
  		CRCa = 0;
	else
	{
  		//Len--;
  		for (IX=0;IX<Len;IX++)
  		{
  			CRCa=CRCa^(uint16)(*Array);
  			for(IY=0;IY<8;IY++)
  			{
  				if ((CRCa & 1)!=0 )
   					CRCa=(CRCa>>1)^0xA001;      
   				else
    				CRCa=CRCa>>1;    //
    		}
    		Array++;
  		}
  
	}
	//Rcvbuf[0] = (CRCa & 0xff00)>>8;//高位置
	//Rcvbuf[1] = (CRCa & 0x00ff);  //低位置
	return CRCa;
}


uint16   crc_gen(uint8  data[],uint16   num)   
  {   
          uint16   i,j;   
          uint16   code,carry;   
          code=0xffff;   
          for(i=0;i<num;i++)   
          {   
                  code=code   ^data[i];   
                  for(j=0;j<8;j++)   
                  {   
                  	carry=code   &0x0001;   
                  	code=code>>1;   
                  	if(carry==1)code=code^0xa001;   
                  }   
          }   
          return   code;   
  }
  
  
uint16 WNCRC16(uint16 usStartValue, uint16 usPolynomial,uint8 *pby, uint16 ilen)
{
	uint16 usCRC16 = usStartValue;
	uint16 usTemp1 = 0;
	uint16 usTemp2 = 0;
	uint16 usFlag = 0;
	uint8 byTemp = 0x00;
	uint16 i=0; 
	uint16 j=0;
 	for(i=0; i<ilen ; i++)
 	{ 
  		byTemp = pby[i];
  		usCRC16 = usCRC16^byTemp;

  		for(j=0; j<8; j++)
  		{
       		usFlag = usCRC16 & 0x0001;
       		usTemp1 = (usCRC16>>1);
            if(usFlag == 0)
       		{
           		usTemp2=0;
       		}
       		else
       		{
    			usTemp2 = usPolynomial;
       		}

       		usCRC16 = usTemp1^usTemp2;  
  		}
 	}

 	return usCRC16;
}


void BuildTable16(uint16 aPoly, uint16 Table_CRC[256])
{
    uint16 i, j;
    uint16 nData;
    uint16 nAccum;

    for ( i = 0; i < 256; i++ )
    {
        nData = ( uint16 )( i << 8 );
        nAccum = 0;
        for ( j = 0; j < 8; j++ )
        {
            if ( ( nData ^ nAccum ) & 0x8000 )
                nAccum = ( nAccum << 1 ) ^ aPoly;
            else
                nAccum <<= 1;
            nData <<= 1;
        }
        Table_CRC[i] = ( uint16 )nAccum;
    }
}

#define GX 0x1021
void BuildTable16a(uint16 aPoly, uint16 Table_CRC[256])
{
	uint16 i;
	uint16 crc;
	uint8 n,tmp;
	for(i =0; i<256; i++)
    {
		crc = i << 8;
		for(n=0; n<8; n++)
		{
			if(crc & (1<<15))
				crc ^= GX;
            else
				crc <<= 1;
		}
		Table_CRC[i]  = crc;
	}
}



uint16 CRC162(uint8 *ptr,uint16 len)
{
	uint16 CRCtbl[16]={ /* CRC余式表 */
	0x0000,0xCC01,0xD801,0x1400,0xF001,0x3C00,0x2800,0xE401,
	0xA001,0x6C00,0x7800,0xB401,0x5000,0x9C01,0x8801,0x4400
	};
	uint16 crc=0xffff;
	uint8  da;
	while(len--!=0)
	{
		da = crc^*ptr;
		crc >>= 4;
		crc ^= CRCtbl[da&0x0f];
		da = crc^((*ptr)>>4);
		crc >>= 4;
		crc ^= CRCtbl[da&0x0f];
		ptr++;
	}
	return(crc);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?