122 lines
4.0 KiB
C
122 lines
4.0 KiB
C
|
||
#include "crc.h"
|
||
//#include <stdio.h> //用于验证和生成CRC_Table
|
||
|
||
//X8+X4+X3+X2+1 -> 0X1D -> POLY=B8
|
||
static const unsigned char crc_table[] =
|
||
{
|
||
0x00, 0xb8, 0xc8, 0x70, 0x28, 0x90, 0xe0, 0x58, 0x50, 0xe8, 0x98, 0x20, 0x78, 0xc0, 0xb0, 0x08,
|
||
0xa0, 0x18, 0x68, 0xd0, 0x88, 0x30, 0x40, 0xf8, 0xf0, 0x48, 0x38, 0x80, 0xd8, 0x60, 0x10, 0xa8,
|
||
0xf8, 0x40, 0x30, 0x88, 0xd0, 0x68, 0x18, 0xa0, 0xa8, 0x10, 0x60, 0xd8, 0x80, 0x38, 0x48, 0xf0,
|
||
0x58, 0xe0, 0x90, 0x28, 0x70, 0xc8, 0xb8, 0x00, 0x08, 0xb0, 0xc0, 0x78, 0x20, 0x98, 0xe8, 0x50,
|
||
0x48, 0xf0, 0x80, 0x38, 0x60, 0xd8, 0xa8, 0x10, 0x18, 0xa0, 0xd0, 0x68, 0x30, 0x88, 0xf8, 0x40,
|
||
0xe8, 0x50, 0x20, 0x98, 0xc0, 0x78, 0x08, 0xb0, 0xb8, 0x00, 0x70, 0xc8, 0x90, 0x28, 0x58, 0xe0,
|
||
0xb0, 0x08, 0x78, 0xc0, 0x98, 0x20, 0x50, 0xe8, 0xe0, 0x58, 0x28, 0x90, 0xc8, 0x70, 0x00, 0xb8,
|
||
0x10, 0xa8, 0xd8, 0x60, 0x38, 0x80, 0xf0, 0x48, 0x40, 0xf8, 0x88, 0x30, 0x68, 0xd0, 0xa0, 0x18,
|
||
0x90, 0x28, 0x58, 0xe0, 0xb8, 0x00, 0x70, 0xc8, 0xc0, 0x78, 0x08, 0xb0, 0xe8, 0x50, 0x20, 0x98,
|
||
0x30, 0x88, 0xf8, 0x40, 0x18, 0xa0, 0xd0, 0x68, 0x60, 0xd8, 0xa8, 0x10, 0x48, 0xf0, 0x80, 0x38,
|
||
0x68, 0xd0, 0xa0, 0x18, 0x40, 0xf8, 0x88, 0x30, 0x38, 0x80, 0xf0, 0x48, 0x10, 0xa8, 0xd8, 0x60,
|
||
0xc8, 0x70, 0x00, 0xb8, 0xe0, 0x58, 0x28, 0x90, 0x98, 0x20, 0x50, 0xe8, 0xb0, 0x08, 0x78, 0xc0,
|
||
0xd8, 0x60, 0x10, 0xa8, 0xf0, 0x48, 0x38, 0x80, 0x88, 0x30, 0x40, 0xf8, 0xa0, 0x18, 0x68, 0xd0,
|
||
0x78, 0xc0, 0xb0, 0x08, 0x50, 0xe8, 0x98, 0x20, 0x28, 0x90, 0xe0, 0x58, 0x00, 0xb8, 0xc8, 0x70,
|
||
0x20, 0x98, 0xe8, 0x50, 0x08, 0xb0, 0xc0, 0x78, 0x70, 0xc8, 0xb8, 0x00, 0x58, 0xe0, 0x90, 0x28,
|
||
0x80, 0x38, 0x48, 0xf0, 0xa8, 0x10, 0x60, 0xd8, 0xd0, 0x68, 0x18, 0xa0, 0xf8, 0x40, 0x30, 0x88,
|
||
};
|
||
|
||
unsigned char CRC_Calc(unsigned char * dataptr,unsigned char len)
|
||
{
|
||
unsigned char i;
|
||
unsigned char crc=0xFF; // 计算的初始crc值
|
||
|
||
while(len--)
|
||
{
|
||
crc ^= *dataptr++; // 每次先与需要计算的数据异或,计算完指向下一数据
|
||
for (i=0; i<8; i++) // 下面这段计算过程与计算一个字节crc一样
|
||
{
|
||
if (crc & 0x80) // 判断最高位是否为1
|
||
// 最高位为1,不需要异或,往左移一位,然后与0x31异或
|
||
// 0x31(多项式:x8+x5+x4+1,100110001),最高位不需要异或,直接去掉
|
||
//X8+X4+X3+X2+1 -> 0X1D -> B8
|
||
crc = (crc << 1) ^ 0xB8;
|
||
else
|
||
crc = (crc << 1);
|
||
}
|
||
}
|
||
|
||
return (crc^0XFF);
|
||
}
|
||
|
||
|
||
unsigned char CRC_Calc_Table(unsigned char * dataptr,unsigned char len)
|
||
{
|
||
unsigned char crc = 0xFF;
|
||
|
||
while (len--)
|
||
{
|
||
crc = crc_table[crc ^ *dataptr++];
|
||
}
|
||
return (crc^0XFF);
|
||
}
|
||
|
||
|
||
//以下程序用于验证和生成CRC_Table
|
||
/*
|
||
unsigned char cal_table_high_first(unsigned char value)
|
||
{
|
||
unsigned char i, crc;
|
||
|
||
crc = value;
|
||
//数据往左移了8位,需要计算8次
|
||
for (i=0; i<8; i++)
|
||
{
|
||
if (crc & 0x80) //判断最高位是否为1
|
||
{
|
||
//最高位为1,不需要异或,往左移一位,然后与0x31异或
|
||
//0x31(多项式:x8+x5+x4+1,100110001),最高位不需要异或,直接去掉
|
||
//X8+X4+X3+X2+1 -> 0X1D -> B8
|
||
crc = (crc << 1) ^ 0xB8; }
|
||
else
|
||
{
|
||
//最高位为0时,不需要异或,整体数据往左移一位
|
||
crc = (crc << 1);
|
||
}
|
||
}
|
||
|
||
return crc;
|
||
}
|
||
|
||
//计算crc_Table
|
||
void create_crc_table(void)
|
||
{
|
||
unsigned short i;
|
||
unsigned char j;
|
||
|
||
for (i=0; i<=0xFF; i++)
|
||
{
|
||
if (0 == (i%16))
|
||
printf("\n");
|
||
|
||
j = i&0xFF;
|
||
printf("0x%.2x, ", cal_table_high_first (j)); //依次计算每个字节的crc校验值
|
||
}
|
||
printf("\n");
|
||
}
|
||
|
||
|
||
int main()
|
||
{
|
||
unsigned char TestArr[] = {0x00,0x15,0x22,0x11,0xff,0x13,0x66};
|
||
unsigned char crc;
|
||
create_crc_table();
|
||
printf("crc_data = {0x00,0x15,0x22,0x11,0xff,0x13,0x66}\n");
|
||
crc = CRC_Calc(TestArr,7);
|
||
printf("CRC_Calc = 0x%x \n",crc);
|
||
crc = CRC_Calc_Table(TestArr,7);
|
||
printf("CRC_Calc_Table = 0x%x \n",crc);
|
||
return 0;
|
||
}
|
||
*/
|
||
|
||
|
||
|