.子程序 checksum, 短整数型
.参数 buffer, 短整数型, 参考
.参数 size, 整数型
.局部变量 cksum, 整数型
.判断循环首 (size > 1)
cksum = buffer + 1 + cksum
size = size - 2
.判断循环尾 ()
.如果真 (size ≠ 0)
cksum = cksum + 到字节 (buffer)
.如果真结束
cksum = 右移 (cksum, 16) + 位与 (cksum, 65535)
cksum = cksum + 右移 (cksum, 16)
返回 (cksum)
//========================================|功能函数//计算效验和
uint8
CHECK_SUM(uint8
*pt,uint8
pos,uint8
len)
reentrant
{
uint8
CHECKSUM=0
pt+=pos
//预置指针到pos
while(len--)
{
if(*pt
&
BIT0){CHECKSUM++}
if(*pt
&
BIT1){CHECKSUM++}
if(*pt
&
BIT2){CHECKSUM++}
if(*pt
&
BIT3){CHECKSUM++}
if(*pt
&
BIT4){CHECKSUM++}
if(*pt
&
BIT5){CHECKSUM++}
if(*pt
&
BIT6){CHECKSUM++}
if(*pt
&
BIT7){CHECKSUM++}
pt++
}
//
F_Wtd
return
CHECKSUM
}
//========================================|
用法:
tmp=CHECK_SUM(UART_BUF,0,UART_RX_LEN)
按位计算CRC采用CRC-CCITT多项式,多项式为0x11021,C语言编程时,参与计算为0x1021。当按位计算CRC时,例如计算二进制序列为1001 1010 1010 1111时,将二进制序列数左移16位,即为1001 1010 1010 1111 (0000 0000 0000 0000),实际上该二进制序列可拆分为1000 0000 0000 0000 (0000 0000 0000 0000) + 000 0000 0000 0000 (0000 0000 0000 0000) + 00 0000 0000 0000 (0000 0000 0000 0000) + 1 0000 0000 0000 (0000 0000 0000 0000) + ……现在开始分析运算:
<1>对第一个二进制分序列求余数,竖式除法即为0x10000 ^ 0x11021运算,后面的0位保留;
<2>接着对第二个二进制分序列求余数,将第一步运算的余数*2后再和第二个二进制分序列一起对0x11021求余,这一步理解应该没什么问题。如果该分序列为0,无需计算。
<3>对其余的二进制序列求余与上面两步相同。
<4>计算到最后一位时即为整个二进制序列的余数,即为CRC校验码。
该计算方法相当于对每一位计算,运算过程很容易理解,所占内存少,缺点是一位一位计算比较耗时。
下面给出C语言实现方法:
代码如下:
unsigned char test[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff}
unsigned char len = 16
void main( void )
{
unsigned long temp = 0
unsigned int crc
unsigned char i
unsigned char *ptr = test
while( len-- ) {
for(i = 0x80i != 0i = i >>1) {
temp = temp * 2
if((temp &0x10000) != 0)
temp = temp ^ 0x11021
if((*ptr &i) != 0)
temp = temp ^ (0x10000 ^ 0x11021)
}
ptr++
}
crc = temp
printf("0x%x ",crc)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)