公告:

串口通讯奇偶数校验及CRC校验如何使用详解

作者:智凡单片机 / 时间:7个月前 (03/22) / 分类:MSP430 / 阅读:818 / 评论:0

       最近两天在做一个射频数据传输的项目,里面就用到串口奇偶数校验,下面就以51单片机来讲解奇偶校验的使用,楼主做的项目是杰理方案的,所以有点不同,不过都是大同小异,都是对对应串口寄存器进行操作,只要会其中一种,其他的都是触类旁通。 

3750935539746260884.png 串口通讯奇偶数校验及CRC校验如何使用详解 MSP430

       我们以前在学校使用串口基本都不用奇偶数校验都是采用硬件CRC(循环冗余校验码)校验的。但有时候为了数据传输的更加严谨和差错的处理会采用奇偶校验。这里简单说下软件上CRC校验是如何计算的。 所谓CRC是指将数据以二进制的多项式形式来说明,也就是将二进制数转换成多项式的形式,多项式和二进制有直接的对应关系。x的最高次幂数对应二进制的最高位,那么对应的多项式的各次幂为:有此幂次项对应为1,无此幂次项对应0,且x的最高幂次为R,那么转出成对应的二进制数有R+1位;
例如报文:11001对应的信息多项式为:c(x)= x^4+x^3+1;又如对应的信息多项式为c(x)=x^5+x^3+x+1;那么对应的报文数据为:101011;
多项式包括生成多项式G(X)和信息多项式C(x)(也就是要发送报文的二进制数据生成的多项式);
多项式是是发送方和接收方的一个约定,也是一个二进制数,在整个数据传输过程,这个数不会变,双方以这个数为标准,对发送的数据做一个“模2除法”,以此来验证数据的收发是否正确。且CRC校验码的位数=R-1(即是最高次幂位数减1);那么怎么计算出一个报文的CRC校验码呢?
 假设生成多项式为:g(x)=x^4+x^3+x+1;求出对应要送二进制数据10101的CRC校验码;
 1 先把生成多项式g(x)=x^4+x^3+x+1转换成二进制数除数即:11011;
 2 从上面知道,CRC校验码为R-1=3,所以要发送的CRC校验码为3位数,那么将报文10101左移动3位即10101 000;后面3位就是后面要替换对应的CRC校验码的数。
 3用生成多项式的二进制数对要发送的报文(10101 000)做“模2除法”运算,得到3位数的余数,就是对应的CRC校验码,将得到的余数替换报文后三位000即可。
 说完CRC校验,下面说一下串口的奇偶数校验,基于51单片机来讲。
 所谓的奇偶数校验就是串口数据传输提供的一种对收发数据是否正确的一种校验方式。是指将对应的要发送的数据以二进制的形式,计算其数据里面“1”的个数,例如数据:101101里面“1”的个数为4个,则为偶数个;又如数据:10101里面的“1”的个数为3个,则为奇数个。如,采用偶校验,那么101101对应的偶数校验码为0,10101对应的偶数校验码为1;满足发送的数据二进制的“1”的个数机上偶数校验码等于偶数的条件即可。
在51单片机中,一般不使用奇偶校验时,我们发送的数据是8位,使用奇偶校验时,在发送完数据后,还要再发送一位校验位即一共9位数据。而1单片机提供了TB8和RB8两个寄存器。在平时不使用奇偶数校验时,这两个寄存器没什么作用,TB8就是发送方要发送的奇偶数校验码寄存器,而RB8就是接收方接收到的奇偶数校验码状态寄存器。每次在发送数据前,要先计算出该数据对应的奇偶数校验码,并将该校验码赋值给TB8寄存器。接收将数据发送给发送寄存器buf,发送完数据,接着再发送一位校验码数据;而接收方通过RB8状态寄存器内的状态码来判断所接收数据是否符合奇偶数,从而判断数据传输有没有出错。
那么,如何计算得出奇偶校验码呢?下面写出两种楼主用的方法:
1:
u8 xdata parity=0;  //初始判断标记
    u8 xdata parity_data=0;//对应是否为奇偶数
parity_data=c;//  c为要发送的数据
while (parity_data)
{
 parity = !parity; //奇数为1,偶数为0
 parity_data = parity_data & (parity_data - 1);
}
if(0==parity) //偶数
{
TB8=0;
}else  //   奇数
{
 TB8=1;
}
 这里是通过parity定义初始变量为0 ,然后parity_data - 1来减少“1”的个数,再与上parity_data;每次减少一个“1”,对应parity就取反,直到最后一个“1”时,可得出对应的parity变量为“1”还是“0”,即可得出该数据是偶数还是奇数g 个“1”;然后再对TB8寄存器进行赋值;
ACC=c;   //  ACC累加器
if(P==1)//   奇数
{ 
TB8=1;
}
else   
{
TB8=0;
}
 第二种方法更加简单,直接利用ACC累加器来计算数据的奇偶校验码;
将数据直接赋值给ACC累加器,他会对数据进行一个累加。然后累加器中“P”位的数据会随ACC累加器中数值的变化而变化,如果ACC的数据有奇数个“1”则对应的"P"位置1,否则置0.那么就可以通过"P"来判断数据里面“1”的个数,从而对奇偶校验码寄存器赋值。


没有评论,留下你的印记,证明你来过。


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。