其他
一文搞定通信协议中CRC校验(附代码)
/***简单说说几种校验***/
一、奇偶校验
奇偶校验在串口通讯中应该是会讲到这个知识点的,不过我们可能平时并不会关注太多,但是在我们以后的工作中,在进行通讯信号的诊断是能够起到一定帮助作用的,通过在传输比特流中添加一个奇偶校验位,通过检测传输过程中比特流中“1”个数来确定奇偶校验位是0还是1,这样接收方根据比特流中“1”的个数是奇数还是偶数来确定数据传输是否正确。
由上面的简单简介,我们可以基本看出该校验方法的一些弊端,比如说在数据域中有一个位由0变成了1,有一个比特位由1变成了0,那该校验方法则无法确保数据性!
二、求和校验
我们知道奇偶校验是用一个比特位来作为整个数据的校验,而我们的求和校验你可以使用一个byte,或者是多个bye来作为校验位,像我们的通信数据一般是以byte来做一个数据单元,那么我们只需要将所有数据内容按照byte进行累加即可获得数据的校验和!接受方便可以根据该校验和和我们实际接收到的数据进行对比,获得最的数据传输结果!
我们也可以从求和校验的原理找到一些明显的弊端,假如说我们数据的byte1和byte2的传输顺序发生了变化,这样我们的接收方却认为校验通过认为数据正确的。不过在我们平时一些简单的项目中,用求和校验基本上能够规避掉大部分的通讯干扰问题引起的数据问题!
/***重点讲讲CRC校验***/
CRC又叫循环冗余校验,主要是通过bit流的除法和余数的方法进行侦测,CRC主要是有极强的检错的能力,并且效率非常高。(至于为什么交错能力强,可以网上查找相关资料阅读,效率高主要是运算相对简单,都是通过移位和异或的方法就可以计算,效率较高)
CRC校验的基本形式:如果我们实际传输的数据是n个bit,那么通过对这n个bit进行CRC校验获得k个校验码加在数据后面,形成(n+k)个bit发送给接受方!
CRC版本:我们的CRC校验根据应用场景的不同也分为很多的版本,CRC-8,CRC-16等等,不同的版本主要是模型不一样。
CRC的数据模型包括:CRC的多项式,初值,宽度以及数据的翻转问题!常用模型表格如下:
图表解析:
1)CRC就是通过多项式公式来获得除数;其中表格中的“多项式”列表示该值得16进制表达式。
2)输入和输出反转,表示输入的数据和输出的数据是否进行位的反转,注意这里不是每个位的1变成0,0变成1,而是高低位的交换,后面的程序会说明这个问题。
本来想着还说一下CRC的原理,感觉网络上有很多的资料和教程,我直接贴代码,大伙可以通过读代码也可以理解去基本的原理:(以CRC16-MODBUS为例子)
其输出结果:
上面的结果与我们想要获得是一致的,可以找一下在线CRC校验工具,比如如下图所示:
下面我在这里在解析一下代码便于大家的理解和以后的调试与移植,首先我们的代码中用的两种实现方法,其中第一种实现方法应该属于我们平时使用的比较多的一种形式,因为第二种思想方法需要对数据进行处理,这样相当于增加的处理时间。
我们输入的数据0x01转化为二进制为0000.0001,如果我们使用正常的思路采用方法2采用左移的异或方式除法,那么我们除数就是跟我们多项式公式一致的0x8005,那么方法1采用右移异或除法,我们的除数需要高低位调换就变成了0xA001。
下面再讲一下大家为了提高效率使用的查询方法实现CRC校验,查表其实就是原始数据与CRC校验数据存在一一对应关系,大体思路就是我们每个byte进行CRC计算以后都会获得一个CRC值,我们把CRC值形成一个数组就行了!代码网上查找吧!哈哈!
/***校验方法的实际应用***/
我们应该对串口通讯中的奇偶校验和求和校验应该比较熟悉,怎么说呢?校验无非就是对数据建立数学上的一种关系,然后我们可以把这种关系附加在数据后面,然后由发送方组织数据并传输给接收方,这样我们的接收方便可以根据附加的数据和我们规定好的这种数学关系来进行判断,我们真实的数据否完整或者正确。
所以说在我们实际的编程过程中,我们只需要把这个数学关系封装成一个函数,发送方通过调用这个函数把返回值附加到我的发送数据中,这样接收方接收到所有的数据,调用我们所封装的同样函数获得相应的校验信息,然后拿实际我们算出的校验信息与发送方发过来的校验信息进行对比,如果相等则表示数据没问题,如果不想等则表示在传输过程中有数据丢失或者是错乱。
好了,这里是公众号“最后一个bug”,感谢大家的关注,后续带来更加精彩的文章!