打印

解读CRC的校验原理

[复制链接]
1395|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
FVJFIFE|  楼主 | 2011-10-29 20:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
随着数据采集系统的功能日益强大,由于传输距离、现场状况等诸多可能出现的因素的影响,计算机与受控设备之间的通讯数据常会发生无法预测的错误。为了防止错误所带来的影响,在数据的接收端必须进行差错校验。虽然差错校验也可以完全由硬件来承担,但由于单片机和PC都具有很强的软件编程能力,这就为实施软件的差错校验提供了前提条件,而软件的差错校验有经济实用并且不增加硬件开销的优点。  1 CRC法的原理
  传统的差错检验法有:奇偶校验法,校验和法,行列冗余校验法等。这些方法都是在数据后面加一定数量的冗余位同时发送出去,例如在单片机的通讯方式2和3中,TB8就可以作为奇偶校验位同数据一起发送出去,在数据的接收端通过对数据信息进行比较、判别或简单的求和运算,然后将所得和接收到的冗余位进行比较,若相等就认为数据接收正确,否则就认为数据传送过程中出现错误。但是冗余位只能反映数据行或列的奇偶情况,所以这 类检验方法对数据行或列的偶数个错误不敏感,漏判的概率很高。因此,此种方法的可靠性 就差。
  循环冗余码校验英文名称为Cyclical Redundancy Check,简称CRC。它是利用除法及余数 的原理来作错误侦测(Error Detecting)的。实际应用时,发送装置计算出CRC值并随数据一同发送给接收装置,接收装置对收到的数据重新计算CRC并与收到的CRC相比较,若两个CR C值不同,则说明数据通讯出现错误。由于这种方法取得校验码的方式具有很强的信息覆盖能力,所以它是一种效率极高的错误校验法。错误的概率几乎为零。在很多的仪器设备中都 采用这种冗余校验的通讯规约。
  根据应用环境与习惯的不同,CRC又可分为以下几种标准:
  ① CRC-12码;② CRC-16码;
  ③ CRC-CCITT码;④ CRC-32码。
  CRC-12码通常用来传送6-bit字符串。?CRC-16?及CRC-CCITT码则是用来传送8-b it字符,其中CRC-16为美国采用,而CRC-CCITT为欧洲国家所采用。CRC-32码大都被采用在一种称为Point-to-Point的同步传输中。
  2 CRC校验码的生成过程
  我们以最常用的CRC-16码作为例子进行说明。
  冗余循环码包括2个字节,即16位二进制数。先预置16位寄存器全部为1,再逐 步把每8位的数据信息进行处理。在进行CRC计算时只用8位数据位,起始位和停止位,如有奇偶校验位的话也包括奇偶校验位,都不参与CRC计算。
  在计算CRC码时,8位数据与寄存器的数据相异或,得到的数据向低位移一位,用 0填补最高位,再检查最低位。如果最低位为1,把寄存器的内容与预置数相异或;若最低位为0,则不进行异或计算。
  这个过程一直重复8次,第8次移位后,下一个8位数据再与现在寄存器中的内容 相异或,这个过程和以上一样重复8次。当所有的信息处理完后,最后寄存器中的内容即为CRC码。这个CRC码将由发送设备跟在数据的最后一起发送。
  计算CRC的步骤为:
  (1)预置16位寄存器位十六进制数FFFF(即全为1)。称此寄存器位CRC寄存器。
  (2)把第一个8位数据与16位寄存器的低位相异或,将结果放于CRC寄存器中;
  (3)把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位;
  (4)如果最低位为0,重复第三步(再次移位);
  如果最低位为1,CRC寄存器与多项式码进行异或;
  (5)重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
  (6)重复步骤2到5,进行下一个8位数据的处理;
  (7)最后得到的CRC寄存器即为CRC码。
  

相关帖子

沙发
FVJFIFE|  楼主 | 2011-10-29 20:18 | 只看该作者
*************************************************

  函数功能:求CRC16校验值程函数

  修改日期:2006.7.4

  待修改: OK

  参数: *STr指向txbuf,待发送数组;

  num为报文字节数

  最后计算结果为2字节数。

  MODBUS传输时,CRC低位在前,crc%256求低位;

  高位在后,crc/256求高位。?*************************************************/

  uint crc16(uchar *str,uint num) //CRC计算子程序,

  {

  uchar i;

  //uint crc;

  crc=0xffff;

  for (i=0; i {

  arc= (str[i] ^ crc) & 0x00ff;

  crc=_irol_(crc,8);           //整形循环右移指令

  crc= crc & 0x00ff;

  crc= crc ^ crctable[arc];

  }

  return(crc);

  }

  /**************************************************************************

  函数功能:CRC校验程函数

  修改日期:2006.7.4

  待修改: OK

  参数: N为报文字节数,rxbuf[]为接收报文区

  如果最后计算结果CRC==0,说明报文在传输过程中正确

  **************************************************************************/

  void crc_verify(uchar N) //CRC校验程序

  {

  uchar i;

  crc = 0xFFFF; //modbus_crc 初值

  for (i=0; i<=7;i++ ) //CRC校验方式 可以做一个子程序来处理

  {

  arc= (rxbuf[i] ^ crc) & 0x00FF; //xor

  crc=_irol_(crc,8); //整形循环右移指令

  crc= crc & 0x00FF;

  crc= crc ^ crctable[arc]; //xor

  _nop_();

  }

  }

  uint code crctable[]={ //CRC计算用表

  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,

  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

  };

使用特权

评论回复
板凳
即时生效| | 2011-10-29 20:44 | 只看该作者
CRC一般都做到硬件里面了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

897

帖子

1

粉丝