RSS

CRC算法原理及C语言实现

来源: 作者: 时间:2008-04-02 Tag: 点击:

很显然,按字节求CRC时,由于采用了查表法,大大提高了计算速度。但对于广泛运用的8位微处理器,代码空间有限,对于要求256个CRC余式表(共512字节的内存)已经显得捉襟见肘了,但CRC的计算速度又不可以太慢,因此再介绍下面一种按半字节求CRC的算法。
5  按半字节计算CRC
同样道理,对于一个二进制序列数可以按字节表示为式(5-1),其中 为半个字节(共4位)。
              (5-1)
求此二进制序列数的CRC码时,先乘以 后(既左移16位),再除以多项式G(X),所得的余数既是所要求的CRC码。如式(4-2)所示:
              (5-2)
可以设:                                            (5-3)
其中 为整数, 为16位二进制余数。将式(5-3)代入式(5-2)得:
                    (5-4) 字串1
因为:       
                                                    (5-5)
其中 是 的高4位, 是 的低12位。将式(5-5)代入式(5-4),经整理后得:
                                                                               (5-6)
再设:                 (5-7)

字串4


其中 为整数, 为16位二进制余数。将式(5-7)代入式(5-6),如上类推,最后得:
                (5-8)
很显然,十六位二进制数 既是我们要求的CRC码。
式(5-7)是编写按字节计算CRC程序的关键,它说明计算本字节后的CRC码等于上一字节CRC码的低12位左移4位后,再加上上一字节余式CRC右移4位(也既取高4位)和本字节之和后所求得的CRC码,如果我们把4位二进制序列数的CRC全部计算出来,放在一个表里,采用查表法,每个字节算两次(半字节算一次),可以在速度和内存空间取得均衡。由此不难理解下面按半字节求CRC码的C语言程序。*ptr指向发送缓冲区的首字节,len是要发送的总字节数,CRC余式表是按0x11021多项式求出的。
unsigned  cal_crc(unsigned char *ptr,  unsigned char len) {
  unsigned int crc;
  unsigned char da;
  unsigned int crc_ta[16]={               /* CRC余式表 */
    0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,

字串4


0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
  }

  crc=0;
  while(len--!=0) {
    da=((uchar)(crc/256))/16;      /* 暂存CRC的高四位 */
    crc<<=4;                   /* CRC右移4位,相当于取CRC的低12位)*/
    crc^=crc_ta[da^(*ptr/16)];     /* CRC的高4位和本字节的前半字节相加后查表计算CRC,
然后加上上一次CRC的余数 */
    da=((uchar)(crc/256))/16;      /* 暂存CRC的高4位 */
    crc<<=4;                   /* CRC右移4位, 相当于CRC的低12位) */
    crc^=crc_ta[da^(*ptr&0x0f)];   /* CRC的高4位和本字节的后半字节相加后查表计算CRC, 字串6
然后再加上上一次CRC的余数 */
    ptr++;
  }
  return(crc);
}
5  结束语
以上介绍的三种求CRC的程序,按位求法速度较慢,但占用最小的内存空间;按字节查表求CRC的方法速度较快,但占用较大的内存;按半字节查表求CRC的方法是前两者的均衡,即不会占用太多的内存,同时速度又不至于太慢,比较适合8位小内存的单片机的应用场合。以上所给的C程序可以根据各微处理器编译器的特点作相应的改变,比如把CRC余式表放到程序存储区内等.
上一页 1 2下一页
Google
最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册