51單片機(jī)是對所有兼容Intel 8031指令系統(tǒng)的單片機(jī)的統(tǒng)稱。該系列單片機(jī)的始祖是Intel的8004單片機(jī),后來隨著Flash rom技術(shù)的發(fā)展,8004單片機(jī)取得了長足的進(jìn)展,成為應(yīng)用最廣泛的8位單片機(jī)之一,其代表型號是ATMEL公司的AT89系列,它廣泛應(yīng)用于工業(yè)測控系統(tǒng)之中。很多公司都有51系列的兼容機(jī)型推出,今后很長的一段時間內(nèi)將占有大量市場。51單片機(jī)是基礎(chǔ)入門的一個單片機(jī),還是應(yīng)用最廣泛的一種。需要注意的是51系列的單片機(jī)一般不具備自編程能力。
UART是一種通用串行數(shù)據(jù)總線,用于異步通信。該總線雙向通信,可以實(shí)現(xiàn)全雙工傳輸和接收。在嵌入式設(shè)計(jì)中,UART用于主機(jī)與輔助設(shè)備通信,如汽車音響與外接AP之間的通信,與PC機(jī)通信包括與監(jiān)控調(diào)試器和其它器件,如EEPROM通信。
計(jì)算機(jī)內(nèi)部采用并行數(shù)據(jù),不能直接把數(shù)據(jù)發(fā)到Modem,必須經(jīng)過UART整理才能進(jìn)行異步傳輸,其過程為:CPU先把準(zhǔn)備寫入串行設(shè)備的數(shù)據(jù)放到UART的寄存器(臨時內(nèi)存塊)中,再通過FIFO(First Input First Output,先入先出隊(duì)列)傳送到串行設(shè)備,若是沒有FIFO,信息將變得雜亂無章,不可能傳送到Modem。它是用于控制計(jì)算機(jī)與串行設(shè)備的芯片。有一點(diǎn)要注意的是,它提供了RS-232C數(shù)據(jù)終端設(shè)備接口,這樣計(jì)算機(jī)就可以和調(diào)制解調(diào)器或其它使用RS-232C接口的串行設(shè)備通信了。
作為接口的一部分,UART還提供以下功能:將由計(jì)算機(jī)內(nèi)部傳送過來的并行數(shù)據(jù)轉(zhuǎn)換為輸出的串行數(shù)據(jù)流。將計(jì)算機(jī)外部來的串行數(shù)據(jù)轉(zhuǎn)換為字節(jié),供計(jì)算機(jī)內(nèi)部并行數(shù)據(jù)的器件使用。在輸出的串行數(shù)據(jù)流中加入奇偶校驗(yàn)位,并對從外部接收的數(shù)據(jù)流進(jìn)行奇偶校驗(yàn)。在輸出數(shù)據(jù)流中加入啟停標(biāo)記,并從接收數(shù)據(jù)流中刪除啟停標(biāo)記。處理由鍵盤或鼠標(biāo)發(fā)出的中斷信號(鍵盤和鼠標(biāo)也是串行設(shè)備)。
可以處理計(jì)算機(jī)與外部串行設(shè)備的同步管理問題。有一些比較高檔的UART還提供輸入輸出數(shù)據(jù)的緩沖區(qū),比較新的UART是16550,它可以在計(jì)算機(jī)需要處理數(shù)據(jù)前在其緩沖區(qū)內(nèi)存儲16字節(jié)數(shù)據(jù),而通常的UART是8250。如果您購買一個內(nèi)置的調(diào)制解調(diào)器,此調(diào)制解調(diào)器內(nèi)部通常就會有16550 UART。接下來我們一起了解一下基于51單片機(jī)的UART串口通信。
51串行口結(jié)構(gòu)
51單片機(jī)的UART串行通信是基于其串行口的可編程硬件結(jié)構(gòu),只要用正確的程序代碼通過初始化串行口對應(yīng)寄存器的形式將其串行硬件結(jié)構(gòu)初始化,再編寫符合此串行口通信的程序代碼便能夠?qū)崿F(xiàn)串行通信,其硬件結(jié)構(gòu)決定了編程機(jī)制( 當(dāng)然還要靠51芯片內(nèi)CPU等機(jī)制 )。
此結(jié)構(gòu)具有UART( 通用異步收發(fā)器 )的全部功能,能同時進(jìn)行數(shù)據(jù)的發(fā)送和接收,也可作為同步移位寄存器使用。此結(jié)構(gòu)集成于單片機(jī)內(nèi)部。
51串行口通信編程機(jī)制
決定編程機(jī)制的先決條件是51單片機(jī)的硬件結(jié)構(gòu)及51芯片內(nèi)部CPU的執(zhí)行機(jī)制。根據(jù)串行通信口硬件結(jié)構(gòu),實(shí)現(xiàn)UART通信可以分為兩步:
(1)初始化串行通信口( UART )
配置SCON:設(shè)定串口方式( SM0及SM1位配置4種方式 );串口是否要接收數(shù)據(jù)(REN位 )
設(shè)定PCON寄存器的SMOD位(若非串口方式0 )
若串口為方式1和方式3,則需要配置TMOD:選擇定時器1并配置其初值裝載方式(MI M0位 ),并設(shè)置TH1,TL0的初值以確定通信的波特率(由波特率的計(jì)算公式 ),然后配置TCON:開啟定時器1( TR1 )。
允許使用中斷( ES ),開啟UART中斷( EA )
可以這些寄存器的配置含義可以查看相應(yīng)的知識點(diǎn):中斷配置IE寄存器、定時/計(jì)數(shù)方式配置寄存器TMOD、定時/計(jì)數(shù)控制寄存器及通信寄存器SCON寄存器筆記。
(2)程序?qū)崿F(xiàn):編寫發(fā)送/接收數(shù)據(jù)代碼及中斷服務(wù)程序
注:TI及RI的置位可查看SCON寄存器TI RI被置位的條件
[1]發(fā)送的數(shù)據(jù)需要通過程序指令“SBUF =數(shù)據(jù);”來將數(shù)據(jù)送往串行發(fā)送緩沖寄存器中,在此條語句后,要用循環(huán)判斷SCON寄存器中的TI位是否被硬件置位1(表示發(fā)送完畢),等待發(fā)送完畢,TI置位被置為1時會進(jìn)入串行中斷服務(wù)程序[由此不能在串行中斷服務(wù)程序里面將TI置0,因?yàn)閺难h(huán)里面進(jìn)入中斷后會返回到循環(huán)語句中來,所以要在串行中斷服務(wù)程序之外將TI置0,置0的目的是提供下一次數(shù)據(jù)發(fā)送成功的依據(jù)或進(jìn)入中斷服務(wù)器程序 ],需要用程序代碼將TI重新置為0;然后再由CPU控制的時序?qū)?shù)據(jù)從TXD( P3.1 )腳發(fā)出,經(jīng)過連接的串口線到從設(shè)備(接收數(shù)據(jù)的設(shè)備 )。
[2]獲取接收到數(shù)據(jù)時需要通過程序指令“存數(shù)據(jù)變量=SBUF;”將串行接收緩沖寄存器接收到的數(shù)據(jù)讀取到程序中來,當(dāng)接收到數(shù)據(jù)完畢后,RI會被硬件置位1,此時也會進(jìn)入串行中斷服務(wù)程序,需要用程序指令將RI重新置位0。當(dāng)然接收數(shù)據(jù)是由RXD( P3.0 )引腳完成。
[3]串行中斷服務(wù)程序的中斷號為4,所以編寫串行中斷服務(wù)程序時需要有以下格式:
void 函數(shù)名() interrupt 4
{
中斷服務(wù)程序內(nèi)容
}
串行中斷服務(wù)函數(shù)當(dāng)TI或RI被硬件置位1時才被系統(tǒng)調(diào)用。TI被硬件置1的情況是,當(dāng)串行發(fā)送緩沖寄存器內(nèi)的數(shù)據(jù)被通過TXD( P3.1 )發(fā)送完畢時( 不同的串口方式置1條件不同 )不是指將數(shù)據(jù)存入串行發(fā)送緩沖器中時TI會被置1,同理RI被置1的情況是當(dāng)RXD( P3.0 )接收到數(shù)據(jù)將此數(shù)據(jù)按位存入串行接收緩沖寄存器內(nèi)完畢時( 不同串口方式置1的條件不同 )不是指從串行接收緩沖寄存器讀完數(shù)據(jù)時RI會被置1。這個數(shù)據(jù)的長度和TI( RI )被置位1根據(jù)串行通信方式不同而不同。
對于用程序來實(shí)現(xiàn)51單片機(jī)中的串行通信還需要明確兩點(diǎn)(與其它部分的聯(lián)系):
(1)在51單片機(jī)串行通信的方式1和方式3中,波特率由定時器1的溢出率決定。
(2)SBUF為特殊功能寄存器,它在程序中的兩種不同的指令形式表示不同的含義,當(dāng)在程序中用寫指令“SBUF=a;”時,表示將a存入串行數(shù)據(jù)發(fā)送緩沖寄存器中;當(dāng)在程序中使用讀指令“a=SBUF;”時,表示向串行數(shù)據(jù)接收緩沖寄存器讀數(shù)據(jù)并將得到數(shù)據(jù)賦值于a。接收器具有雙緩沖結(jié)構(gòu),即在從接收寄存器中前一個已經(jīng)收到的字節(jié)之前,便能接收第二個字節(jié),如果第二個字節(jié)已經(jīng)接收完畢,第一個字節(jié)還沒有被讀出,則第一個字節(jié)就損失( 被覆蓋 )。而發(fā)送器中的數(shù)據(jù)是由CPU控制的,所以不必程序用戶擔(dān)憂。
程序?qū)崿F(xiàn)串行通信
程序的大體框架為main主函數(shù)、串行中斷服務(wù)程序、子函數(shù)(初始化串口、延時函數(shù),字符串處理函數(shù)等)
(1)首先是用程序?qū)崿F(xiàn)串行通信的初始化
(2)用程序?qū)崿F(xiàn)發(fā)數(shù)據(jù)
將要發(fā)送的數(shù)據(jù)賦值給SBUF即可。
(3)在中斷函數(shù)中接受數(shù)據(jù)
不管發(fā)送數(shù)據(jù)成功還是接受到數(shù)據(jù)都會進(jìn)入到中斷程序中,故而在中斷程序中判斷是否RI被置位為1,如是則表示收到了數(shù)據(jù)。
然后只需要在主程序main函數(shù)中調(diào)用串行口初始化函數(shù)及用一定的邏輯調(diào)用數(shù)據(jù)發(fā)送函數(shù)即可。
(4)通過串口調(diào)試助手來觀察程序執(zhí)行效果
【1】發(fā)數(shù)據(jù)顯示
設(shè)置串口調(diào)試助手:
在串口調(diào)試助手中按照下劃線部分設(shè)置后,結(jié)果顯示區(qū)域就會顯示由程序發(fā)將上來的數(shù)據(jù)。
【2】串口調(diào)試助手往單片機(jī)發(fā)送數(shù)據(jù)并再顯示到串口調(diào)試界面之上
對串口調(diào)試助手的設(shè)置除了發(fā)送數(shù)據(jù)之上的設(shè)置之外還需要在表格中填入字符串,然后點(diǎn)擊表格下畫圈使之為“停止循環(huán)發(fā)送”,然后就可以將收到的數(shù)據(jù)同將要發(fā)送的數(shù)據(jù)一起發(fā)送到串口調(diào)試界面之上來。
評論
查看更多