crc16校验的c语言程序

crc16校验的c语言程序,第1张

下面我们以CRC-16为例来说明任意长度数据的CRC校验码生成过程。我们采用将数据流分成若干个8bit字符,并由低字节到高字节传送的并行方法来求CRC校验码。具体计算过程为:用一个16bit的寄存器来存放CRC校验值,且设定其初值为0x0000;将数据流的第一个8bit与16bit的CRC寄存器的高字节相异或,并将结果存入CRC寄存器高字节;CRC寄存器左移一位,最低1bit补零,同时检查移出的最高1bit,若移出的最高1bit为0,则继续按上述过程左移,若最高1bit为1,则将CRC寄存器中的值与生成多项式码相异或,结果存入CRC寄存器值;继续左移并重复上述处理方法,直到将8bit数据处理完为止,则此时CRC寄存器中的值就是第一个8bit数据对应的CRC校验码;然后将此时CRC寄存器的值作为初值,用同样的处理方法重复上述步骤来处理下一个8bit数据流,直到将所有的8bit字符都处理完后,此刻CRC寄存器中的值即为整个数据流对应的CRC校验码。

下面示出了其计算过程的流程图:

在用C语言编写CRC校验码的实现程序时我们应该注意,生成多项式 对应的十六进制数为0x18005,由于CRC寄存器左移过程中,移出的最高位为1时与 相异或,所以与16bit的CRC寄存器对应的生成多项式的十六进制数可用0x8005表示。下面给出并行处理8bit数据流的C源程序:

unsigned short crc_dsp(unsigned short reg, unsigned char data_crc)

//reg为crc寄存器, data_crc为将要处理的8bit数据流

{

unsigned short msb//crc寄存器将移出的最高1bit

unsigned short data

unsigned short gx = 0x8005, i = 0//i为左移次数, gx为生成多项式

data = (unsigned short)data_crc

data = data <<8

reg = reg ^ data

do

{

msb = reg &0x8000

reg = reg <<1

if(msb == 0x8000)

{

reg = reg ^ gx

}

i++

}

while(i <8)

return (reg)

}

以上为处理每一个8bit数据流的子程序,在计算整个数据流的CRC校验码时,我们只需将CRC_reg的初值置为0x0000,求第一个8bit的CRC值,之后,即可将上次求得的CRC值和本次将要处理的8bit数据作为函数实参传递给上述子程序的形参进行处理即可,最终返回的reg值便是我们所想得到的整个数据流的CRC校验值。

那么CRC循环冗余校验的原理是什么呢,众所周知在数据帧的最后有一个CRC校验码,这是CRC循环冗余校验的根本所在,那么这个校验码是怎么来的呢?其实这个校验码就是一个余数,被除数是数据段的数据M左移n位(右移后空出来的位置用0填充),除数是收发双方实现原定好的长度为k数据P,那么大伙是不是有疑问那么究竟源数据M要左移几位呢n到底要为多大?其实右移的位数的大小n就是除数位数的k-1。至于为什么请往下看。假设M为1001010,P为1101

我们实际走一下这个过程,这样比较容易理解一点,具体步骤如下:

其实这个和我们小学学的除法区别不大,只有一点不同,注意看你源数据和除数相减时和我们十进制除法是不一样的,这里用的是,模2运算就是进行加减法的时候两个数字同为1或者同为0则结果为0不同则为1。冗余码就是除完以后的余数

所以实际发送的就是数据部分加冗余码即按照上面的例子就时M+冗余码(这里的+不是算算数运算符),即1001010101。看到这里你是不是就明白了为什么冗余码的长度是除数的长度减一了吧。

那么接收端接收到数据以后怎么验证自己收到的数据是不是正确无误的呢,接收端拿到数据以后就直接用数据连上校验码除以已知的除数如果余数位0则数据正确,如果余数不为0则判定该则该帧有误,就丢弃,要注意的是判断只能判断帧是否正确但不能判断帧出错几位或者说在哪个位置出错。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11045225.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-13
下一篇2023-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存