《單片機技術(shù)》課件項目六 單片機溫度采集系統(tǒng)_第1頁
《單片機技術(shù)》課件項目六 單片機溫度采集系統(tǒng)_第2頁
《單片機技術(shù)》課件項目六 單片機溫度采集系統(tǒng)_第3頁
《單片機技術(shù)》課件項目六 單片機溫度采集系統(tǒng)_第4頁
《單片機技術(shù)》課件項目六 單片機溫度采集系統(tǒng)_第5頁
已閱讀5頁,還剩132頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

一、學習目標1.了解單片機的串口的概念。2.掌握單片機串口硬件結(jié)構(gòu)。3.掌握單片機串口通信工作方式。4.掌握單總線(一線總線)工作原理。5.掌握單片機驅(qū)動DS18B20驅(qū)動方法。二、學習任務任務一用串口擴展IO口;任務二單片機雙機通信;任務三PC與單片機串口通信;任務四DS18B20溫度采集系統(tǒng)。三、任務分解任務一用串口擴展I0口【任務描述】大街上有很多點陣廣告屏,有的是插U盤更新內(nèi)容,有的則是使用PC機通過單片機串口動態(tài)更新內(nèi)容,串口動態(tài)更新內(nèi)容的實質(zhì)就是單片機與外界通信。單片機之間可實現(xiàn)雙機通信、多機通信并可與PC機通信;利用PC機與單片機可組成上位機、下位機通信網(wǎng)絡(luò)。本任務用單片機的串口擴展出8個IO口,實現(xiàn)流水燈效果?!救蝿彰枋觥看蠼稚嫌泻芏帱c陣廣告屏,有的是插U盤更新內(nèi)容,有的則是使用PC機通過單片機串口動態(tài)更新內(nèi)容,串口動態(tài)更新內(nèi)容的實質(zhì)就是單片機與外界通信。單片機之間可實現(xiàn)雙機通信、多機通信并可與PC機通信;利用PC機與單片機可組成上位機、下位機通信網(wǎng)絡(luò)。本任務用單片機的串口擴展出8個IO口,實現(xiàn)流水燈效果?!救蝿辗治觥渴煜ふ莆諉纹瑱C串口的硬件結(jié)構(gòu),熟悉單片機串口通信工作方式0的應用?!鞠嚓P(guān)知識】一、串行通信概述

計算機與外界的信息交換稱為通信。通信的基本方式可分為并行通信和串行通信兩種。所謂并行通信是指數(shù)據(jù)的各位同時在多根數(shù)據(jù)線上發(fā)送或接收。串行通信是數(shù)據(jù)的各位在同一根數(shù)據(jù)線上依次逐位發(fā)送或接收。1串行通信基礎(chǔ)知識

目前串行通信在單片機雙機、多機以及單片機與PC機之間的通信等方面得到了廣泛應用。

并行通信示意圖P0.7P0.6P0.5P0.4P0.3P0.2P0.1P0.0P2.7RDWRRDWRCSD7D6D5D4D3D2D1D0825589C51

串行通信示意圖89C51外設(shè)TXDTXDRXDRXD發(fā)送接收1.1異步通信和同步通信

串行通信按同步方式可分為異步通信和同步通信兩種基本通信方式。1)

同步通信(SynchronousCommunication)

同步通信是一種連續(xù)傳送數(shù)據(jù)的通信方式,一次通信傳送多個字符數(shù)據(jù),稱為一幀信息。數(shù)據(jù)傳輸速率較高,通??蛇_56000bps或更高。其缺點是要求發(fā)送時鐘和接收時鐘保持嚴格同步。同步字符數(shù)據(jù)字符1數(shù)據(jù)字符2…數(shù)據(jù)字符n-1數(shù)據(jù)字符n校驗字符(校驗字符)同步通信數(shù)據(jù)傳送格式2)異步通信(AsynchronousCommunication)

在異步通信中,數(shù)據(jù)通常是以字符或字節(jié)為單位組成數(shù)據(jù)幀進行傳送的。收、發(fā)端各有一套彼此獨立,互不同步的通信機構(gòu),由于收發(fā)數(shù)據(jù)的幀格式相同,因此可以相互識別接收到的數(shù)據(jù)信息。同步通信的數(shù)據(jù)幀格式如圖所示。D0D1D2D3D4

D5

D6

D7

0/11111D70/1100D0D1第n字符幀空閑位停止位奇偶校驗停止位8位數(shù)據(jù)8位數(shù)據(jù)起始位起始位奇偶校驗第n-1字符幀第n+1字符幀異步通信幀格式8位數(shù)據(jù)

異步通信信息幀格式如圖所示。(1)起始位:在沒有數(shù)據(jù)傳送時,通信線上處于邏輯“1”狀態(tài)。當發(fā)送端要發(fā)送1個字符數(shù)據(jù)時,首先發(fā)送1個邏輯“0”信號,這個低電平便是幀格式的起始位。其作用是向接收端表示發(fā)送端開始發(fā)送一幀數(shù)據(jù)。接收端檢測到這個低電平后,就準備接收數(shù)據(jù)信號。(2)數(shù)據(jù)位:在起始位之后,發(fā)送端發(fā)出(或接收端接收)的是數(shù)據(jù)位,數(shù)據(jù)的位數(shù)沒有嚴格的限制,5~8位均可。由低位到高位逐位傳送。(3)奇偶校驗位:數(shù)據(jù)位發(fā)送完(接收完)之后,可發(fā)送一位用來檢驗數(shù)據(jù)在傳送過程中是否出錯的奇偶校驗位。奇偶校驗是收發(fā)雙方預先約定好的有限差錯檢驗方式之一。有時也可不用奇偶校驗。(4)停止位:字符幀格式的最后部分是停止位,邏輯“1”電平有效,它可占1/2位、1位或2位。停止位表示傳送一幀信息的結(jié)束,也為發(fā)送下一幀信息作好準備。1.2串行通信的波特率

波特率(BaudRate)是串行通信中一個重要概念,它是指傳輸數(shù)據(jù)的速率,亦稱比特率。波特率的定義是每秒傳輸二進制數(shù)碼的位數(shù)。如:波特率為1200bps是指每秒鐘能傳輸1200位二進制數(shù)碼。

波特率的倒數(shù)即為每位數(shù)據(jù)傳輸時間。例如:波特率為1200bps,每位的傳輸時間為:1)(833.01200msdT==

波特率和字符的傳輸速率不同,若采用圖9.4的數(shù)據(jù)幀格式,并且數(shù)據(jù)幀連續(xù)傳送(無空閑位),則實際的字符傳輸速率為1200/11=109.09幀/秒。

波特率也不同于發(fā)送時鐘和接收時鐘頻率。同步通信的波特率和時鐘頻率相等,而異步通信的波特率通常是可變的。1.3串行通信的制式1)單工制式(Simplex)

單工制式是指甲乙雙方通信只能單向傳送數(shù)據(jù)。單工制式如圖9.5所示。

在串行通信中,數(shù)據(jù)是在兩個站之間傳送的。按照數(shù)據(jù)傳送方向,串行通信可分為三種制式。發(fā)送器A接收器B圖6.5單工制式2)半雙工制式(Halfduplex)

半雙工制式是指通信雙方都具有發(fā)送器和接收器,雙方既可發(fā)送也可接收,但接收和發(fā)送不能同時進行,即發(fā)送時就不能接收,接收時就不能發(fā)送。半雙工制式如圖6.6所示。發(fā)送接收發(fā)送接收A端B端圖6.6半雙工制式3)全雙工制式(Fullduplex)

全雙工制式是指通信雙方均設(shè)有發(fā)送器和接收器,并且將信道劃分為發(fā)送信道和接收信道,兩端數(shù)據(jù)允許同時收發(fā),因此通信效率比前兩種高。全雙工制式如圖6.7所示。發(fā)送接收接收發(fā)送A端B端圖6.7全雙工制式1.4串行通信的校驗

串行通信的目的不只是傳送數(shù)據(jù)信息,更重要的是應確保準確無誤地傳送。因此必須考慮在通信過程中對數(shù)據(jù)差錯進行校驗,因為差錯校驗是保證準確無誤地通信的關(guān)鍵。常用差錯校驗方法有奇偶校驗、累加和校驗以及循環(huán)冗余碼校驗等。1)奇偶校驗

奇偶校驗的特點是按字符校驗,即在發(fā)送每個字符數(shù)據(jù)之后都附加一位奇偶校驗位(1或0),當設(shè)置為奇校驗時,數(shù)據(jù)中1的個數(shù)與校驗位1的個數(shù)之和應為奇數(shù);反之則為偶校驗。收、發(fā)雙方應具有一致的差錯檢驗設(shè)置,當接收1幀字符時,對1的個數(shù)進行檢驗,若奇偶性(收、發(fā)雙方)一致則說明傳輸正確。奇偶校驗只能檢測到那種影響奇偶位數(shù)的錯誤,比較低級且速度慢,一般只用在異步通信中。2)累加和校驗

累加和校驗是指發(fā)送方將所發(fā)送的數(shù)據(jù)塊求和,并將“校驗和”附加到數(shù)據(jù)塊末尾。接收方接收數(shù)據(jù)時也是先對數(shù)據(jù)塊求和,將所得結(jié)果與發(fā)送方的“校驗和”進行比較,若兩者相同,表示傳送正確,若不同則表示傳送出了差錯。“校驗和”的加法運算可用邏輯加,也可用算術(shù)加。累加和校驗的缺點是無法檢驗出字節(jié)或位序的錯誤。3)循環(huán)冗余碼校驗(CRC)

循環(huán)冗余碼校驗的基本原理是將一個數(shù)據(jù)塊看成一個位數(shù)很長的二進制數(shù),然后用一個特定的數(shù)去除它,將余數(shù)作校驗碼附在數(shù)據(jù)塊之后一起發(fā)送。接收端收到該數(shù)據(jù)塊和校驗碼后,進行同樣的運算來校驗傳送是否出錯。目前CRC已廣泛用于數(shù)據(jù)存儲和數(shù)據(jù)通信中,并在國際上形成規(guī)范,市面上已有不少現(xiàn)成的CRC軟件算法。2AT89C51的串行接口AT89C51內(nèi)部有一個可編程全雙工串行通信接口。該部件不僅能同時進行數(shù)據(jù)的發(fā)送和接收,也可作為一個同步移位寄存器使用。下面將對其內(nèi)部結(jié)構(gòu)、工作方式以及波特率進行介紹。2.1串行接口的結(jié)構(gòu)及功能AT89C51串行口結(jié)構(gòu)框圖發(fā)送SBUF(99H)接收SBUF(99H)同步時鐘門電路發(fā)送控制器接收控制器輸入移位寄存器串行口控制寄存器(98H)內(nèi)部總線≥1串行口中斷TIRITXD(P3.1)RXD(P3.0)

發(fā)送數(shù)據(jù)過程:CPU通過內(nèi)部總線將并行數(shù)據(jù)寫入發(fā)送SBUF,在發(fā)送控制電路的控制下,按設(shè)定好的波特率,每來一次移位脈沖,通過引腳TXD向外輸出一位。一幀數(shù)據(jù)發(fā)送結(jié)束后,向CPU發(fā)出中斷申請,TI位置1。CPU響應中斷后,開始準備發(fā)送下一幀數(shù)據(jù)。發(fā)送SBUF(99H)接收SBUF(99H)同步時鐘門電路發(fā)送控制器接收控制器輸入移位寄存器串行口控制寄存器(98H)內(nèi)部總線≥1串行口中斷TIRITXD(P3.1)RXD(P3.0)接收數(shù)據(jù)過程:CPU不停地檢測引腳RXD上的信號,當信號中出現(xiàn)低電平時,在接收控制電路的控制下,按設(shè)定好的波特率,每來一次移位脈沖,讀取外部設(shè)備發(fā)送的一位數(shù)據(jù)到移位寄存器。一幀數(shù)據(jù)結(jié)束后,數(shù)據(jù)被存入接收SBUF,同時向CPU發(fā)出中斷申請,RI位置1。CPU響應中斷后,開始接收下一幀數(shù)據(jù)。1)串行數(shù)據(jù)緩沖器SBUFSBUF是串行口緩沖寄存器,包括發(fā)送寄存器和接收寄存器,以便能以全雙工方式進行通信。此外,在接收寄存器之前還有移位寄存器,從而構(gòu)成了串行接收的雙緩沖結(jié)構(gòu),這樣可以避免在數(shù)據(jù)接收過程中出現(xiàn)幀重疊錯誤。發(fā)送數(shù)據(jù)時,由于CPU是主動的,不會發(fā)生幀重疊錯誤,因此發(fā)送電路不需要雙重緩沖結(jié)構(gòu)。

在邏輯上,SBUF只有一個,它既表示發(fā)送寄存器,又表示接收寄存器,具有同一個單元地址99H。但在物理結(jié)構(gòu)上,則有兩個完全獨立的SBUF,一個是發(fā)送緩沖寄存器SBUF,另一個是接收緩沖寄存器SBUF。如果CPU寫SBUF,數(shù)據(jù)就會被送入發(fā)送寄存器準備發(fā)送;如果CPU讀SBUF,則讀入的數(shù)據(jù)一定來自接收緩沖器。即CPU對SBUF的讀寫,實際上是分別訪問上述兩個不同的寄存器。2)串行控制寄存器SCON

串行控制寄存器SCON用于設(shè)置串行口的工作方式、監(jiān)視串行口的工作狀態(tài)、控制發(fā)送與接收的狀態(tài)等。它是一個既可以字節(jié)尋址又可以位尋址的8位特殊功能寄存器。其格式如圖6-1所示。見表6-1串行口控制寄存器SCONRITIRB8TB8RENSM2SM1SM0SCON98H99H9AH9BH9CH9DH9EH9FH位地址0:雙機1:多機多機通信0:禁止1:允許接收控制發(fā)送數(shù)據(jù)第9位接收數(shù)據(jù)第9位發(fā)送中斷標志接收中斷標志(1)SM0SM1:串行口工作方式選擇位。其狀態(tài)組合所對應的工作方式如表所示。SM0SM1工作方式功能說明000同步移位寄存器輸入/輸出,波特率固定為fosc/1201110位異步收發(fā),波特率可變(T1溢出率/n,n=32或16)10211位異步收發(fā),波特率固定為fOsc/n,n=64或32)11311位異步收發(fā),波特率可變(T1溢出率/n,n=32或16)6-1串行口工作方式(2)SM2:多機通信控制器位。在方式0中,SM2必須設(shè)成0。在方式1中,當處于接收狀態(tài)時,若SM2=1,則只有接收到有效的停止位“1”時,RI才能被激活成“1”(產(chǎn)生中斷請求)。在方式2和方式3中,若SM2=0,串行口以單機發(fā)送或接收方式工作,TI和RI以正常方式被激活并產(chǎn)生中斷請求;若SM2=1,RB8=1時,RI被激活并產(chǎn)生中斷請求。(4)TB8:方式2和方式3中要發(fā)送的第9位數(shù)據(jù)。該位由軟件置位或復位。在方式2和方式3時,TB8是發(fā)送的第9位數(shù)據(jù)。在多機通信中,以TB8位的狀態(tài)表示主機發(fā)送的是地址還是數(shù)據(jù):TB8=1表示地址,TB8=0表示數(shù)據(jù)。TB8還可用作奇偶校驗位。(3)REN:串行接受允許控制位。該位由軟件置位或復位。當REN=1,允許接收;當REN=0,禁止接收。(6)TI:發(fā)送中斷標志位。TI=1,表示已結(jié)束一幀數(shù)據(jù)發(fā)送,可由軟件查詢TI位標志,也可以向CPU申請中斷。注意:TI在任何工作方式下都必須由軟件清0。(5)RB8:接收數(shù)據(jù)第9位。在方式2和方式3時,RB8存放接收到的第9位數(shù)據(jù)。RB8也可用作奇偶校驗位。在方式1中,若SM2=0,則RB8是接收到的停止位。在方式0中,該位未用。(7)RI:接收中斷標志位。RI=1,表示一幀數(shù)據(jù)接收結(jié)束??捎绍浖樵僐I位標志,也可以向CPU申請中斷。

注意:RI在任何工作方式下也都必須由軟件清0。在AT89C51中,串行發(fā)送中斷TI和接收中斷RI的中斷入口地址是同是0023H,因此在中斷程序中必須由軟件查詢TI和RI的狀態(tài)才能確定究竟是接收還是發(fā)送中斷,進而作出相應的處理。單片機復位時,SCON所有位均清0。PCOND7D6D5D4D3D2D1D0位名稱SMOD---GF1GF0PDIDL

SMOD:串行口波特率倍增位。在工作方式1~工作方式3時,若SMOD=1,則串行口波特率增加一倍。若SMOD=0,波特率不加倍。系統(tǒng)復位時,SMOD=0。2.電源控制寄存器PCON2.2串行口工作方式AT89C51串行通信共有4種工作方式,它們分別是方式0、方式1、方式2和方式3,由串行控制寄存器SCON中的SM0SM1決定,如表9-1所示。1.工作方式0

在方式0下,串行口作為同步移位寄存器使用。此時SM2、RB8、TB8均應設(shè)置為0。

(1)發(fā)送:TI=0時,執(zhí)行“SBUF=0xxx”啟動發(fā)送,8位數(shù)據(jù)由低位到高位從RXD引腳送出,TXD發(fā)送同步脈沖。發(fā)送完后,由硬件置位TI。

(2)接收:RI=0,REN=1時啟動接收,數(shù)據(jù)從RXD輸入,TXD輸出同步脈沖。8位數(shù)據(jù)接收完,由硬件置位RI??赏ㄟ^“x=SBUF”讀取數(shù)據(jù)。

方式0的波特率為fosc/12,即一個機器周期發(fā)送或接收一位數(shù)據(jù)。

應當指出:方式0并非是同步通信方式。它的主要用途是外接同步移位寄存器,以擴展并行I/O口。2.工作方式1

方式1是一幀10位的異步串行通信方式,包括1個起始位(0),8個數(shù)據(jù)位和一個停止位(1),其幀格式如下:

起始位0D0D1D2D3D4D5D6D7

停止位1(1)數(shù)據(jù)發(fā)送

當TI=0時,執(zhí)行“SBUF=0xxx”指令后開始發(fā)送,由硬件自動加入起始位和停止位,構(gòu)成一幀數(shù)據(jù),然后由TXD端串行輸出。發(fā)送完后,TXD輸出線維持在“1”狀態(tài)下,并將SCON中的TI置1,表示一幀數(shù)據(jù)發(fā)送完畢。(2)數(shù)據(jù)接收

RI=0,REN=1時,接收電路以波特率的16倍速度采樣RXD引腳,如出現(xiàn)由“1”變“0”跳變,認為有數(shù)據(jù)正在發(fā)送。

在接收到第9位數(shù)據(jù)(即停止位)時,必須同時滿足以下兩個條件:RI=0和SM2=0或接收到的停止位為“1”,才把接收到的數(shù)據(jù)存入SBUF中,停止位送RB8,同時置位RI。若上述條件不滿足,接收到的數(shù)據(jù)不裝入SBUF被舍棄。在方式1下,SM2應設(shè)定為0。(3)波特率波特率=2SMOD×(T1溢出率)/32T1溢出率=1/T1定時時間=(M-T初)·T機1波特率=32·12·(M-T初)2SMOD·fosc3.工作方式2和方式3

工作方式2和方式3都是11位異步收發(fā)串行通信方式,兩者的差異僅在波特率上有所不同。方式2:波特率=2SMOD·fosc/64(SMOD=0或1)方式3:(與方式1相同)波特率=32·12·(M-T初)2SMOD·fosc(1)數(shù)據(jù)發(fā)送

TI=0,發(fā)送數(shù)據(jù)前,先由軟件設(shè)置TB8,可使用如下指令完成:TB8=1

;將TB8位置1TB8=0

;將TB8位置0

然后再向SBUF寫入8位數(shù)據(jù),并以此來啟動串行發(fā)送。一幀數(shù)據(jù)發(fā)送完畢后,CPU自動將TI置1,其過程與方式1相同。(2)數(shù)據(jù)接收

REN=1,RI=0時,啟動接收

①若SM2=0,接收到的8位數(shù)據(jù)送SBUF,第9位數(shù)據(jù)送RB8。②若SM2=1,接收到的第9位數(shù)據(jù)為0,數(shù)據(jù)不送SBUF;接收到的第9位數(shù)據(jù)為1,數(shù)據(jù)送SBUF,第9位送RB8。

對波特率需要說明的是,當串行口工作在方式1或方式3,且要求波特率按規(guī)范取1200、2400、4800、9600…時,若采用晶振12MHz和6MHz,按上述公式算出的T1定時初值將不是一個整數(shù),因此會產(chǎn)生波特率誤差而影響串行通信的同步性能。解決的方法只有調(diào)整單片機的晶振頻率fosc,為此有一種頻率為11.0592MHz的晶振,這樣可使計算出的T1初值為整數(shù)。下表列出了串行方式1或方式3在不同晶振時的常用波特率和誤差。常用波特率和誤差

晶振頻率(MHZ)波特率

(HZ)SMODT1方式2定時初值實際波特率誤差(%)12.0096001F9H8923712.0048000F9H4460712.0024000F3H24040.1612.0012000E6H12020.1611.0592192001FDH19200011.059296000FDH9600011.059248000EAH4800011.059224000F4H2400011.059212000E8H12000【任務實施】利用8位并行輸出串口移位寄存器74LS164擴展16位輸出口的電路。串行口的數(shù)據(jù)通過RXD(P3.0)引腳加到74LS164的輸入端。串行口輸出移位時鐘通過TXD(P3.1)引腳加到74LS164時鐘端,作為同步移位脈沖,其波特率固定為fOSC/12。串行通信方式0應用電路對應的程序如下:

#include<reg51.h>#include<intrins.h>#defineucharunsignedchar#defineuintunsignedint//延時voidDelayMS(uintms){uchari;while(ms--)for(i=0;i<120;i++);}//主程序voidmain(){ucharc=0x80;SCON=0x00;//串口模式0,即移位寄存器輸入/輸出方式

while(1){c=_crol_(c,1);SBUF=c;//TI=0,沒有發(fā)送完

while(TI==0);//等待發(fā)送結(jié)束

TI=0;//TI軟件置位

DelayMS(400);}}【進階提高】通過指撥開關(guān)動作產(chǎn)生高低電平,作為74LS165的輸入,74LS165將接收到的數(shù)據(jù)發(fā)往串口,串口負責接收,串口將接收到的數(shù)據(jù)送P1口顯示。擴展串口串口接收電路對應的程序如下:#include<reg51.h>#include<intrins.h>#include<stdio.h>#defineucharunsignedchar#defineuintunsignedintsbitSPL=P2^5;//shift/load//延時voidDelayMS(uintms){uchari;while(ms--)for(i=0;i<120;i++);}//主程序

voidmain(){SCON=0x10;while(1){SPL=0;SPL=1;while(RI==0);RI=0;P0=SBUF;DelayMS(20);}}任務二單片機雙機通信在銀行業(yè)務系統(tǒng)中,為了提高柜員的登錄安全和授權(quán)操作中的安全性,應用動態(tài)口令系統(tǒng)。通過單片機的雙機通信可模擬動態(tài)密碼的獲取。這里就用到了單片機雙機通信。假設(shè)單片機甲機中存放的動態(tài)口令是010086,甲機發(fā)送動態(tài)口令給單片機乙機,乙機接收到數(shù)據(jù)以后在6個數(shù)碼管上顯示接收數(shù)據(jù)。將兩個獨立的單片機系統(tǒng)用連接線進行連接,使用串行通信進行數(shù)據(jù)傳送。那么單片機如何利用串口實現(xiàn)雙機通信的?【分析任務】本任務要實現(xiàn)雙機通信,需要掌握雙機通信編程要領(lǐng)。通信協(xié)議一般如下:

主機發(fā)送數(shù)據(jù),從機接收數(shù)據(jù),雙方發(fā)送和接收數(shù)據(jù)采用查詢方式;

雙機開始通信,主機發(fā)送握手信號,等待從機應答;

從機接收到握手信號后,應答OK或BUSY;

當從機應答OK后,主機開始向從機發(fā)送緩沖區(qū)里的數(shù)據(jù);從機接收完數(shù)據(jù)后,返回接收成功或失敗,若失敗,主機將重新發(fā)送,從機將重新接收。主機發(fā)送的數(shù)據(jù)格式:字節(jié)數(shù)n,數(shù)據(jù)1,數(shù)據(jù)2......數(shù)據(jù)n,字節(jié)校驗;其中字節(jié)校驗是將字節(jié)數(shù)和所有數(shù)據(jù)進行相異或。【相關(guān)知識】一、串行口雙機或多機通信工作方式單片機串口的初始化要使用單片機的串口,需要對其進行初始化工作。單片機串口初始化需完成單片機串口工作方式選擇、波特率設(shè)置、波特率發(fā)生器設(shè)置等基本的設(shè)置。如設(shè)置單片機晶振頻率為11.0592MHz,串口波特率為9600b/s,串口選擇工作方式1,定時器配置為工作方式2。初始化程序如下:voidUartInit(void){TMOD=(TMOD&0x0f)|0x20;//設(shè)置定時器T1為定時方式2TH1=110592001/12/32/9600;//求波特率為9600時定時器初值TL1=TH1;TR1=1;//啟動T1計數(shù)器SCON=0x70;//設(shè)置串行工作方式1,允許接收PCON=0x80;}【任務實施】#include<reg51.h>#defineucharunsignedchar#defineuintunsignedint#definekey_portP1#definedis_portP2voidmain(void){ ucharkey_in=0xff; SCON=0x50;//MODER1,REN=1; TMOD=0x20;//TIMER1MODER2; TH1=0xf3;//bode=2400 TL1=0xf3; ET1=1; TR1=1; EA=1; ES=1; while(1){ if(key_in!=key_port) { key_in=key_port; SBUF=key_in; } }}voidget_disp(void)interrupt4using0{ if(RI) //如果是串口輸入引起中斷

{dis_port=SBUF; RI=0; } elseTI=0; //否則就是串口輸出引起的中斷}【進階提高】在KeilC51中錄入下面程序,并調(diào)試程序:#include<reg51.h>#defineucharunsignedchar#defineuintunsignedintucharxx=0; //設(shè)計數(shù)標志sbitkey=P1^7; //設(shè)鍵盤ucharbuffer=0;voiddelay(intk) //延時函數(shù){inti;for(i=0;i<k;i++);}//顯示子程序voiddisplay(ucharm){switch(m) { case0:P2=0x3F;break; case1:P2=0x06;break; case2:P2=0x5B;break; case3:P2=0x4F;break; case4:P2=0x66;break; case5:P2=0x6D;break; case6:P2=0x7D;break; case7:P2=0x07;break; case8:P2=0x7F;break; case9:P2=0x6F;break;

case10:P2=0x77;break; case11:P2=0x7C;break; case12:P2=0x39;break; case13:P2=0x5E;break; case14:P2=0x79;break; default:P2=0x71;break; }}voidint_s()interrupt4//串口中斷服務程序{ES=0; //關(guān)串口中斷

if(RI==1){buffer=SBUF; RI=0;//清標志位

display(buffer);}if(TI==1){TI=0; } ES=1;//開串口中斷

return;}voidmain(){display(buffer);//初始化

EA=1; ES=1;SCON=0X50; //工作方式1 TMOD=0X20;//定時器1工作方式2 TH1=0XE6;//1200bps,12Mhz TR1=1; //啟動定時器

while(1){while(key==1) //查詢鍵盤是否松開

{;}if(key==0) //查詢鍵盤是否按下

delay(10); if(key==0) { xx=xx+1; //計數(shù)標志加1 if(xx==16) { xx=0; } SBUF=xx;//發(fā)送數(shù)據(jù)

} while(key==0) //鍵盤是否松開

{;} }}任務三PC與單片機通信【任務描述】比較而言,個人電腦(PC機)具有更強的信息處理能力,經(jīng)常需要將單片機采集到的現(xiàn)場數(shù)據(jù)傳送給PC機集中處理,或者由PC機發(fā)出命令,各終端(單片機)執(zhí)行。本任務要求由PC機發(fā)出不同的數(shù)據(jù),單片機接收后回傳給PC機,從而驗證接收數(shù)據(jù)是否正確?!救蝿辗治觥咳蝿找笸ㄟ^串口工具向單片機發(fā)信息,單片機通過收到信息后將信息回傳給PC機,需要有單片機發(fā)送信息和接收信息兩個方面的編程知識。【相關(guān)知識】單片機可以利用“串口”實現(xiàn)和PC機的通信,這需要了解PC機的一些特性?!癛S-232C標準”是美國EIA(電子工業(yè)聯(lián)合會)與BELL等公司一起開發(fā)并于1969年公布的通信協(xié)議。目前該通信協(xié)議在微機通信接口中廣泛使用,IBMPC機上的COM1、COM2接口就是選用了RS-232接口。RS-232標準包括了按位串行傳輸?shù)碾姎夂蜋C械方面的規(guī)定,使用數(shù)據(jù)終端設(shè)備和數(shù)據(jù)通信設(shè)備之間的接口。1.機械特性。2.功能特性。RS-232c接口的主要引腳功能定義。插針序號

符號

功能

方向2(3)TXD

發(fā)送數(shù)據(jù)

輸出3(2)RXD

接收數(shù)據(jù)

輸入4(7)RTS

請求發(fā)送

輸出5(8)CTS

清除發(fā)送

輸入6(6)DSR數(shù)據(jù)通信設(shè)備準備好

輸入7(5)GND

信號地—8(1)DCD數(shù)據(jù)載體檢測

輸入20(4)DTR

數(shù)據(jù)終端準備好輸出22(9)RI

振鈴指示

輸入3.電氣特性。RS-232C采用“負邏輯”,規(guī)定邏輯0:+3~+15V;邏輯1:—15~-3V。RS-232C標準的信號傳輸?shù)淖畲箅娎|長度為幾十米,傳輸速率小于20KB/s。4.電平轉(zhuǎn)換。鑒于AT89C51單片機的輸入、輸出電平均為TTL/CMOS電平,而計算機配置的是RS-232C標準串行接口,使用的是RS-232C標準電平,二者的電氣規(guī)范不一致,因此要完成PC機與單片機的數(shù)據(jù)通信,必須進行電平轉(zhuǎn)換?!救蝿諏嵤繂纹瑱C與PC通信任務對應的程序代碼如下:#include<reg52.h>#defineucharunsignedchar#defineuintunsignedint#defineN26ucharx;//uchardatatable[N];//暫存數(shù)組,可以將10改為你需要的數(shù)值chartable1[N];uintcnt=0;ucharsendFlag=0;//未發(fā)送數(shù)據(jù)時ucharreceFlag=0;//未接受到數(shù)據(jù)時uinti=0,j;voidserial_init(void){TMOD=0x20;//計時器1作為比特率發(fā)生器,方式2TH1=0xfd;TL1=0xfd;//裝入初值TR1=1;//計時中斷允許SM0=0;SM1=1;//串行口工作于方式2ES=1;//串行口中斷允許PS=1;REN=1;//接收允許EA=1;//總中斷允許}voidmain(){serial_init();//初始化

while(1){P2=table1[0];//顯示數(shù)組的第一個元素

if(receFlag==1){

fasong();

receFlag=0;//發(fā)完了清標志

}}}voidserial()interrupt4{

ES=0;//關(guān)串口中斷

if(RI){

table1[cnt]=SBUF;cnt++;

while(!RI);//等待接收完畢

if(cnt==N){cnt=0;receFlag=1;}

RI=0;//軟件清除接收中斷

}if(TI){TI=0;//發(fā)送完一個數(shù)據(jù)

sendFlag=0;//清標志位

}ES=1;//開串口中斷

}【進階提高】把任務3中接收到的從PC機發(fā)過來的數(shù)據(jù),用數(shù)碼管顯示其ASCII碼,比如發(fā)過來一個‘1’,顯示的是31,發(fā)過來一個字符‘2’,顯示的是32。錄入下面程序,并調(diào)試運行。單片機與PC通信用數(shù)碼管顯示對應的程序代碼如下:#include<reg52.h>#defineucharunsignedchar#defineuintunsignedint#defineN1ucharx;chartable1[N];//暫存數(shù)組uintcnt=0;ucharsendFlag=0;//未發(fā)送數(shù)據(jù)時ucharreceFlag=0;//未接受到數(shù)據(jù)時uinti=0,j;//共陽數(shù)碼管段碼ucharcodedis[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};voiddelayms(ucharms)//延時ms{uchari;while(ms--){for(i=0;i<120;i++);}}voidserial_init(void){TMOD=0x20;//計時器1作為比特率發(fā)生器,方式2TH1=0xfd;TL1=0xfd;//裝入初值TR1=1;//計時中斷允許SM0=0;SM1=1;//串行口工作于方式2ES=1;//串行口中斷允許PS=1;REN=1;//接收允許EA=1;//總中斷允許}voidsend_char(unsignedchartxd)//傳送一個字符{ ES=0;SBUF=txd;while(!TI);//等特數(shù)據(jù)傳送

sendFlag=1; ES=1;//清除數(shù)據(jù)傳送標志}voidfasong(){//發(fā)送數(shù)組receive[];uchari;for(i=0;i<N;i++){send_char(table1[i]);}

}voiddisplay(){P1=0x01;P2=dis[table1[0]&0x0f];delayms(10);//個位顯示P1=0x02;P2=dis[table1[0]/16];delayms(10);//十位顯示}voidmain(){serial_init();//初始化

while(1){display();if(receFlag==1){fasong();receFlag=0;//發(fā)完了清標志

}}}voidserial()interrupt4{

ES=0;//關(guān)串口中斷

if(RI){

table1[cnt]=SBUF;cnt++;while(!RI);//等待接收完畢

if(cnt==N){cnt=0;receFlag=1;}RI=0;//軟件清除接收中斷

}if(TI){TI=0;//發(fā)送完一個數(shù)據(jù)

sendFlag=0;//清標志位

}ES=1;//開串口中斷

}任務四DS18B20溫度采集系統(tǒng)【任務描述】

使用數(shù)字溫度傳感器DS18B20,將采集到的溫度信息送單片機,單片機處理該實時溫度信息后,通過串口送PC串口顯示?!救蝿辗治觥?-wire單總線是Maxim全資子公司Dallas的一項專有技術(shù)。與目前多數(shù)標準串行數(shù)據(jù)通信方式,如SPI/I2C/MICROWIRE不同,它采用單根信號線,既傳輸時鐘,又傳輸數(shù)據(jù),而且數(shù)據(jù)傳輸是雙向的。它具有節(jié)省I/O口線資源、結(jié)構(gòu)簡單、成本低廉、便于總線擴展和維護等諸多優(yōu)點?!鞠嚓P(guān)知識】一、溫度傳感器DS18B20DS18B20對應的程序代碼如下:#include<reg52.h>#include<intrins.h>#define uchar unsignedchar#define uint unsignedint#define u8 unsignedchar#define u16 unsignedint#define u32 unsignedlongint#define uchar32unsignedlongcharunsignedintsdata;//測量到的溫度的整數(shù)部分unsignedcharxiaoshu1;//小數(shù)第一位unsignedcharxiaoshu2;//小數(shù)第二位unsignedcharxiaoshu;//兩位小數(shù)bitfg=1;//溫度正負標志sbitP10=P1^0;sbitP11=P1^1;sbitP12=P1^2;//通信端口使用#define TX_0 P10=0#define TX_1 P10=1//uchar32*p=sort_temp;//=======================================//精確延時函數(shù)//=======================================//延時1us==用于在切換引腳電平時,等待引腳電平穩(wěn)定voiddelay1us(void)//12MHz,12分頻單片機{}//延時7us==讀間隙產(chǎn)生后延時7us,然后單片機讀取引腳電平voiddelay7us(void)//12MHz,12分頻單片機{//調(diào)用占2個周期

_nop_();_nop_(); _nop_();_nop_();_nop_();}//延時15us==拉低500us復位后,18B20在15us后會發(fā)出存在脈沖voiddelay15us(void)//12MHz,12分頻單片機{ //調(diào)用占2個周期

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();}//延時60us==產(chǎn)生寫時序后,延時60us,等待18B20成功讀取引腳電平voiddelay60us(void)//12MHz,12分頻單片機{unsignedchara,b;for(b=11;b>0;b--)for(a=1;a>0;a--);}//延時500us==復位時用到voiddelay500us(void)//12MHz,12分頻單片機{unsignedchara,b;for(b=99;b>0;b--)for(a=1;a>0;a--);}//========================//粗略可調(diào)延時函數(shù)//========================voiddelayms(u16ms){ while(ms--) {unsignedchara,b,c;for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--); }}voiddelay(void)//417us對應2400波特率{unsignedchara;for(a=206;a>0;a--);}//===========================//DS18B20讀一個字節(jié)//===========================u8DS18B20_Read_Byte(void){ u8i; u8byte=0; for(i=0;i<8;i++) { byte>>=1; P11=0; delay1us(); P11=1; //上升沿產(chǎn)生讀時間間隙

delay7us(); //至少7us以后,讀取DS18B20數(shù)據(jù),但也不能過大,例如延時15us就不正常了

if(P11) { byte|=0x80; } delay60us(); P11=1; //釋放總線

} returnbyte;}//===========================//向DS18B20寫一個字節(jié)//===========================voidDS18B20_Write_Byte(u8byte){ u8i=0; for(i=0;i<8;i++) { P11=0; //下降沿產(chǎn)生寫時間間隙

delay1us(); if(byte&0x01) //把數(shù)據(jù)對應位的電平送到DQ引腳

{ P11=1;} else { P11=0;} delay60us(); //延時60us,等待DS18b20讀取引腳電平

byte>>=1; P11=1; //釋放總線

}}//===========================//復位DS18B20//===========================voidDS18B20_RST(void){ P11=1; delay1us(); P11=0;delay500us(); //拉低500us,復位信號

P11=1; //DQ=1 delay15us(); //15us}//=============================//DS18B20存在檢測返回0表示器件存在,1不存在//=============================u8DS18B20_Check(void){ u8revalue=0; u8times=0; while(times<240&&(P11!=0)) //檢測到低電平跳出或者循環(huán)240次跳出

{ times++; delay1us(); } if(times>=240) revalue=1; elsetimes=0; while(times<240&&(P11==0)) //檢測到高電平跳出

{ times++; delay1us(); } if(times<240) revalue=0; else revalue=1;

returnrevalue;}//===========================//讀取DS18B20溫度值//===========================floatDS18B20_Read_Temp(void){ intTEMP_INT; floatTEMP; u8H8,L8; DS18B20_RST(); //復位

DS18B20_Check(); DS18B20_Write_Byte(0xcc); //跳過ROM命令單個傳感器所以不必讀取ROM里的序列號

DS18B20_Write_Byte(0x44); //開始轉(zhuǎn)換

DS18B20_RST(); //復位

DS18B20_Check(); DS18B20_Write_Byte(0xcc); //跳過ROM命令單個傳感器所以不必讀取ROM里的序列號DS18B20_Write_Byte(0xbe); //讀寄存器,共九字節(jié),前兩字節(jié)為轉(zhuǎn)換值

L8=DS18B20_Read_Byte(); //低8位

H8=DS18B20_Read_Byte(); //高8位

if(H8>0x7f)//最高位為1時溫度是負

{L8=~L8;H8=~H8+1;//補碼轉(zhuǎn)換,取反加一

fg=1;//讀取溫度為負時fg=1} xiaoshu1=(L8&0x0f)*10/16;//小數(shù)第一位

xiaoshu2=(L8&0x0f)*100/16%10;//小數(shù)第二位

xiaoshu=xiaoshu1*10+xiaoshu2;//小數(shù)兩位TEMP_INT=(H8<<8)|L8; //將高8位左移8位后與低8位相加【此處按位或相當于相加】 TEMP=TEMP_INT*0.0625; //默認為12位ADC對應的轉(zhuǎn)換精度為0.0625 returnTEMP;}//===========================//DS18B20初始化配置引腳//===========================u8DS18B20_Init(void){ u8revalue='?'; DS18B20_RST(); revalue=DS18B20_Check(); if(revalue==0) { DS18B20_Read_Temp(); } returnrevalue;}voidSendByte(unsignedcharnum){ unsignedchari; TX_0; delay(); //起始位

for(i=0;i<8;i++) { if(num&0x01) //先發(fā)低位

TX_1; else TX_0; num>>=1; delay(); } TX_1; delay(); //停止}voidmain(){floattemp=0; // u8zhengs=0; u8xiaos=0; DS18B20_Init(); delayms(900); while(1) { temp=DS18B20_Read_Temp(); zhengs=temp; delayms(100); SendByte('T'); SendByte(':'); SendByte(zhengs/10%10+'0');

SendByte(zhengs%10+'0'); SendByte('.'); SendByte(xiaoshu1+'0'); SendByte(xiaoshu2+'0'); SendByte(10); //換行

SendByte(13); //回車

}}【進階提高】將DS18B20采集到的信息上傳給PC,先來實現(xiàn)串口助手發(fā)來的信息發(fā)送給單片機,然后保存于一數(shù)組里,然后將數(shù)組里面的東西發(fā)送給PC端,一發(fā)一收來檢查數(shù)據(jù)的正確性.sbitrw=P0^6;//1602的讀寫控制線sbiten=P0^7;//1602的使能控制線sbitP11=P1^1;sbitP12=P1^2;//通信端口使用//uchar32*p=sort_temp;//=======================================//精確延時函數(shù)//=======================================//延時1us==用于在切換引腳電平時,等待引腳電平穩(wěn)定voiddelay1us(void)//12MHz,12分頻單片機{}//延時7us==讀間隙產(chǎn)生后延時7us,然后單片機讀取引腳電平voiddelay7us(void)//12MHz,12分頻單片機{

//調(diào)用占2個周期

_nop_();_nop_(); _nop_();_nop_();_nop_();}//延時15us==拉低500us復位后,18B20在15us后會發(fā)出存在脈沖voiddelay15us(void)//12MHz,12分頻單片機{ //調(diào)用占2個周期

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();}//延時60us==產(chǎn)生寫時序后,延時60us,等待18B20成功讀取引腳電平voiddelay60us(void)//12MHz,12分頻單片機{unsignedchara,b;for(b=11;b>0;b--)for(a=1;a>0;a--);}//延時500us==復位時用到voiddelay500us(void)//12MHz,12分頻單片機{unsignedchara,b;for(b=99;b>0;b--)for(a=1;a>0;a--);}//========================//粗略可調(diào)延時函數(shù)//========================voiddelayms(u16ms){ while(ms--) {unsignedchara,b,c;for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--); }}voiddelay(uintn)//延時函數(shù){uintx,y;for(x=n;x>0;x--)for(y=110;y>0;y--);}//===========================//DS18B20讀一個字節(jié)//===========================u8DS18B20_Read_Byte(void){ u8i; u8byte=0; for(i=0;i<8;i++) { byte>>=1; P11=0; delay1us(); P11=1; //上升沿產(chǎn)生讀時間間隙

delay7us(); //至少7us以后,讀取DS18B20數(shù)據(jù),但也不能過大,例如延時15us就不正常了

if(P11) { byte|=0x80; } delay60us(); P11=1; //釋放總線

} returnbyte;}//===========================//向DS18B20寫一個字節(jié)//===========================voidDS18B20_Write_Byte(u8byte){ u8i=0; for(i=0;i<8;i++) { P11=0; //下降沿產(chǎn)生寫時間間隙

delay1us(); if(byte&0x01) //把數(shù)據(jù)對應位的電平送到DQ引腳

{ P11=1;} else { P11=0;} delay60us(); //延時60us,等待DS18b20讀取引腳電平

byte>>=1; P11=1; //釋放總線

}}//=============================//DS18B20存在檢測返回0表示器件存在,1不存在//=============================u8DS18B20_Check(void){ u8revalue=0; u8times=0; while(times<240&&(P11!=0)) //檢測到低電平跳出或者循環(huán)240次跳出

{ times++; delay1us(); }

if(times>=240) revalue=1; else times=0; while(times<240&&(P11==0)) //檢測到高電平跳出

{ times++; delay1us(); }if(times<240) revalue=0; else revalue=1;

returnrevalue;}//===========================//讀取DS18B20溫度值//===========================floatDS18B20_Read_Temp(void){ intTEMP_INT; floatTEMP; u8H8,L8; DS18B20_RST(); //復位

DS18B20_Check();

DS18B20_Write_Byte(0xcc); //跳過ROM命令單個傳感器所以不必讀取ROM里的序列號

DS18B20_Write_Byte(0x44); //開始轉(zhuǎn)換

DS18B20_RST(); //復位

DS18B20_Check(); DS18B20_Write_Byte(0xcc); //跳過ROM命令單個傳感器所以不必讀取ROM里的序列號DS18B20_Write_Byte(0xbe); //讀寄存器,共九字節(jié),前兩字節(jié)為轉(zhuǎn)換值

L8=DS18B20_Read_Byte(); //低8位

H8=DS18B20_Read_Byte(); //高8位

TEMP_INT=(H8<<8)|L8; //將高8位左移8位后與低8位相加【此處按位或相當于相加】 TEMP=TEMP_INT*0.0625; //默認為12位ADC對應的轉(zhuǎn)換精度為0.0625 returnTEMP;}//液晶開始/*********************************************************************************/ voidlcd_wcom(ucharcom)//1602寫命令函數(shù)(單片機給1602寫命令){//1602接收到命令后,不用存儲,直接由HD44780執(zhí)行并產(chǎn)生相應動作

rs=0;//選擇指令寄存器

rw=0;//選擇寫

P2=com;//把命令字送入P2delay(5);//延時一小會兒,讓1602準備接收數(shù)據(jù)

en=1;//使能線電平變化,命令送入1602的8位數(shù)據(jù)口

en=0;}voidlcd_wdat(uchardat)//1602寫數(shù)據(jù)函數(shù){rs=1;//選擇數(shù)據(jù)寄存器

rw=0;//選擇寫

P2=dat;//把要顯示的數(shù)據(jù)送入P2delay(5);//延時一小會兒,讓1602準備接收數(shù)據(jù)

en=1;//使能線電平變化,數(shù)據(jù)送入1602的8位數(shù)據(jù)口

en=0;}voidlcd_init()

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論