在连续的高速异步通讯中,如果没有作为握手用的信号位,那么如何辨识一个字符帧的开始变成了难题。从一串连续的数字中找出字节的帧头,然后正确的识别出要传输的信息,除非做多次尝试,并且通讯双方约定好起始信息,方可正确传输信息。此时,为了让信号有较为明显的辨识信息,增加奇偶校验位,以及加长停止位的长度,都是一个提高帧起始判定的一种方法。
在波特率为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个停止位。示意图如下所示。
在数据接收时,在双方的发送接收参数都协商好以后,通过对重复的停止位,校验位进行确认,就可由大量数据中判定出数据的起始位等信息。否则,需要定义握手信息来确认是否通讯正常。
|