|
串行口的工作方式
8051單片機的全雙工串行口可編程為4種工作方式,現(xiàn)分述如下:
一.方式0:
方式0為移位寄存器輸入/輸出方式。可外接移位寄存器以擴展I/O口,也可以外接同步輸入/輸出設(shè)備。8位串行數(shù)據(jù)者是從RXD輸入或輸出,TXD用來輸出同步脈沖。
- 輸出 串行數(shù)據(jù)從RXD引腳輸出,TXD引腳輸出移位脈沖。CPU將數(shù)據(jù)寫入發(fā)送寄存器時,立即啟動發(fā)送,將8位數(shù)據(jù)以fos/12的固定波特率從RXD輸出,低位在前,高位在后。發(fā)送完一幀數(shù)據(jù)后,發(fā)送中斷標志TI由硬件置位。
- 輸入 當串行口以方式0接收時,先置位允許接收控制位REN。此時,RXD為串行數(shù)據(jù)輸入端,TXD仍為同步脈沖移位輸出端。當(RI)=0和(REN)=1同時滿足時,開始接收。當接收到第8位數(shù)據(jù)時,將數(shù)據(jù)移入接收寄存器,并由硬件置位RI。
二.方式1
方式1為波特率可變的10位異步通訊接口方式。發(fā)送或接收一幀信息,包括1個起始位0,8個數(shù)據(jù)位和1個停止位1。
- 輸出 當CPU執(zhí)行一條指令將數(shù)據(jù)寫入發(fā)送緩沖SBUF時,就啟動發(fā)送。串行數(shù)據(jù)從TXD引腳輸出,發(fā)送完一幀數(shù)據(jù)后,就由硬件置位TI。
- 輸入 在(REN)=1時,串行口采樣RXD引腳,當采樣到1至0的跳變時,確認是開始位0,就開始接收一幀數(shù)據(jù)。只有當(RI)=0且停止位為1或者(SM2)=0時,停止位才進入RB8,8位數(shù)據(jù)才能進入接收寄存器,并由硬件置位中斷標志RI;否則信息丟失。所以在方式1接收時,應(yīng)先用軟件清零RI和SM2標志。
三.方式2
方式二為固定波特率的11位UART方式。它比方式1增加了一位可程控位1或0的第9位數(shù)據(jù)。
- 輸出: 發(fā)送的串行數(shù)據(jù)由TXD端輸出一幀信息為11位,附加的第9位來自SCON寄存器的TB8位,用軟件置位或復(fù)位。它可作為多機通訊中地址/數(shù)據(jù)信息的標志位,也可以作為數(shù)據(jù)的奇偶校驗位。當CPU執(zhí)行一條數(shù)據(jù)寫入SUBF的指令時,就啟動發(fā)送器發(fā)送。發(fā)送一幀信息后,置位中斷標志TI。
- 輸入: 在(REN)=1時,串行口采樣RXD引腳,當采樣到1至0的跳變時,確認是開始位0,就開始接收一幀數(shù)據(jù)。在接收到附加的第9位數(shù)據(jù)后,當(RI)=0或者(SM2)=0時,第9位數(shù)據(jù)才進入RB8,8位數(shù)據(jù)才能進入接收寄存器,并由硬件置位中斷標志RI;否則信息丟失。且不置位RI。再過一位時間后,不管上述條件時否滿足,接收電路即行復(fù)位,并重新檢測RXD上從1到0的跳變。
四.方式3
方式3為波特率可變的11位UART方式。除波特率外,其余與方式2相同。
波特率選擇
如前所述,在串行通訊中,收發(fā)雙方的數(shù)據(jù)傳送率(波特率)要有一定的約定。在8051串行口的四種工作方式中,方式0和2的波特率是固定的,而方式1和3的波特率是可變的,由定時器T1的溢出率控制。
- 方式0
方式0的波特率固定為主振頻率的1/12。
- 方式2
方式2的波特率由PCON中的選擇位SMOD來決定,可由下式表示:
波特率=2的SMOD次方除以64再乘一個fosc,也就是當SMOD=1時,波特率為1/32fosc,當SMOD=0時,波特率為1/64fosc
3.方式1和方式3
定時器T1作為波特率發(fā)生器,其公式如下:
波特率= 定時器T1溢出率
T1溢出率= T1計數(shù)率/產(chǎn)生溢出所需的周期數(shù)
式中T1計數(shù)率取決于它工作在定時器狀態(tài)還是計數(shù)器狀態(tài)。當工作于定時器狀態(tài)時,T1計數(shù)率為fosc/12;當工作于計數(shù)器狀態(tài)時,T1計數(shù)率為外部輸入頻率,此頻率應(yīng)小于fosc/24。產(chǎn)生溢出所需周期與定時器T1的工作方式、T1的預(yù)置值有關(guān)。
定時器T1工作于方式0:溢出所需周期數(shù)=8192-x
定時器T1工作于方式1:溢出所需周期數(shù)=65536-x
定時器T1工作于方式2:溢出所需周期數(shù)=256-x
因為方式2為自動重裝入初值的8位定時器/計數(shù)器模式,所以用它來做波特率發(fā)生器最恰當。
當時鐘頻率選用11.0592MHZ時,取易獲得標準的波特率,所以很多單片機系統(tǒng)選用這個看起來“怪”的晶振就是這個道理。
下表列出了定時器T1工作于方式2常用波特率及初值。
|
常用波特率
|
Fosc(MHZ)
|
SMOD
|
TH1初值
|
|
19200
|
11.0592
|
1
|
FDH
|
|
9600
|
11.0592
|
0
|
FDH
|
|
4800
|
11.0592
|
0
|
FAH
|
|
2400
|
11.0592
|
0
|
F4h
|
|
1200
|
11.0592
|
0
|
E8h
|
串行口應(yīng)用編程實例
1. 串口方式0應(yīng)用編程 8051單片機串行口方式0為移位寄存器方式,外接一個串入并出的移位寄存器,就可以擴展一個并行口。
例:用8051串行口外接CD4094擴展8位并行輸出口,如圖所示,8位并行口的各位都接一個發(fā)光二極管,要求發(fā)光管呈流水燈狀態(tài)。串行口方式0的數(shù)據(jù)傳送可采用中斷方式,也可采用查詢方式,無論哪種方式,都要借助于TI或RI標志。串行發(fā)送時,可以靠TI置位(發(fā)完一幀數(shù)據(jù)后)引起中斷申請,在中斷服務(wù)程序中發(fā)送下一幀數(shù)據(jù),或者通過查詢TI的狀態(tài),只要TI為0就繼續(xù)查詢,TI為1就結(jié)束查詢,發(fā)送下一幀數(shù)據(jù)。在串行接收時,則由RI引起中斷或?qū)?span -us="" lang="EN">RI查詢來確定何時接收下一幀數(shù)據(jù)。無論采用什么方式,在開始通訊之前,都要先對控制寄存器SCON進行初始化。在方式0中將,將00H送SCON就可以了。
ORG 2000H
START: MOV SCON,#00H ;置串行口工作方式0
MOV A,#80H ;最高位燈先亮
CLR P1.0 ;關(guān)閉并行輸出(避象傳輸過程中,各LED的"暗紅"現(xiàn)象)
OUT0: MOV SBUF,A ;開始串行輸出
OUT1: JNB TI,OUT1 ;輸出完否
CLR TI ;完了,清TI標志,以備下次發(fā)送
SETB P1.0 ;打開并行口輸出
ACALL DELAY ;延時一段時間
RR A ;循環(huán)右移
CLR P1.0 ;關(guān)閉并行輸出
JMP OUT0 ;循環(huán)
說明:DELAY延時子程序可以用前面我們講P1口流水燈時用的延時子程序,這里就不給出了。
二、異步通訊
org 0000H
AJMP START
ORG 30H
START:
mov SP,#5fh ;
mov TMOD,#20h ;T1: 工作模式2
mov PCON,#80h ;SMOD=1
mov TH1,#0FDH ;初始化波特率(參見表)
mov SCON,#50h ;Standard UART settings
MOV R0,#0AAH ;準備送出的數(shù)
SETB REN ;允許接收
SETB TR1 ;T1開始工作
WAIT:
MOV A,R0
CPL A
MOV R0,A
MOV SBUF,A
LCALL DELAY
JBC TI,WAIT1 ;如果TI等于1,則清TI并轉(zhuǎn)WAIT1
AJMP WAIT
WAIT1: JBC RI,READ ;如果RI等于1,則清RI并轉(zhuǎn)READ
AJMP WAIT1
READ:
MOV A,SBUF ;將取得的數(shù)送P1口
MOV P1,A
LJMP WAIT
DELAY: ;延時子程序
MOV R7,#0ffH
DJNZ R7,$
RET
END
將程序編譯通過,寫入芯片,插入實驗板,用通讀電纜將實驗板與主機的串口相連就可以實驗了。上面的程序功能很簡單,就是每隔一段時間向主機輪流送數(shù)55H和AAH,并把主機送去的數(shù)送到P1口。可以在PC端用串口精靈來做實驗。串口精靈在我主頁上有下載。運行串口精靈后,按主界面上的“設(shè)置參數(shù)”按鈕進入“設(shè)置參數(shù)”對話框,按下面的參數(shù)進行設(shè)置。注意,我的機器上用的是串口2,如果你不是串口2,請自行更改串口的設(shè)置。
設(shè)置完后,按確定返回主界面,注意右邊有一個下拉列表,應(yīng)當選中“按16進制”。然后按“開始發(fā)送”、“開始接收”就可以了。按此設(shè)置,實驗板上應(yīng)當有兩只燈亮,6只燈滅。大家可以自行更改設(shè)置參數(shù)中的發(fā)送字符如55,00,FF等等,觀察燈的亮滅,并分析原因,也可以在主界面上更改下拉列表中的“按16進制”為“按10進制”或“按ASCII字符”來觀察現(xiàn)象,并仔細分析。這對于大家理解16進制、10進制、ASCII字符也是很有好處的。程序本身很簡單,又有注釋,這里就不詳加說明了。
三、上述程序的中斷版本
org 0000H
AJMP START
org 0023h
AJMP SERIAL ;
ORG 30H
START:
mov SP,#5fh ;
mov TMOD,#20h ;T1: 工作模式2
mov PCON,#80h ;SMOD=1
mov TH1,#0FDH ;初始化波特率(參見表)
mov SCON,#50h ;Standard UART settings
MOV R0,#0AAH ;準備送出的數(shù)
SETB REN ;允許接收
SETB TR1 ;T1開始工作
SETB EA ;開總中斷
SETB ES ;開串口中斷
SJMP $
SERIAL:
MOV A,SBUF
MOV P1,A
CLR RI
RETI
END
本程序沒有寫入發(fā)送程序,大家可以自行添加。
|