标题:
MCU串口异步通讯过程中的奇偶校验和停止位深入研究
[打印本页]
作者:
爱51hei
时间:
2015-10-29 12:46
标题:
MCU串口异步通讯过程中的奇偶校验和停止位深入研究
在连续的高速异步通讯中,如果没有作为握手用的信号位,那么如何辨识一个字符帧的开始变成了难题。从一串连续的数字中找出字节的帧头,然后正确的识别出要传输的信息,除非做多次尝试,并且通讯双方约定好起始信息,方可正确传输信息。此时,为了让信号有较为明显的辨识信息,增加奇偶校验位,以及加长停止位的长度,都是一个提高帧起始判定的一种方法。
在波特率为115200的设置下,如果采用N,8,1的标准设置,可以从下面的波形图中看出,如果连续发送字符0x55,则停止位到下一个起始位之间的脉宽是11.12us, 而标准的数字位的脉宽是8.83us。如果在两个数据的发送之间没有其他延时信号,则可能无法分辨出那一个位是一个字符帧的起始位,从而导致后续其它字符的帧错误。这样在使用软件方法做串行数据接收时,就会出错。
图1,在波特率115200时,标准位脉冲宽度为8.83us
图2,在波特率115200时,停止位到下一个起始位的宽度可能更小,这里是11.12us。
图3,出现帧判别错误的情形(这里是奇偶校验设置不正确导致)。
为了解决这个异常,可以通过加长停止位的方法,提高软件对起始位的识别几率。因此上可以将常用的1个停止位,增加到1.5个或2个位长度。对于长线传输,为了检查传输过程中信号是否受其他干扰而导致的翻转,又在停止位之前,插入奇偶校验位的方式,协议商定传输的1的个数是奇数个或者偶数个,然后通过插补的方式确定每帧的情况相同。这样,如果在接收端发现帧错误,可以及时检查出来。
使用C51的发送程序:
sbit
TXB = P3^
1
;
sbit
RXB = P3^
0
;
bit
bUartBusy;
//串口正在使用的标志
unsigned char
bEven;
//用来计算偶校验的和
#define ON 1
#define OFF 0
// #define EVENPARITY
//#define STOP2BITS
void
SendChar(
unsigned char
c)
{
unsigned char
nCnt;
TXB=
0
;
//串口起始位开始
TR0 =
1
;
//定时器0开始计时
ET0 =
1
;
//使能定时器0中断
bUartBusy = ON;
//bUartBusy 在Timer0的服务程序中设置为OFF
while
(bUartBusy == ON);
//维持当前TXB的电平,直到下一次中断到来。输出一个位宽的数据。
//由低位开始,将数据通过串口输出
#ifdef
EVENPARITY
//如果定义偶校验
bEven=
0
;
//偶校验的初值为0.
#endif
for
(nCnt =
0
; nCnt <
8
; nCnt++) {
TXB =c &
0x01
;
//输出最低位
#ifdef
EVENPARITY
bEven = bEven + (c &
0x01
);
//偶校验计算,把所有的1加起来
#endif
c >>=
1
;
//右移一位,准备在下个周期中输出
bUartBusy = ON;
while
(bUartBusy == ON);
}
#ifdef
EVENPARITY
TXB=bEven &
0x1
;
//取1的个数和作为偶校验结果位发送。
bUartBusy = ON;
while
(bUartBusy == ON);
#endif
TXB =
1
;
// 发送第一个串口停止位
bUartBusy = ON;
while
(bUartBusy == ON);
#ifdef
STOP2BITS
//如果定义2位停止位
bUartBusy = ON;
//发送第2个停止位
while
(bUartBusy == ON);
#endif
TR0 =
0
;
//定时器0结束计时
ET0 =
0
;
//禁能定时器0中断
}
定时器Timer0的中断服务中,仅仅完成标志设置,确保每个数据位发送的延迟时间准确。
void
Timer0ISR(
void
)
interrupt
1
using
1
{
EA=
0
;
bUartBusy=OFF;
EA=
1
;
}
关于定时器的工作模式和时间间隔设置如下:
void
uartInit(
void
)
{
AUXR |=
0x80
;
//Timer0为1T模式
TMOD &=
0xF0
;
//设置Timer0为模式0(16位自动重装载)
//设置Timer0的计数器初值
TL0 = (
0xFFFF
- MCUFREQ / UARTBAUD) &
0xFF
;
TH0 = ((
0xFFFF
- MCUFREQ / UARTBAUD) >>
8
) &
0xFF
;
TR0 =
0
;
ET0 =
0
;
EA =
1
;
}
其中:AUXR 为特殊功能寄存器,地址为0x8e。
sfr
AUXR=
0x8E;
#define
MCUFREQ
11059200
//系统主频为11.0592MHz
#define
UARTBAUD
115200
//串口通讯的波特率
此时,数据的波形变化如下:
取其中的一个字符分析如下:完整的字符帧包括8位数据位,1个起始位,1个偶校验位,2个停止位。示意图如下所示。
在数据接收时,在双方的发送接收参数都协商好以后,通过对重复的停止位,校验位进行确认,就可由大量数据中判定出数据的起始位等信息。否则,需要定义握手信息来确认是否通讯正常。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1