Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2350512
  • 博文数量: 816
  • 博客积分: 10000
  • 博客等级: 上将
  • 技术积分: 5010
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-17 17:57
文章分类

全部博文(816)

文章存档

2011年(1)

2008年(815)

分类:

2008-12-17 18:01:42

//CCITT 标准的, 我遇到过的软件多数采用的
void _CrcCcitt16(unsigned short &c, void *s, int n)
{
  unsigned long i, b;
  for(int k=0; k   {
     b=((unsigned long)(((unsigned char*)s)[k]))<<8;
     for(i=0; i<8; i++)
      {
        c = ((b^c) & 0x8000) ? (c<<1)^0x1021 : (c<<1); //16|12,5,0 = 0001 0000 0010 0000 = 1021
        b<<=1;
      }
   }
}

//标准 CRC, 虽然是标准 CRC, 但用的可能没有 CCITT 的普遍
void _Crc16(unsigned short &c, void *s, int n)
{
  unsigned long i, b;
  for(int k=0; k   {
     b=((unsigned long)(((unsigned char*)s)[k]))<<8;
     for(i=0; i<8; i++)
      {
        c = ((b^c) & 0x8000) ? (c<<1)^0x8005 : (c<<1); //16|15,2,0 = 1000 0000 0000 0101 = 8005
        b<<=1;
      }
   }
}

无论采用哪种标准, 只是多项式系数不同, CCITT 用的是 0x1021 而 标准CRC16 用的是 0x8005, 也可能有其它标准, 只是系数不同

在本站的串口控件里面有这两个的函数, 并且还有 CRC8 和 CRC32 的函数。
如果你 #include 可直接使用这些 CRC 函数。

参数:
c: CRC校验码, 在计算之前清零(或者按照特殊设计要求赋初始值), 计算之后就是经过计算之后的数据的 CRC 校验码
s: 数据地址
n: 数据的字节数

例如:
unsigned short crc;
char buf[9] = {0x11, 0x22, 0x45, 0x78, 0xaa, 0xbc, 0xff};
crc=0; //计算之前需要清零
_CrcCcitt16(crc, buf, 7); //计算 buf 里面的前 7 个字节的 crc 校验码

//crc 的值写入 buf 有两种情况, 可以按你的需要选择:

//1.低位在前, 高位在后, 只需要一条语句即可
*(short*)(buf+7)=crc; //buf 的第 7 个字节为 crc 低位字节, 第 8 个字节为 crc 的高位字节

//2.高位在前, 低位在后, 需要分别赋值
buf[7] = crc>>8; //buf 的第 7 个字节为 crc 的高位字节
buf[8] = crc; //buf 的第 8 个字节为 crc 的低位字节

--------------------next---------------------

阅读(1108) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~