//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) |