CRC校验程序

什么是CRC校验: http://www.51hei.com/bbs/dpj-47736-1.html

https://wenku.baidu.com/view/0b9f0dd4360cba1aa811daf5.html?rec_flag=default&sxts=1532740998346

CRC-16校验码计算方法:

常用查表法和计算法。计算方法一般都是:
(1)、预置1个16位的寄存器为十六进制FFFF(即全为1),称此寄存器为CRC寄存器;
(2)、把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器,高八位数据不变;
(3)、把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;
(4)、如果移出位为0:重复第3步(再次右移一位);如果移出位为1,CRC寄存器与多项式A001(1000 0000 0000 0101)进行异或;(modbus多项式为x16+x15+x2+1 = 8005,A001是8005按位颠倒后的结果)
(5)、重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
(6)、重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
(7)、将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
(8)、最后得到的CRC寄存器内容即为:CRC码。

所以要写一个CRC校验首先你得搞清楚这些:

一、确定CRC-8还是CRC-16校验,从而确定一帧数据结尾附加的字节数。
二、确定生成多项式。(我是根据modbus协议写的。)
三、确定是正序检验还是反序检验。正序检验采用正序简记式,反序检验采用反转简记式。
四、判断CRC是否正确的两种方法:
1.算前七个字节的CRC算出来与最后一个字节相等,则正确。(一般用于发送端计算CRC值)
2.算8个字节的CRC,算出来等于0则正确。(一般用于接收端进行检测)(我一般用这个)

也就是说假如我是发送端,我要发送一串数据,当然了屁股后头还得跟着几个字节的CRC(刚刚说了有CRC8和CRC16还有CRC32之分),那么这几个字节的CRC就是根据你要发送的这串数据(不包含CRC位)来算。算好了,发出去。再假设下我现在是在接收端,接收端我接收到了主机发送过来的一串数据,这个时候我咋知道数据发过来有没有出错呢(没出错就做出相应的响应,出错就抛弃这帧数据)?将接收到的数据去除CRC位,我再算一次CRC。假如算出来的跟他发送过来的CRC一样,哎呦,这串数据没出错。响应吧。你的响应被主机接收到,主机也是像之前一样算CRC,然后比较发送过来的CRC是否一样。然后照此循环。看懂了吗?没看懂?那附上我学长教我时写的小教程(其实就是一张图而已。。。)

下面是程序实现(这个程序就是实现算CRC哒)

小细节:在VS中:int(16bit)      short(16bit)     char(8bit)

#include"stdio.h"

int main ()
{

	int len = 0;
	int i,  j;
	unsigned short ax1, axh1, axl1 ;
	unsigned char axh, axl;
	unsigned short ax = 0xffff;
	unsigned char data[8] = {};

	while(1)			//动态录入数据回车结束。
	{
		scanf("%d", &data[len]);
		len++;
		if(getchar() == '\n')
			break;
	}

	printf("我爱灌汤包\n");

	 for(j = 0; j < len; j++)	//上述计算步骤(6)		//calculate  ax (计算ax)
	 {
	  ax ^= (unsigned short)data[j]; 
	 
		 for(i = 0; i < 8; i++)//上述计算步骤(5)
		 {
			if(ax & 1)//若最高位为1则
			{
				ax = (ax >> 1);
				ax ^= 0xa001; 
			}
			else
			{
				ax = (ax >> 1);
			}
		}
	 }
	 ax1 = ax;	 

	 axl = (ax1>>8);	// ax的高低位分开显示
	 axh = ax1;

	 axl1=(ax1 >> 8);		// ax的高低位合并显示
	 axh1 = (ax1 << 8);
	 ax = axh1 | axl1;
	
	  printf("%02x	%02x	%02x\n", axh, axl, ax); 
	  getchar();
	  return 0;


}

 

 

以上我是用数组写的,回头再贴上用指针写的。

查表法是将移位异或的计算结果做成了一个表,就是将0~256放入一个长度为16位的寄存器中的低八位,高八位填充0,然后将该寄存器与多项式0XA001按照上述3、4步骤,直到八位全部移出,最后寄存器中的值就是表格中的数据,高八位、低八位分别单独一个表。(后续再补充吧)

猜你喜欢

转载自blog.csdn.net/qq_34471646/article/details/81257158