51 單片機UART 串口通信 方式1 實(shí)現
51單片機的UART串行通信是基于其串行口的可編程硬件結構,只要用正確的程序代碼通過(guò)初始化串行口對應寄存器的形式將其串行硬件結構初始化,再編寫(xiě)符合此串行口通信的程序代碼便能夠實(shí)現串行通信,其硬件結構決定了編程機制( 當然還要靠51芯片內CPU等機制 )。此結構具有UART( 通用異步收發(fā)器 )的全部功能,能同時(shí)進(jìn)行數據的發(fā)送和接收,也可作為同步移位寄存器使用。此結構集成于單片機內部。
本文引用地址:http://dyxdggzs.com/article/201611/318608.htmFigure1:51串行口結構
2 51串行口通信編程機制
決定編程機制的先決條件是51單片機的硬件結構及51芯片內部CPU的執行機制。根據串行通信口硬件結構,實(shí)現UART通信可以分為兩步:
(1)初始化串行通信口( UART )
- 配置SCON:設定串口方式( SM0及SM1位配置4種方式);串口是否要接收數據(REN位)
- 設定PCON寄存器的SMOD位(若非串口方式0 )
- 若串口為方式1和方式3,則需要配置TMOD:選擇定時(shí)器1并配置其初值裝載方式(MI M0位),并設置TH1,TL0的初值以確定通信的波特率(由波特率的計算公式),然后配置TCON:開(kāi)啟定時(shí)器1( TR1 )。
- 允許使用中斷( ES ),開(kāi)啟UART中斷( EA )
可以這些寄存器的配置含義可以查看相應的知識點(diǎn):中斷配置IE寄存器、定時(shí)/計數方式配置寄存器TMOD、定時(shí)/計數控制寄存器及通信寄存器SCON寄存器筆記。
(2)程序實(shí)現:編寫(xiě)發(fā)送/接收數據代碼及中斷服務(wù)程序
注:TI及RI的置位可查看SCON寄存器TI RI被置位的條件
[1]發(fā)送的數據需要通過(guò)程序指令“SBUF =數據;”來(lái)將數據送往串行發(fā)送緩沖寄存器中,在此條語(yǔ)句后,要用循環(huán)判斷SCON寄存器中的TI位是否被硬件置位1(表示發(fā)送完畢),等待發(fā)送完畢,TI置位被置為1時(shí)會(huì )進(jìn)入串行中斷服務(wù)程序[由此不能在串行中斷服務(wù)程序里面將TI置0,因為從循環(huán)里面進(jìn)入中斷后會(huì )返回到循環(huán)語(yǔ)句中來(lái),所以要在串行中斷服務(wù)程序之外將TI置0,置0的目的是提供下一次數據發(fā)送成功的依據或進(jìn)入中斷服務(wù)器程序],需要用程序代碼將TI重新置為0;然后再由CPU控制的時(shí)序將數據從TXD( P3.1 )腳發(fā)出,經(jīng)過(guò)連接的串口線(xiàn)到從設備(接收數據的設備)。
[2]獲取接收到數據時(shí)需要通過(guò)程序指令“存數據變量=SBUF;”將串行接收緩沖寄存器接收到的數據讀取到程序中來(lái),當接收到數據完畢后,RI會(huì )被硬件置位1,此時(shí)也會(huì )進(jìn)入串行中斷服務(wù)程序,需要用程序指令將RI重新置位0。當然接收數據是由RXD( P3.0 )引腳完成。
[3]串行中斷服務(wù)程序的中斷號為4,所以編寫(xiě)串行中斷服務(wù)程序時(shí)需要有以下格式:
void函數名()interrupt 4
{
中斷服務(wù)程序內容
}
串行中斷服務(wù)函數當TI或RI被硬件置位1時(shí)才被系統調用。TI被硬件置1的情況是,當串行發(fā)送緩沖寄存器內的數據被通過(guò)TXD( P3.1 )發(fā)送完畢時(shí)(不同的串口方式置1條件不同)不是指將數據存入串行發(fā)送緩沖器中時(shí)TI會(huì )被置1,同理RI被置1的情況是當RXD( P3.0 )接收到數據將此數據按位存入串行接收緩沖寄存器內完畢時(shí)(不同串口方式置1的條件不同)不是指從串行接收緩沖寄存器讀完數據時(shí)RI會(huì )被置1。這個(gè)數據的長(cháng)度和TI( RI )被置位1根據串行通信方式不同而不同。
對于用程序來(lái)實(shí)現51單片機中的串行通信還需要明確兩點(diǎn)(與其它部分的聯(lián)系):
(1)在51單片機串行通信的方式1和方式3中,波特率由定時(shí)器1的溢出率決定。
(2)SBUF為特殊功能寄存器,它在程序中的兩種不同的指令形式表示不同的含義,當在程序中用寫(xiě)指令“SBUF=a;”時(shí),表示將a存入串行數據發(fā)送緩沖寄存器中;當在程序中使用讀指令“a=SBUF;”時(shí),表示向串行數據接收緩沖寄存器讀數據并將得到數據賦值于a。接收器具有雙緩沖結構,即在從接收寄存器中前一個(gè)已經(jīng)收到的字節之前,便能接收第二個(gè)字節,如果第二個(gè)字節已經(jīng)接收完畢,第一個(gè)字節還沒(méi)有被讀出,則第一個(gè)字節就損失( 被覆蓋 )。而發(fā)送器中的數據是由CPU控制的,所以不必程序用戶(hù)擔憂(yōu)。
3 程序實(shí)現串行通信
程序的大體框架為main主函數、串行中斷服務(wù)程序、子函數(初始化串口、延時(shí)函數,字符串處理函數等)
(1)首先是用程序實(shí)現串行通信的初始化
//串口初始化 void UART_Init(void) { SCON = 0x40; //串口方式1 PCON = 0; //SMOD=0 REN = 1; //允許接收 TMOD = 0x20; //定時(shí)器1定時(shí)方式2 TR1 = 1; //啟動(dòng)定時(shí)器 ES = 1; //UART中斷 EA = 1; //中斷使能 } |
(2)用程序實(shí)現發(fā)數據
將要發(fā)送的數據賦值給SBUF即可。
SBUF = aChar; while(TI == 0);//等待,直到發(fā)送成功 TI = 0; |
這是發(fā)送一次數據(如一個(gè)字符,在串口發(fā)送方式1下占10個(gè)位)的代碼,可單獨寫(xiě)成函數。此種寫(xiě)法不可以將“TI = 0;”寫(xiě)在中斷函數中,不然會(huì )造成死循環(huán)。
(3)在中斷函數中接受數據
不管發(fā)送數據成功還是接受到數據都會(huì )進(jìn)入到中斷程序中,故而在中斷程序中判斷是否RI被置位為1,如是則表示收到了數據。
void UART_Receive_Int() interrupt 4 { if( RI == 1) { RI = 0; if( index < 1 ) { Receive[index] = SBUF; index++; }else{ index = 0; } } } |
然后只需要在主程序main函數中調用串行口初始化函數及用一定的邏輯調用數據發(fā)送函數即可。
(4)通過(guò)串口調試助手來(lái)觀(guān)察程序執行效果
發(fā)數據顯示
設置串口調試助手:
Figure2:向調試助手發(fā)數據顯示
在串口調試助手中按照下劃線(xiàn)部分設置后,結果顯示區域就會(huì )顯示由程序發(fā)將上來(lái)的數據。
串口調試助手往單片機發(fā)送數據并再顯示到串口調試界面之上
Figure3:調試助手向單片機發(fā)送數據顯示界面
對串口調試助手的設置除了發(fā)送數據之上的設置之外還需要在表格中填入字符串,然后點(diǎn)擊表格下畫(huà)圈使之為“停止循環(huán)發(fā)送”,然后就可以將收到的數據同將要發(fā)送的數據一起發(fā)送到串口調試界面之上來(lái)。
此次筆記記錄完畢。
評論