CRC16校验示例C语言程序

#include
#include
#include"crc16.h"

int main(int argc, char **argv) {
	unsigned char meg[4]={0xB5,0x12,0xA3,0x49};
	sendMessage(meg,sizeof(meg));
	receiveMessage(meg,sizeof(meg));
	return EXIT_SUCCESS;
}





#ifndef _CRC16_H_
#define _CRC16_H_

void sendMessage(unsigned char *meg,int const length);//发送报文,报文信息,报文信息总字节数 

void receiveMessage(unsigned char *meg,int const length);//接收报文 

static unsigned short crc16_xmodem(unsigned const char *meg,int const length);//采用CRC16-XMODEM标准进行校验码计算 

static unsigned short crc16_xmodem_improve(unsigned const char *meg,int const length);//采用CRC16-XMODEM标准进行校验码计算(算法改) 

static unsigned short crc16_ccitt(unsigned const char *meg,int const length);//采用CRC16-CCITT标准进行校验码计算

#endif



#include 
#include"crc16.h"
#define improvement 1     //使用普通的寄存器移位算法还是改进算法 

static unsigned short crc_send;//定义一个全局变量,用于存放发送的crc校验码 

void sendMessage(unsigned char *meg,int const length){
	unsigned char *p;
	printf("正在计算CRC码...\n");
#if improvement
	crc_send=crc16_ccitt(meg,length);
	//crc_send=crc16_xmodem_improve(meg,length);//这里计算校验码需要实际发送的数据帧字节数
#else 
	crc_send=crc16_ccitt(meg,length);
	//crc_send=crc16_xmodem(meg,length);//计算校验码只需循环数据帧的字节数(移位时自动在数据码末尾补16个0)
#endif 

	printf("正在发送报文:");
	for(p=meg;p<&meg[length];printf("%0x\t",*p++));
	printf("%0x\t%0x\012",(unsigned char)(crc_send>>8),(unsigned char)crc_send);
	printf("报文发送完毕!\012\012\012");
}

void receiveMessage(unsigned char *meg,int const length){
	unsigned char *p;
	unsigned short crc;
	
	printf("正在接收报文...");
	printf("\n报文接收完毕!\n");
	
	printf("正在校验CRC码...\n");
#if improvement
	crc=crc16_ccitt(meg,length);
	//crc=crc16_xmodem_improve(meg,length);	
#else 
	crc=crc16_ccitt(meg,length);
	//crc=crc16_xmodem(meg,length);
	
#endif
	if(crc == crc_send)
		printf("OK,报文接收成功!\n");
	else 
		printf("ERROR,报文接收失败!\n");
}

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

程序可以如下实现:

1)将M*x^r的前r位放入一个长度为r的寄存器;

2)如果寄存器的首位为1,将寄存器左移1位(将Mx^r剩下部分的MSB移入寄存器的LSB),

再与生成多项式G的后r位异或,否则仅将寄存器左移1位(将Mx^r剩下部分的MSB移入寄存器的LSB);

3)重复第2步,直到M全部Mx^r移入寄存器;

4)寄存器中的值则为校验码。

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

unsigned short crc16_xmodem(unsigned const char *meg,int const length){
	int i,j;//循环变量
	unsigned short crc_reg=(meg[0]<<8) + meg[1];//定义一个16位的CRC寄存器并初始化为meg码的前两字节 
	for(i=0;i>7-j & 1)) ^ 0x1021;	//crc_reg左移一位,并与此字节的下下字节位往crc_reg中填充,并将最终的crc_reg与0x1021异或 
				else
					crc_reg=(crc_reg<<1) + (meg[i+2]>>7-j & 1);
		}
		else{              
			for(j=0;j<8;++j)
				if(crc_reg & 0x8000)          
					crc_reg=(crc_reg<<1) ^ 0x1021;	//当i>=len-i时,自动填充0 
				else
					crc_reg=(crc_reg<<1);
		}				 
	return crc_reg;	
}

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

CRC16的算法原理:

1.根据CRC16的标准选择初值crc_ini的值。

2.将数据的第一个字节tmp与crc_ini高8位异或。

3.判断最高位,若该位为 0 左移一位,若为 1 左移一位再与生成多项式Gx异或。

4.重复3直至8位全部移位计算结束。

5.重复将所有输入数据操作完成以上步骤,所得16位数即16位CRC校验码。

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

unsigned short crc16_xmodem_improve(unsigned const char *meg,int const length){
	int i, j;  
    unsigned short crc_ini=0; 
    unsigned short tmp;   //定义一个临时变量存入数据的每个字节 
    for (i=0;i>1) ^ 0x8408;
            else
                crc_ini>>=1;
            tmp>>=1;           
        }
    }
    return crc_ini;
}

参考 :1、http://blog.csdn.net/leumber/article/details/54311811

           2、http://blog.csdn.net/exceptional_czr/article/details/70767572

你可能感兴趣的:(CRC16校验示例C语言程序)