傳統(tǒng)的8051系列單片機一般都配備一個串口,而STC89C52RC增強型單片機也不例外,只有一個串口可供使用,這樣就出問題了,假如當(dāng)前單片機系統(tǒng)要求二個串口或多個串口進(jìn)行同時通信,8051系列單片機只有一個串口可供通信就顯得十分尷尬,但是在實際的應(yīng)用中,有兩種方法可以選擇。
方法1:使用能夠支持多串口通信的單片機,不過通過更換其他單片機來代替8051系列單片機,這樣就會直接導(dǎo)致成本的增加,優(yōu)點就是編程簡單,而且通信穩(wěn)定可靠。
方法2:在IO資源比較充足的情況下,可以通過IO來模擬串口的通信,雖然這樣會增加編程的難度,模擬串口的波特率會比真正的串口通信低一個層次,但是唯一優(yōu)點就是成本上得到控制,而且通過不同的IO組合可以實現(xiàn)更加之多的模擬串口,在實際應(yīng)用中往往會采用模擬串口的方法來實現(xiàn)多串口通信。
普遍使用串口通信的數(shù)據(jù)流都是1位起始位、8位數(shù)據(jù)位、1位停止位的格式的,如表1。
表1
起始位
8位數(shù)據(jù)位
停止位
0
Bit0
Bit1
Bit2
Bit3
Bit4
Bit5
Bit6
Bit7
1
要注意的是,起始位作為識別是否有數(shù)據(jù)到來,停止位標(biāo)志數(shù)據(jù)已經(jīng)發(fā)送完畢。起始位固定值為0,停止位固定值為1,那么為什么起始位要是0,停止位要是1呢?這個很好理解,假設(shè)停止位固定值為1,為了更加易識別數(shù)據(jù)的到來,電平的跳變最為簡單也最容易識別,那么當(dāng)有數(shù)據(jù)來的時候,只要在規(guī)定的時間內(nèi)檢測到發(fā)送過來的第一位的電平是否0值,就可以確定是否有數(shù)據(jù)到來;另外停止位為1的作用就是當(dāng)沒有收發(fā)數(shù)據(jù)之后引腳置為高電平起到抗干擾的作用。
在平時使用紅外無線收發(fā)數(shù)據(jù)時,一般都采用模擬串口來實現(xiàn)的,但是有個問題要注意,波特率越高,傳輸距離越近;波特率越低,傳輸距離越遠(yuǎn)。對于這些通過模擬串口進(jìn)行數(shù)據(jù)傳輸,波特率適宜為1200b/s來進(jìn)行數(shù)據(jù)傳輸。
例子:在使用單片機的串口接收數(shù)據(jù)實驗當(dāng)中,使用串口調(diào)試助手發(fā)送16字節(jié)數(shù)據(jù),單片機采用模擬串口的方法將接收到的數(shù)據(jù)返發(fā)到PC機。
模擬串口實驗代碼:
1#include"stc.h"23#defineRXDP3_0//宏定義:接收數(shù)據(jù)的引腳4#defineTXDP3_1//宏定義:發(fā)送數(shù)據(jù)的引腳5#defineRECEIVE_MAX_BYTES16//宏定義:最大接收字節(jié)數(shù)67#defineTIMER_ENABLE(){TL0=TH0;TR0=1;fTimeouts=0;}//使能T/C8#defineTIMER_DISABLE(){TR0=0;fTimeouts=0;}//禁止T/C9#defineTIMER_WAIT(){while(!fTimeouts);fTimeouts=0;}//等待T/C超時101112unsignedcharfTimeouts=0;//T/C超時溢出標(biāo)志位13unsignedcharRecvBuf[16];//接收數(shù)據(jù)緩沖區(qū)14unsignedcharRecvCount=0;//接收數(shù)據(jù)計數(shù)器151617/****************************************18*函數(shù)名稱:SendByte19*輸入:byte要發(fā)送的字節(jié)20*輸出:無21*功能:串口發(fā)送單個字節(jié)22******************************************/23voidSendByte(unsignedcharb)24{25unsignedchari=8;2627TXD=0;2829TIMER_ENABLE();30TIMER_WAIT();313233while(i--)34{35if(b&1)TXD=1;36elseTXD=0;3738TIMER_WAIT();3940b>>=1;4142}434445TXD=1;4647TIMER_WAIT();48TIMER_DISABLE();49}50/****************************************51*函數(shù)名稱:RecvByte52*輸入:無53*輸出:單個字節(jié)54*功能:串口接收單個字節(jié)55******************************************/56unsignedcharRecvByte(void)57{58unsignedchari;59unsignedcharb=0;6061TIMER_ENABLE();62TIMER_WAIT();6364for(i=0;i<8;i++)65{66if(RXD)b|=(1<=RECEIVE_MAX_BYTES)137{138RecvCount=0;139140for(i=0;i