在連續(xù)的高速異步通訊中,如果沒有作為握手用的信號位,那么如何辨識一個字符幀的開始變成了難題。從一串連續(xù)的數(shù)字中找出字節(jié)的幀頭,然后正確的識別出要傳輸?shù)男畔ⅲ亲龆啻螄L試,并且通訊雙方約定好起始信息,方可正確傳輸信息。此時,為了讓信號有較為明顯的辨識信息,增加奇偶校驗位,以及加長停止位的長度,都是一個提高幀起始判定的一種方法。
在波特率為115200的設置下,如果采用N,8,1的標準設置,可以從下面的波形圖中看出,如果連續(xù)發(fā)送字符0x55,則停止位到下一個起始位之間的脈寬是11.12us, 而標準的數(shù)字位的脈寬是8.83us。如果在兩個數(shù)據(jù)的發(fā)送之間沒有其他延時信號,則可能無法分辨出那一個位是一個字符幀的起始位,從而導致后續(xù)其它字符的幀錯誤。這樣在使用軟件方法做串行數(shù)據(jù)接收時,就會出錯。

圖1,在波特率115200時,標準位脈沖寬度為8.83us
圖2,在波特率115200時,停止位到下一個起始位的寬度可能更小,這里是11.12us。
圖3,出現(xiàn)幀判別錯誤的情形(這里是奇偶校驗設置不正確導致)。
為了解決這個異常,可以通過加長停止位的方法,提高軟件對起始位的識別幾率。因此上可以將常用的1個停止位,增加到1.5個或2個位長度。對于長線傳輸,為了檢查傳輸過程中信號是否受其他干擾而導致的翻轉(zhuǎn),又在停止位之前,插入奇偶校驗位的方式,協(xié)議商定傳輸?shù)?的個數(shù)是奇數(shù)個或者偶數(shù)個,然后通過插補的方式確定每幀的情況相同。這樣,如果在接收端發(fā)現(xiàn)幀錯誤,可以及時檢查出來。
使用C51的發(fā)送程序:
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的電平,直到下一次中斷到來。輸出一個位寬的數(shù)據(jù)。
//由低位開始,將數(shù)據(jù)通過串口輸出
#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的個數(shù)和作為偶校驗結(jié)果位發(fā)送。
bUartBusy = ON;
while(bUartBusy == ON);
#endif
TXB = 1; // 發(fā)送第一個串口停止位
bUartBusy = ON;
while(bUartBusy == ON);
#ifdef STOP2BITS //如果定義2位停止位
bUartBusy = ON; //發(fā)送第2個停止位
while(bUartBusy == ON);
#endif
TR0 = 0; //定時器0結(jié)束計時
ET0 = 0; //禁能定時器0中斷
}
定時器Timer0的中斷服務中,僅僅完成標志設置,確保每個數(shù)據(jù)位發(fā)送的延遲時間準確。
void Timer0ISR(void) interrupt 1 using 1
{
EA=0;
bUartBusy=OFF;
EA=1;
}
關(guān)于定時器的工作模式和時間間隔設置如下:
void uartInit(void)
{
AUXR |= 0x80; //Timer0為1T模式
TMOD &= 0xF0; //設置Timer0為模式0(16位自動重裝載)
//設置Timer0的計數(shù)器初值
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 //系統(tǒng)主頻為11.0592MHz
#define UARTBAUD 115200 //串口通訊的波特率
此時,數(shù)據(jù)的波形變化如下:

取其中的一個字符分析如下:完整的字符幀包括8位數(shù)據(jù)位,1個起始位,1個偶校驗位,2個停止位。示意圖如下所示。
在數(shù)據(jù)接收時,在雙方的發(fā)送接收參數(shù)都協(xié)商好以后,通過對重復的停止位,校驗位進行確認,就可由大量數(shù)據(jù)中判定出數(shù)據(jù)的起始位等信息。否則,需要定義握手信息來確認是否通訊正常。
|