CRC32太大了,CRC8觉得强度不够,折中选择CRC16校验.
线性编码理论。在发送端传送的K位二进制数据,以一定规则产生一个校验监督码(或者叫监督矩阵)r位,并负载信息后,构成一个新的二进制码序列共(K+R)位。最后发送出去。在接收端根据信息吗和CRC码禁言,是否出错。
CRC16监督式(美国标准):G(X)=X^16+X^15+X2+1
CRC16监督式(欧洲标准):G(X)=X16+X12+X5+1
一般多数采用CCITT推荐的欧标格式:10001000000100001
16位的CRC码产生的规则是先把要发送的信息元左移16位(乘以2^16),再除以监督式,最后得到的是CRC码。再把CRC码附在信息元后面,一起发送出去。
B(X).2^16/G(X)=Q(X)+R(X)/G(X)
Q(X)是商,R(X)是余数。模2加减法就是不带进位借位的加减法相当异或,乘除法和普通数学乘除法一致。例如:
信息码:1011,监督元:G(X)X^8+X^5+X^4+1 CRC8校验 下面是除法运算:
1011 0000 0000
1001 1000 1
10 1000 1000
10 0110 001
11101010
所以CRC 8 监督元:11101010
发送的K+r位码:1011 11101010
接收端接收到的信息码除以监督元,如果R(X)为0,说明传输无误。
假设接收到跟发送一致。验证
1011 1110 1010
1001 1000 1
10 0110 0010
10 0110 001
0
所以接收正确无误
实际通信中发送数据是多字节,比如发送地址、控制、信息、校验。所以必须按多字节去计算CRC码。
B(X)=Bn(X)*2^8n+Bn-1(X)*2^8(n-1)+....+B1(X)*2^8+B0(X)
CRC16时候,上式两端还要乘以2^16,即左移16位。把繁琐的计算过程省略,其实只要记住本 字节的CRC码等于上一字节的余式的CRC码的低 8位左移8位后,再加上上一字节CRC右移8位(也就是取高8位)和本字节之和(异或)所求的的CRC码 。 但是我们不可能这样每部就去计算,单片机是承受 不了的,而且占据大量任务,给实时通信打折扣。所以一般我们会把8位二进制序列数从0~255的CRC全部计算出来,放在表里,扔到EEPROM或者 FLASH中固存。
unsigned int crc_table [256]={ /* C