原创 CRC-16-IBM(A001)的16字表长查表程序

2009-10-18 18:33 8554 5 6 分类: MCU/ 嵌入式

CRC-16-IBM(A001)的16字表长查表程序


此文依据: http://blog.ednchina.com/hotpower/272834/message.aspx


CRC位域4单表查表及建表原则:
左移位域4取列表16个,大端存储模式。右移位域4取行表16个,小端存储模式。


在CRC-16-IBM中CRC的多项式为:右移CRC16=X16+X15+X2+1,即权值=0xA001,故建立16字节的CRC表格:
(参见:http://zh.wikipedia.org/zh-cn/%E5%BE%AA%E7%8E%AF%E5%86%97%E4%BD%99%E6%A0%A1%E9%AA%8C)


网上CRC16的256个表为:
unsigned int CRC16Table[256] = {                                
   0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,  
   0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,  
   0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,  
   0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,  
   0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,  
   0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,  
   0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,  
   0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,  
   0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,  
   0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,  
   0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,  
   0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,  
   0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,  
   0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,  
   0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,  
   0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,  
   0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,//注意本行的0xA001  
   0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,  
   0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,  
   0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,  
   0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,  
   0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,  
   0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,  
   0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,  
   0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,  
   0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,  
   0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,  
   0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,  
   0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,  
   0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,  
   0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,  
   0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
即CRC位域8表:
CRC16Table[256]={CRC[0x0000],CRC[0x0100],CRC[0x0200],...CRC[0xFD00],CRC[0xFE00],CRC[0xFF00]};


特别注意对CRC表逆向出权值的方法(256表):
右移方式,CRC多项式即权值=CRC16Table[0x80]=0xA001
左移方式,CRC多项式即权值=CRC16Table[0x01]


本文采用CRC位域4查表方式,故表为:
CRC16Table[16]={CRC[0x0000],CRC[0x1000],CRC[0x2000],...CRC[0xD000],CRC[0xE000],CRC[0xF000]};
即右移方式取行表:
CRC16Table[16]={
  0x0000,0xCC01,0xD801,0x1400,0xF001,0x3C00,0x2800,0xE401,
  0xA001,0x6C00,0x7800,0xB401,0x5000,0x9C01,0x8801,0x4400//注意本行的0xA001
};


unsigned int GetCRC16(unsigned int crcinit, unsigned int crcval)
{//(可以不要初值crcinit,多字节CRC16时入口需要对crcval做处理)
unsigned int i, crc="0";
  crcval = crcinit ^ crcval;
  for(i = 0;i < 4;i ++)//2个字节位域4需要4次完成
  {
    crc = (crc >> 4) ^ CRC16Table[(crc ^ crcval) & 0x0F];//位域宽4单表16个字节
    crcval >>= 4;//准备下一个位域,域宽4
  }
  return crc;
}


菜农HotPower@126.com  2009.10.18 于雁塔菜地

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户455232 2010-3-14 20:09

大哥啊,我根据你的程序调试下,输出的结果不对啊?帮我看看啊,在VC下调试,结果和表格不符啊! #include unsigned short CRC16Table[16]={ 0x0000,0xCC01,0xD801,0x1400,0xF001,0x3C00,0x2800,0xE401, 0xA001,0x6C00,0x7800,0xB401,0x5000,0x9C01,0x8801,0x4400//注意本行的0xA001 }; unsigned int GetCRCR16(unsigned int crcinit, unsigned int crcval) {//(可以不要初值crcinit,多字节CRC16时入口需要对crcval做处理) unsigned int i, crc=0; crcval = crcinit ^ crcval; for(i = 0;i < 4;i ++)//2个字节位域4需要4次完成 { crc = (crc >> 4) ^ CRC16Table[(crc ^ crcval) & 0x0F];//位域宽4单表16个字节 crcval >>= 4;//准备下一个位域,域宽4 } return crc; } void main(void) { unsigned short i; unsigned short CRC_value[256]; for (i=0;i<256;i++) { CRC_value[i]=(unsigned short)GetCRCR16(0x0000,i); } for(i=0;i<256;i++) { printf(" %4x",CRC_value[i]); if(!((i+1)%8)) printf("\n"); } }
相关推荐阅读
雁塔菜农 2012-04-05 17:51
2012年度新唐Cortex-M0助学开发套件有约束条件赠送申报贴
2012年度新唐Cortex-M0助学套件从4月起每月有约束条件发放16套。 申报人必须是21ic或 EDNC 会员 并具备1月的会龄。 申报时必须注明“遵守约束条件,缴纳250元订金,上...
雁塔菜农 2012-04-05 17:04
2012年度Cortex-M0助学园地推广框图
...
雁塔菜农 2012-04-01 17:59
2012年度Cortex-M0助学园地奖励计划细则
抢楼请点击:菜地公告:即日起创建《菜农Cortex-M0助学园地》(盖楼入口) 每月10号和25号的下午2:50进行2次抢楼,规则同去年12月的疯狂抢楼活动。 奖品由21IC、北航、广州迪圣...
雁塔菜农 2012-02-03 08:19
菜农谋略:搞定牛人宋俊德,对女牛人孙昌旭说:“记住,俺是雁塔菜农~~~ ”
http://www.baidu.com/s?wd=%B2%CB%C5%A9%D0%A6%CC%B8%A1%B6%D0%C2%C0%CB%C3%FB%C8%CB%D0%A7%D3%A6%A1%B7...
我要评论
1
5
关闭 站长推荐上一条 /3 下一条