計數器與定時器2_第1頁
計數器與定時器2_第2頁
計數器與定時器2_第3頁
計數器與定時器2_第4頁
計數器與定時器2_第5頁
已閱讀5頁,還剩32頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、計數器與定時器一、計數概念的引入從選票的統(tǒng)計談起:畫“正”。這就是計數,生活中計數的例子處處可見。例:錄音機上的計數器、家里面用的電度表、汽車上的里程表等等,再舉一個工業(yè)生產中的例子,線纜行業(yè)在電線生產出來之后要計米,也就是測量長度,怎么測法呢?用尺量?不現實,太長不說,要一邊做一邊量呢,怎么辦呢?行業(yè)中有很巧妙的方法,用一個周長是1米的輪子,將電纜繞在上面一周,由線帶輪轉,這樣輪轉一周不就是線長1米嘛,所以只要記下輪轉了多少圈,就可以知道走過的線有多長了。二、計數器的容量從一個生活中的例子看起:一個水盆在水龍頭下,水龍沒關緊,水一滴滴地滴入盆中。水滴不斷落下,盆的容量是有限的,過一段時間之后

2、,水就會逐漸變滿。錄音機上的計數器最多只計到999.那么單片機中的計數器有多大的容量呢?8031單片機中有兩個計數器,分別稱之為T0和T1,這兩個計數器分別是由兩個8位的RAM單元組成的,即每個計數器都是16位的計數器,最大的計數量是65536。三、定時8031中的計數器除了可以作為計數之用外,還可以用作時鐘,時鐘的用途當然很大,如打鈴器,電視機定時關機,空調定時開關等等,那么計數器是如何作為定時器來用的呢?一個鬧鐘,我將它定時在1個小時后鬧響,換言之,也可以說是秒針走了(3600)次,所以時間就轉化為秒針走的次數的,也就是計數的次數了,可見,計數的次數和時間之間的確十分相關。那么它們的關系是

3、什么呢?那就是秒針每一次走動的時間正好是1秒。圖1結論:只要計數脈沖的間隔相等,則計數值就代表了時間的流逝。由此,單片機中的定時器和計數器是一個東西,只不過計數器是記錄的外界發(fā)生的事情,而定時器則是由單片機提供一個非常穩(wěn)定的計數源。那么提供組定時器的是計數源是什么呢?看圖1,原來就是由單片機的晶振經過12分頻后獲得的一個脈沖源。晶振的頻率當然很準,所以這個計數脈沖的時間間隔也很準。問題:一個12M的晶振,它提供給計數器的脈沖時間間隔是多少呢?當然這很容易,就是12M/12等于1M,也就是1個微秒。結論:計數脈沖的間隔與晶振有關,12M的晶振,計數脈沖的間隔是1微秒。四、溢出讓我們再來看水滴的例

4、子,當水不斷落下,盆中的水不斷變滿,最終有一滴水使得盆中的水滿了。這時如果再有一滴水落下,就會發(fā)生什么現象?水會漫出來,用個術語來講就是“溢出”。 水溢出是流到地上,而計數器溢出后將使得TF0變?yōu)椤?”。至于TF0是什么我們稍后再談。一旦TF0由0變成1,就是產生了變化,產生了變化就會引發(fā)事件,就象定時的時間一到,鬧鐘就會響一樣。至于會引發(fā)什么事件,我們下次課再介紹,現在我們來研究另一個問題:要有多少個計數脈沖才會使TF0由0變?yōu)?。五、任意定時及計數的方法剛才已研究過,計數器的容量是16位,也就是最大的計數值到65536,因此計數計到65536就會產生溢出。這個沒有問題,問題是我們現實生活中

5、,經常會有少于65536個計數值的要求,如包裝線上,一打為12瓶,一瓶藥片為100粒,怎么樣來滿足這個要求呢?提示:如果是一個空的盆要1萬滴水滴進去才會滿,我在開始滴水之前就先放入一勺水,還需要10000滴嘛?對了,我們采用預置數的方法,我要計100,那我就先放進65436,再來100個脈沖,不就到了65536了嗎。定時也是如此,每個脈沖是1微秒,則計滿65536個脈沖需時65.536毫秒,但現在我只要10毫秒就可以了,怎么辦?10個毫秒為10000個微秒,所以,只要在計數器里面放進55536就可以了。說明:本課部份圖請打本單片機書,都有,抱歉,不及畫。定時/計數器的方式控制字從上一節(jié)我們已經

6、得知,單片機中的定時/計數器都可以有多種用途,那么我怎樣才能讓它們工作于我所需要的用途呢?這就要通過定時/計數器的方式控制字來設置。在單片機中有兩個特殊功能寄存器與定時/計數有關,這就是TMOD和TCON。順便說一下,TMOD和TCON是名稱,我們在寫程序時就可以直接用這個名稱來指定它們,當然也可以直接用它們的地址89H和88H來指定它們(其實用名稱也就是直接用地址,匯編軟件幫你翻譯一下而已)。從圖1中我們可以看出,TMOD被分成兩部份,每部份4位。分別用于控制T1和T0,至于這里面是什么意思,我們下面介紹。從圖2中我們可以看出,TCON也被分成兩部份,高4位用于定時/計數器,低4位則用于中斷

7、(我們暫不管)。而TF1(0)我們上節(jié)課已提到了,當計數溢出后TF1(0)就由0變?yōu)?。原來TF1(0)在這兒!那么TR0、TR1又是什么呢?看上節(jié)課的圖。計數脈沖要進入計數器還真不容易,有層層關要通過,最起碼,就是TR0(1)要為1,開關才能合上,脈沖才能過來。因此,TR0(1)稱之為運行控制位,可用指令SETB來置位以啟動計數器/定時器運行,用指令CLR來關閉定時/計數器的工作,一切盡在自已的掌握中。定時/計數器的四種工作方式1. 工作方式0 定時器/計數器的工作方式0稱之為13位定時/計數方式。它由TL(1/0)的低5位和TH(0/1)的8位構成13位的計數器,此時TL(1/0)的高3位

8、未用。我們用這個圖來討論幾個問題:1. M1M0:定時/計數器一共有四種工作方式,就是用M1M0來控制的,2位正好是四種組合。 2. C/T:前面我們說過,定時/計數器即可作定時用也可用計數用,到底作什么用,由我們根據需要自行決定,也說是決定權在我們��編程者。如果C/T為0就是用作定時器(開關往上打),如果C/T為1就是用作計數器(開關往下打)。順便提一下:一個定時/計數器同一時刻要么作定時用,要么作計數用,不能同時用的,這是個極普通的常識,幾乎沒有教材會提這一點,但很多初學者卻會有此困惑。 3. GATE:看圖,當我們選擇了定時或計數工作方式后,定時/計數脈沖卻不一定能到達計數

9、器端,中間還有一個開關,顯然這個開關不合上,計數脈沖就沒法過去,那么開關什么時候過去呢?有兩種情況 1. GATE=0,分析一下邏輯,GATE非后是1,進入或門,或門總是輸出1,和或門的另一個輸入端INT1無關,在這種情況下,開關的打開、合上只取決于TR1,只要TR1是1,開關就合上,計數脈沖得以暢通無阻,而如果TR1等于0則開關打開,計數脈沖無法通過,因此定時/計數是否工作,只取決于TR1。 2. GATE=1,在此種情況下,計數脈沖通路上的開關不僅要由TR1來控制,而且還要受到INT1引腳的控制,只有TR1為1,且INT1引腳也是高電平,開關才合上,計數脈沖才得以通過。這個特性可以用來測量

10、一個信號的高電平的寬度,想想看,怎么測? 為什 么在這種模式下只用13位呢?干嗎不用16位,這是為了和51機的前輩48系列兼容而設的一種工作式,如果你覺得用得不順手,那就干脆用第二種工作方式。1. 工作方式1 工作方式1是16位的定時/計數方式,將M1M0設為01即可,其它特性與工作方式0相同。2. 工作方式2 在介紹這種式方式之前先讓我們思考一個問題:上一次課我們提到過任意計數及任意定時的問題,比如我要計1000個數,可是16位的計數器要計到65536才滿,怎么辦呢?我們討論后得出的辦法是用預置數,先在計數器里放上64536,再來1000個脈沖,不就行了嗎?是的,但是計滿了之后我們又該怎么辦

11、呢?要知道,計數總是不斷重復的,流水線上計滿后馬上又要開始下一次計數,下一次的計數還是1000嗎?當計滿并溢出后,計數器里面的值變成了0(為什么,可以參考前面課程的說明),因此下一次將要計滿65536后才會溢出,這可不符合要求,怎么辦?當然辦法很簡單,就是每次一溢出時執(zhí)行一段程序(這通常是需要的,要不然要溢出干嗎?)可以在這段程序中做把預置數64536送入計數器中的事情。所以采用工作方式0或1都要在溢出后做一個重置預置數的工作,做工作當然就得要時間,一般來說這點時間不算什么,可是有一些場合我們還是要計較的,所以就有了第三種工作方式��自動再裝入預置數的工作方式。既然要自動得新裝入預

12、置數,那么預置數就得放在一個地方,要不然裝什么呢?那么預置數放在什么地方呢?它放在T(0/1)的高8位,那么這樣高8位不就不能參與計數了嗎?是的,在工作方式2,只有低8位參與計數,而高8位不參與計數,用作預置數的存放,這樣計數范圍就小多了,當然做任可事總有代價的,關鍵是看值不值,如果我根本不需要計那么多數,那么就可以用這種方式??磮D4,每當計數溢出,就會打開T(0/1)的高、低8位之間的開關,計預置數進入低8位。這是由硬件自動完成的,不需要由人工干預。通常這種式作方式用于波特率發(fā)生器(我們將在串行接口中講解),用于這種用途時,定時器就是為了提供一個時間基準。計數溢出后不需要做事情,要做的僅僅只

13、有一件,就是重新裝入預置數,再開始計數,而且中間不要任何延遲,可見這個任務用工作方式2來完成是最妙不過了。3. 工作方式3 這種式作方式之下,定時/計數器0被拆成2個獨立的定時/計數器來用。其中,TL0可以構成8位的定時器或計數器的工作方式,而TH0則只能作為定時器來用。我們知道作定時、計數器來用,需要控制,計滿后溢出需要有溢出標記,T0被分成兩個來用,那就要兩套控制及、溢出標記了,從何而來呢?TL0還是用原來的T0的標記,而TH0則借用T1的標記。如此T1不是無標記、控制可用了嗎?是的。一般情況處,只有在T1以工作方式2運行(當波特率發(fā)生器用)時,才讓T0工作于方式3的。定時器/計數器的定時

14、/計數范圍工作方式0:13位定時/計數方式,因此,最多可以計到2的13次方,也就是8192次。工作方式1:16位定時/計數方式,因此,最多可以計到2的16次方,也就是65536次。工作方式2和工作方式3,都是8位的定時/計數方式,因此,最多可以計到2的8次方,也說是256次。預置值計算:用最大計數量減去需要的計數次數即可。例:流水線上一個包裝是12盒,要求每到12盒就產生一個動作,用單片機的工作方式0來控制,應當預置多大的值呢?對了,就是8192-12=8180。以上是計數,明白了這個道理,定時也是一樣。這在前面的課程已提到,我們不再重復,請參考前面的例子。 單片機第二十課:中斷系統(tǒng)1. 有關

15、中斷的概念 什么是中斷,我們從一個生活中的例子引入。你正在家中看書,突然電話鈴響了,你放下書本,去接電話,和來電話的人交談,然后放下電話,回來繼續(xù)看你的書。這就是生活中的“中斷”的現象,就是正常的工作過程被外部的事件打斷了。仔細研究一下生活中的中斷,對于我們學習單片機的中斷也很有好處。第一、什么可經引起中斷,生活中很多事件可以引起中斷:有人按了門鈴了,電話鈴響了,你的鬧鐘鬧響了,你燒的水開了.等等諸如此類的事件,我們把可以引起中斷的稱之為中斷源,單片機中也有一些可以引起中斷的事件,8031中一共有5個:兩個外部中斷,兩個計數/定時器中斷,一個串行口中斷。第二、中斷的嵌套與優(yōu)先級處理:設想一下,

16、我們正在看書,電話鈴響了,同時又有人按了門鈴,你該先做那樣呢?如果你正是在等一個很重要的電話,你一般不會去理會門鈴的,而反之,你正在等一個重要的客人,則可能就不會去理會電話了。如果不是這兩者(即不等電話,也不是等人上門),你可能會按你通常的習慣去處理??傊@里存在一個優(yōu)先級的問題,單片機中也是如此,也有優(yōu)先級的問題。優(yōu)先級的問題不僅僅發(fā)生在兩個中斷同時產生的情況,也發(fā)生在一個中斷已產生,又有一個中斷產生的情況,比如你正接電話,有人按門鈴的情況,或你正開門與人交談,又有電話響了情況。考慮一下我們會怎么辦吧。第三、中斷的響應過程:當有事件產生,進入中斷之前我們必須先記住現在看書的第幾頁了,或拿一個

17、書簽放在當前頁的位置,然后去處理不同的事情(因為處理完了,我們還要回來繼續(xù)看書):電話鈴響我們要到放電話的地方去,門鈴響我們要到門那邊去,也說是不同的中斷,我們要在不同的地點處理,而這個地點通常還是固定的。計算機中也是采用的這種方法,五個中斷源,每個中斷產生后都到一個固定的地方去找處理這個中斷的程序,當然在去之前首先要保存下面將執(zhí)行的指令的地址,以便處理完中斷后回到原來的地方繼續(xù)往下執(zhí)行程序。具體地說,中斷響應可以分為以下幾個步驟:1、保護斷點,即保存下一將要執(zhí)行的指令的地址,就是把這個地址送入堆棧。2、尋找中斷入口,根據5個不同的中斷源所產生的中斷,查找5個不同的入口地址。以上工作是由計算機

18、自動完成的,與編程者無關。在這5個入口地址處存放有中斷處理程序(這是程序編寫時放在那兒的,如果沒把中斷程序放在那兒,就錯了,中斷程序就不能被執(zhí)行到)。3、執(zhí)行中斷處理程序。4、中斷返回:執(zhí)行完中斷指令后,就從中斷處返回到主程序,繼續(xù)執(zhí)行。究竟單片機是怎么樣找到中斷程序所在位置,又怎么返回的呢?我們稍后再談。2. MCS-51中斷系統(tǒng)的結構: 如圖(抱歉,本圖請找本51書看一下)所示,由與中斷有關的特殊功能寄存器、中斷入口、順序查詢邏輯電路等組成,包括5個中斷請求源,4個用于中斷控制的寄存器IE、IP、ECON和SCON來控制中斷 類弄、中斷的開、關和各種中斷源的優(yōu)先級確定。1. 中斷請求源:

19、(1)外部中斷請求源:即外中斷0和1,經由外部引腳引入的,在單片機上有兩個引腳,名稱為INT0、INT1,也就是P3.2、P3.3這兩個引腳。在內部的TCON中有四位是與外中斷有關的。IT0:INT0觸發(fā)方式控制位,可由軟件進和置位和復位,IT0=0,INT0為低電平觸發(fā)方式,IT0=1,INT0為負跳變觸發(fā)方式。這兩種方式的差異將在以后再談。IE0:INT0中斷請求標志位。當有外部的中斷請求時,這位就會置1(這由硬件來完成),在CPU響應中斷后,由硬件將IE0清0。IT1、IE1的用途和IT0、IE0相同。(2)內部中斷請求源TF0:定時器T0的溢出中斷標記,當T0計數產生溢出時,由硬件置位

20、TF0。當CPU響應中斷后,再由硬件將TF0清0。TF1:與TF0類似。TI、RI:串行口發(fā)送、接收中斷,在串口中再講解。2、中斷允許寄存器IE在MCS51中斷系統(tǒng)中,中斷的允許或禁止是由片內可進行位尋址的8位中斷允許寄存器IE來控制的。見下表EAXXESET1EX1ET0EX0其中EA是總開關,如果它等于0,則所有中斷都不允許。ES串行口中斷允許ET1定時器1中斷允許EX1外中斷1中斷允許。ET0定時器0中斷允許EX0外中斷0中斷允許。如果我們要設置允許外中斷1,定時器1中斷允許,其它不允許,則IE可以是EAXXESET1EX1ET0EX010001100即8CH,當然,我們也可以用位操作指

21、令SETB EASETB ET1SETB EX1來實現它。3、五個中斷源的自然優(yōu)先級與中斷服務入口地址外中斷0:0003H定時器0:000BH外中斷1:0013H定時器1:001BH串口 :0023H它們的自然優(yōu)先級由高到低排列。寫到這里,大家應當明白,為什么前面有一些程序一始我們這樣寫:ORG 0000HLJMP STARTORG 0030HSTART:。這樣寫的目的,就是為了讓出中斷源所占用的向量地址。當然,在程序中沒用中斷時,直接從0000H開始寫程序,在原理上并沒有錯,但在實際工作中最好不這樣做。優(yōu)先級:單片機采用了自然優(yōu)先級和人工設置高、低優(yōu)先級的策略,即可以由程序員設定那些中斷是高

22、優(yōu)先級、哪些中斷是低優(yōu)先級,由于只有兩級,必有一些中斷處于同一級別,處于同一級別的,就由自然優(yōu)先級確定。開機時,每個中斷都處于低優(yōu)先級,我們可以用指令對優(yōu)先級進行設置??幢?中斷優(yōu)先級中由中斷優(yōu)先級寄存器IP來高置的,IP中某位設為1,相應的中斷就是高優(yōu)先級,否則就是低優(yōu)先級。XXXPSPT1PX1PT0PX0例:設有如下要求,將T0、外中斷1設為高優(yōu)先級,其它為低優(yōu)先級,求IP的值。IP的首3位沒用,可任意取值,設為000,后面根據要求寫就可以了XXXPSPT1PX1PT0PX000000110因此,最終,IP的值就是06H。例:在上例中,如果5個中斷請求同時發(fā)生,求中斷響應的次序。響應次序

23、為:定時器0外中斷1外中斷0實時器1串行中斷。1. MCS51的中斷響應過程: 1、中斷響應的條件:講到這兒,我們依然對于計算機響應中斷感到神奇,我們人可以響應外界的事件,是因為我們有多種“傳感器“眼、耳可以接受不同的信息,計算機是如何做到這點的呢?其實說穿了,一點都不希奇,MCS51工作時,在每個機器周期中都會去查詢一下各個中斷標記,看他們是否是“1“,如果是1,就說明有中斷請求了,所以所謂中斷,其實也是查詢,不過是每個周期都查一下而已。這要換成人來說,就相當于你在看書的時候,每一秒鐘都會抬起頭來看一看,查問一下,是不是有人按門鈴,是否有電話。很蠢,不是嗎?可計算機本來就是這樣,它根本沒人聰

24、明。了解了上述中斷的過程,就不難解中斷響應的條件了。在下列三種情況之一時,CPU將封鎖對中斷的響應:1. CPU正在處理一個同級或更高級別的中斷請求。 2. 現行的機器周期不是當前正執(zhí)行指令的最后一個周期。我們知道,單片機有單周期、雙周期、三周期指令,當前執(zhí)行指令是單字節(jié)沒有關系,如果是雙字節(jié)或四字節(jié)的,就要等整條指令都執(zhí)行完了,才能響應中斷(因為中斷查詢是在每個機器周期都可能查到的)。 3. 當前正執(zhí)行的指令是返回批令(RETI)或訪問IP、IE寄存器的指令,則CPU至少再執(zhí)行一條指令才應中斷。這些都是與中斷有關的,如果正訪問IP、IE則可能會開、關中斷或改變中斷的優(yōu)先級,而中斷返回指令則說

25、明本次中斷還沒有處理完,所以都要等本指令處理結束,再執(zhí)行一條指令才可以響應中斷。 2、中斷響應過程CPU響應中斷時,首先把當前指令的下一條指令(就是中斷返回后將要執(zhí)行的指令)的地址送入堆棧,然后根據中斷標記,將相應的中斷入口地址送入PC,PC是程序指針,CPU取指令就根據PC中的值,PC中是什么值,就會到什么地方去取指令,所以程序就會轉到中斷入口處繼續(xù)執(zhí)行。這些工作都是由硬件來完成的,不必我們去考慮。這里還有個問題,大家是否注意到,每個中斷向量地址只間隔了8個單元,如0003000B,在如此少的空間中如何完成中斷程序呢?很簡單,你在中斷處安排一個LJMP指令,不就可以把中斷程序跳轉到任何地方了

26、嗎?一個完整的主程序看起來應該是這樣的:ORG 0000HLJMP STARTORG 0003HLJMP INT0 ;轉外中斷0ORG 000BHRETI ;沒有用定時器0中斷,在此放一條RETI,萬一 “不小心“產生了中斷,也不會有太大的后果。中斷程序完成后,一定要執(zhí)行一條RETI指令,執(zhí)行這條指令后,CPU將會把堆棧中保存著的地址取出,送回PC,那么程序就會從主程序的中斷處繼續(xù)往下執(zhí)行了。注意:CPU所做的保護工作是很有限的,只保護了一個地址,而其它的所有東西都不保護,所以如果你在主程序中用到了如A、PSW等,在中斷程序中又要用它們,還要保證回到主程序后這里面的數據還是沒執(zhí)行中斷以前的數據

27、,就得自己保護起來。定時、中斷練習一1、利用定時器實現燈的閃爍在學單片機時我們第一個例子就是燈的閃爍,那是用延時程序做的,現在回想起來,這樣做不很恰當,為什么呢?我們的主程序做了燈的閃爍,就不能再干其它的事了,難道單片機只能這樣工作嗎?當然不是,我們可以用定時器來實現燈的閃爍的功能。例1:查詢方式ORG 0000HAJMP STARTORG 30HSTART:MOV P1,#0FFH ;關所 燈MOV TMOD,#00000001B ;定時/計數器0工作于方式1MOV TH0,#15H MOV TL0,#0A0H ;即數5536SETB TR0 ;定時/計數器0開始運行LOOP:JBC TF0

28、,NEXT ;如果TF0等于1,則清TF0并轉NEXT處AJMP LOOP ;否則跳轉到LOOP處運行NEXT:CPL P1.0MOV TH0,#15HMOV TL0,#9FH;重置定時/計數器的初值AJMP LOOPEND AJMP LOOPEND鍵入程序,看到了什么?燈在閃爍了,這可是用定時器做的,不再是主程序的循環(huán)了。簡單地分析一下程序,為什么用JBC呢?TF0是定時/計數器0的溢出標記位,當定時器產生溢出后,該位由0變1,所以查詢該位就可知宇時時間是否已到。該位為1后,要用軟件將標記位清0,以便下一次定時是間到時該位由0變1,所以用了JBC指令,該指位在判1轉移的同時,還將該位清0。以

29、上程序是可以實現燈的閃爍了,可是主程序除了讓燈閃爍外,還是不能做其他的事?。〔?,不對,我們可以在LOOP:和AJMP LOOP指令之間插入一些指令來做其他的事情,只要保證執(zhí)行這些指令的時間少于定時時間就行了。那我們在用軟件延時程序的時候不是也可以用一些指令來替代DJNZ嗎?是的,但是那就要求你精確計算所用指令的時間,然后再減去相應的DJNZ循環(huán)次數,很不方便,而現在只要求所用指令的時間少于定時時間就行,顯然要求低了。當然,這樣的方法還是不好,所以我們常用以下的方法來實現。程序2:用中斷實現ORG 0000HAJMP STARTORG 000BH ;定時器0的中斷向量地址AJMP TIME0 ;

30、跳轉到真正的定時器程序處ORG 30HSTART:MOV P1,#0FFH ;關所 燈MOV TMOD,#00000001B ;定時/計數器0工作于方式1MOV TH0,#15H MOV TL0,#0A0H ;即數5536SETB EA ;開總中斷允許SETB ET0 ;開定時/計數器0允許SETB TR0 ;定時/計數器0開始運行LOOP: AJMP LOOP ;真正工作時,這里可寫任意程序TIME0: ;定時器0的中斷處理程序PUSH ACCPUSH PSW ;將PSW和ACC推入堆棧保護CPL P1.0 MOV TH0,#15HMOV TL0,#0A0H ;重置定時常數POP PSWPO

31、P ACCRETIEND上面的例子中,定時時間一到,TF0由0變1,就會引發(fā)中斷,CPU將自動轉至000B處尋找程序并執(zhí)行,由于留給定時器中斷的空間只有8個字節(jié),顯然不足以寫下所有有中斷處理程序,所以在000B處安排一條跳轉指令,轉到實際處理中斷的程序處,這樣,中斷程序可以寫在任意地方,也可以寫任意長度了。進入定時中斷后,首先要保存當前的一些狀態(tài),程序中只演示了保存存ACC和PSW,實際工作中應該根據需要將可能會改變的單元的值都推入堆棧進行保護(本程序中實際不需保存護任何值,這里只作個演示)。上面的兩個程序運行后,我們發(fā)現燈的閃爍非??欤痉直娌怀鰜?,只是視覺上感到燈有些晃動而已,為什么呢?

32、我們可以計算一下,定時器中預置的數是5536,所以每計60000個脈沖就是定時時間到,這60000個脈沖的時間是多少呢?我們的晶振是12M,所以就是60000微秒,即60毫秒,因此速度是非??斓摹H绻蚁雽崿F一個1S的定時,該怎么辦呢?在該晶振瀕率下,最長的定時也就是65。536個毫秒??!上面給出一個例子。ORG 0000HAJMP STARTORG 000BH ;定時器0的中斷向量地址AJMP TIME0 ;跳轉到真正的定時器程序處ORG 30HSTART:MOV P1,#0FFH ;關所 燈MOV 30H,#00H ;軟件計數器預清0MOV TMOD,#00000001B ;定時/計數器0

33、工作于方式1MOV TH0,#3CH MOV TL0,#0B0H ;即數15536SETB EA ;開總中斷允許SETB ET0 ;開定時/計數器0允許SETB TR0 ;定時/計數器0開始運行LOOP: AJMP LOOP ;真正工作時,這里可寫任意程序TIME0: ;定時器0的中斷處理程序PUSH ACCPUSH PSW ;將PSW和ACC推入堆棧保護INC 30HMOV A,30HCJNE A,#20,T_RET ;30H單元中的值到了20了嗎?T_L1: CPL P1.0 ;到了,取反P10MOV 30H,#0 ;清軟件計數器T_RET:MOV TH0,#15HMOV TL0,#9FH

34、 ;重置定時常數POP PSWPOP ACCRETIEND先自己分析一下,看看是怎么實現的?這里采用了軟件計數器的概念,思路是這樣的,先用定時/計數器0做一個50毫秒的定時器,定時是間到了以后并不是立即取反P10,而是將軟件計數器中的值加1,如果軟件計數器計到了20,就取反P10,并清掉軟件計數器中的值,否則直接返回,這樣,就變成了20次定時中斷才取反一次P10,因此定時時間就延長了成了20*50即1000毫秒了。這個思路在工程中是非常有用的,有的時候我們需要若干個定時器,可51中總共才有2個,怎么辦呢?其實,只要這幾個定時的時間有一定的公約數,我們就可以用軟件定時器加以實現,如我要實現P10

35、口所接燈按1S每次,而P11口所接燈按2S每次閃爍,怎么實現呢?對了我們用兩個計數器,一個在它計到20時,取反P10,并清零,就如上面所示,另一個計到40取反P11,然后清0,不就行了嗎?這部份的程序如下ORG 0000HAJMP STARTORG 000BH ;定時器0的中斷向量地址AJMP TIME0 ;跳轉到真正的定時器程序處ORG 30HSTART:MOV P1,#0FFH ;關所 燈MOV 30H,#00H ;軟件計數器預清0MOV TMOD,#00000001B ;定時/計數器0工作于方式1MOV TH0,#3CH MOV TL0,#0B0H ;即數15536SETB EA ;開總

36、中斷允許SETB ET0 ;開定時/計數器0允許SETB TR0 ;定時/計數器0開始運行LOOP: AJMP LOOP ;真正工作時,這里可寫任意程序TIME0: ;定時器0的中斷處理程序PUSH ACCPUSH PSW ;將PSW和ACC推入堆棧保護INC 30HINC 31H ;兩個計數器都加1MOV A,30HCJNE A,#20,T_NEXT ;30H單元中的值到了20了嗎?T_L1: CPL P1.0 ;到了,取反P10MOV 30H,#0 ;清軟件計數器T_NEXT:MOV A,31HCJNE A,#40,T_RET ;31h單元中的值到40了嗎?T_L2:CPL P1.1MOV

37、 31H,#0 ;到了,取反P11,清計數器,返回T_RET:MOV TH0,#15HMOV TL0,#9FH ;重置定時常數POP PSWPOP ACCRETIEND程序一下載 代碼下載 程序二下載 代碼下載 程序三下載 代碼下載 程序四下載 代碼下載您能用定時器的方法實現前面講的流水燈嗎?試試看。定時/計數器實驗2前面我們做了定時器的實驗,現在來看一看計數實驗,在工作中計數通常會有兩種要求:第一、將計數的值顯示出來,第二、計數值到一定程度即中斷報警。第一種如各種計數器、里程表,第二種如前面例中講到的生產線上的計數。先看第一種吧。我們的硬件中是這樣連線的:324構成的振蕩器連到定時/計數器1

38、的外部引腳T1上面,我們就利用這個來做一個計數實驗,要將計數的值顯示出來,當然最好用數碼管了,可我們還沒講到這一部份,為了避免把問題復雜化,我們用P1口的8個LED來顯示計到的數據。程序如下:ORG 0000H AJMP START ORG 30H START: MOV SP,#5FH MOV TMOD,#01000000B ;定時/計數器1作計數用,0不用全置0 SETB TR1 ;啟動計數器1開始運行. LOOP: MOV A,TL0 MOV P1,A AJMP LOOPEND 在硬件上用線將324的輸出與T1連通(印板上有焊盤)運行這種程序,注意將板按正確的位置放置(LM324放在左手邊

39、,LED排列是按從高位到低們排列)看到什么?隨著324后接的LED的閃爍,單片機的8只LED也在不斷變化,注意觀察,是不是按二進制:00000000000000010000001000000011。這樣的順序在變呢?這就對了,這就是TL0中的數據。程序二:ORG 0000H AJMP START ORG 001BH AJMP TIMER1 ;定時器1的中斷處理ORG 30H START: MOV SP,#5FH MOV TMOD,#01010000B ;定時/計數器1作計數用,模式1,0不用全置0 MOV TH1,#0FFH MOV TL1,#0FAH ;預置值,要求每計到6個脈沖即為一個事件

40、 SETB EASETB ET1 ;開總中斷和定時器1中斷允許 SETB TR1 ;啟動計數器1開始運行. AJMP $ TIMER1: PUSH ACC PUSH PSW CPL P1.0 ;計數值到,即取反P1.0 MOV TH1,#0FFH MOV TL1,#0FAH ;重置計數初值POP PSW POP ACC RETI END 上面這個程序完成的工作很簡單,就是在每6個脈沖到來后取反一次P1。0,因此實驗的結果應當是:LM324后接的LED亮、滅6次,則P1。0口所接LED亮或滅一次。這實際就是我們上面講的計數器的第二種應用。程序三:外部中斷實驗ORG 0000H AJMP STAR

41、T ORG 0003H ;外部中斷地直入口 AJMP INT0 ORG 30H START: MOV SP,#5FH MOV P1,#0FFH ;燈全滅 MOV P3,#0FFH ;P3口置高電平 SETB EA SETB EX0 AJMP $ INT0: PUSH ACC PUSH PSW CPL P1.0 POP PSW POP ACC RETI END 本程序的功能很簡單,按一次按鍵1(接在12引腳上的)就引發(fā)一次中斷0,取反一次P1。0,因此理論上按一下燈亮,按一下燈滅,但在實際做實驗時,可能會發(fā)覺有時不“靈”,按了它沒反應,但在大部份時候是對的,這是怎么回事呢?我們在講解鍵盤時再作解

42、釋,這個程序本身是沒有問題的。程序1下載 程序1代碼 程序2下載 程序2代碼 程序3下載 程序3代碼串行接口1. 概述 1. 串行接口的一般概念 單片機與外界進行信息交換稱之為通訊。 8051單片機的通訊方式有兩種:并行通訊:數據的各位同時發(fā)送或接收。串行通訊:數據一位一位順序發(fā)送或接收。參看下圖:串行通訊的方式:1. 異步通訊:它用一個起始位表示字符的開始,用停止位表示字符的結束。其每幀的格式如下: 在一幀格式中,先是一個起始位0,然后是8個數據位,規(guī)定低位在前,高位在后,接下來是奇偶校驗位(可以省略),最后是停止位1。用這種格式表示字符,則字符可以一個接一個地傳送。在異步通訊中,CPU與外

43、設之間必須有兩項規(guī)定,即字符格式和波特率。字符格式的規(guī)定是雙方能夠在對同一種0和1的串理解成同一種意義。原則上字符格式可以由通訊的雙方自由制定,但從通用、方便的角度出發(fā),一般還是使用一些標準為好,如采用ASCII標準。波特率即數據傳送的速率,其定義是每秒鐘傳送的二進制數的位數。例如,數據傳送的速率是120字符/s,而每個字符如上述規(guī)定包含10數位,則傳送波特率為1200波特。2. 同步通訊:在同步通訊中,每個字符要用起始位和停止位作為字符開始和結束的標志,占用了時間;所以在數據塊傳遞時,為了提高速度,常去掉這些標志,采用同步傳送。由于數據塊傳遞開始要用同步字符來指示,同時要求由時鐘來實現發(fā)送端

44、與接收端之間的同步,故硬件較復雜。 3. 通訊方向:在串行通訊中,把通訊接口只能發(fā)送或接收的單向傳送方法叫單工傳送;而把數據在甲乙兩機之間的雙向傳遞,稱之為雙工傳送。在雙工傳送方式中又分為半雙工傳送和全雙工傳送。半雙工傳送是兩機之間不能同時進行發(fā)送和接收,任一時該,只能發(fā)或者只能收信息。 28051單片機的串行接口結構8051串行接口是一個可編程的全雙工串行通訊接口。它可用作異步通訊方式(UART),與串行傳送信息的外部設備相連接,或用于通過標準異步通訊協(xié)議進行全雙工的8051多機系統(tǒng)也可以通過同步方式,使用TTL或CMOS移位寄存器來擴充I/O口。8051單片機通過引腳RXD(P3.0,串行

45、數據接收端)和引腳TXD(P3.1,串行數據發(fā)送端)與外界通訊。SBUF是串行口緩沖寄存器,包括發(fā)送寄存器和接收寄存器。它們有相同名字和地址空間,但不會出現沖突,因為它們兩個一個只能被CPU讀出數據,一個只能被CPU寫入數據。1. 串行口的控制與狀態(tài)寄存器 1. 串行口控制寄存器SCON 它用于定義串行口的工作方式及實施接收和發(fā)送控制。字節(jié)地址為98H,其各位定義如下表:D7 D6 D5 D4 D3 D2 D1 D0 SM0 SM1 SM2 REN TB8 RB8 TI RI SM0、SM1:串行口工作方式選擇位,其定義如下:SM0、SM1 工作方式 功能描述 波特率 0 0 方式0 8位移位

46、寄存器 Fosc/12 0 1 方式1 10位UART 可變 1 0 方式2 11位UART Fosc/64或fosc/32 1 1 方式3 11位UART 可變 其中fosc為晶振頻率SM2:多機通訊控制位。在方式0時,SM2一定要等于0。在方式1中,當(SM2)=1則只有接收到有效停止位時,RI才置1。在方式2或方式3當(SM2)=1且接收到的第九位數據RB8=0時,RI才置1。REN:接收允許控制位。由軟件置位以允許接收,又由軟件清0來禁止接收。TB8: 是要發(fā)送數據的第9位。在方式2或方式3中,要發(fā)送的第9位數據,根據需要由軟件置1或清0。例如,可約定作為奇偶校驗位,或在多機通訊中作為

47、區(qū)別地址幀或數據幀的標志位。RB8:接收到的數據的第9位。在方式0中不使用RB8。在方式1中,若(SM2)=0,RB8為接收到的停止位。在方式2或方式3中,RB8為接收到的第9位數據。TI: 發(fā)送中斷標志。在方式0中,第8位發(fā)送結束時,由硬件置位。在其它方式的發(fā)送停止位前,由硬件置位。TI置位既表示一幀信息發(fā)送結束,同時也是申請中斷,可根據需要,用軟件查詢的方法獲得數據已發(fā)送完畢的信息,或用中斷的方式來發(fā)送下一個數據。TI必須用軟件清0。RI: 接收中斷標志位。在方式0,當接收完第8位數據后,由硬件置位。在其它方式中,在接收到停止位的中間時刻由硬件置位(例外情況見于SM2的說明)。RI置位表示

48、一幀數據接收完畢,可用查詢的方法獲知或者用中斷的方法獲知。RI也必須用軟件清0。2. 特殊功能寄存器PCON PCON是為了在CHMOS的80C51單片機上實現電源控制而附加的。其中最高位是SMOD。1. 串行口的工作方式 8051單片機的全雙工串行口可編程為4種工作方式,現分述如下:1. 方式0為移位寄存器輸入/輸出方式。可外接移位寄存器以擴展I/O口,也可以外接同步輸入/輸出設備。8位串行數據者是從RXD輸入或輸出,TXD用來輸出同步脈沖。 1. 輸出 串行數據從RXD引腳輸出,TXD引腳輸出移位脈沖。CPU將數據寫入發(fā)送寄存器時,立即啟動發(fā)送,將8位數據以fos/12的固定波特率從RXD

49、輸出,低位在前,高位在后。發(fā)送完一幀數據后,發(fā)送中斷標志TI由硬件置位。 2. 輸入 當串行口以方式0接收時,先置位允許接收控制位REN。此時,RXD為串行數據輸入端,TXD仍為同步脈沖移位輸出端。當(RI)=0和(REN)=1同時滿足時,開始接收。當接收到第8位數據時,將數據移入接收寄存器,并由硬件置位RI。 下面兩圖分別是方式0擴展輸出和輸入的接線圖。 1. 方式1為波特率可變的10位異步通訊接口方式。發(fā)送或接收一幀信息,包括1個起始位0,8個數據位和1個停止位1。 1. 輸出 當CPU執(zhí)行一條指令將數據寫入發(fā)送緩沖SBUF時,就啟動發(fā)送。串行數據從TXD引腳輸出,發(fā)送完一幀數據后,就由硬

50、件置位TI。 2. 輸入 在(REN)=1時,串行口采樣RXD引腳,當采樣到1至0的跳變時,確認是開始位0,就開始接收一幀數據。只有當(RI)=0且停止位為1或者(SM2)=0時,停止位才進入RB8,8位數據才能進入接收寄存器,并由硬件置位中斷標志RI;否則信息丟失。所以在方式1接收時,應先用軟件清零RI和SM2標志。 1. 方式2 方式月為固定波特率的11位UART方式。它比方式1增加了一位可程控為1或0的第9位數據。1. 輸出: 發(fā)送的串行數據由TXD端輸出一幀信息為11位,附加的第9位來自SCON寄存器的TB8位,用軟件置位或復位。它可作為多機通訊中地址/數據信息的標志位,也可以作為數據

51、的奇偶校驗位。當CPU執(zhí)行一條數據寫入SUBF的指令時,就啟動發(fā)送器發(fā)送。發(fā)送一幀信息后,置位中斷標志TI。 2. 輸入: 在(REN)=1時,串行口采樣RXD引腳,當采樣到1至0的跳變時,確認是開始位0,就開始接收一幀數據。在接收到附加的第9位數據后,當(RI)=0或者(SM2)=0時,第9位數據才進入RB8,8位數據才能進入接收寄存器,并由硬件置位中斷標志RI;否則信息丟失。且不置位RI。再過一位時間后,不管上述條件時否滿足,接收電路即行復位,并重新檢測RXD上從1到0的跳變。 1. 工作方式3 方式3為波特率可變的11位UART方式。除波特率外,其余與方式2相同。1. 波特率選擇 如前所

52、述,在串行通訊中,收發(fā)雙方的數據傳送率(波特率)要有一定的約定。在8051串行口的四種工作方式中,方式0和2的波特率是固定的,而方式1和3的波特率是可變的,由定時器T1的溢出率控制。1. 方式0 方式0的波特率固定為主振頻率的1/12。2. 方式2 方式2的波特率由PCON中的選擇位SMOD來決定,可由下式表示:波特率=2的SMOD次方除以64再乘一個fosc,也就是當SMOD=1時,波特率為1/32fosc,當SMOD=0時,波特率為1/64fosc3方式1和方式3定時器T1作為波特率發(fā)生器,其公式如下:波特率=定時器T1溢出率 T1溢出率= T1計數率/產生溢出所需的周期數式中T1計數率取

53、決于它工作在定時器狀態(tài)還是計數器狀態(tài)。當工作于定時器狀態(tài)時,T1計數率為fosc/12;當工作于計數器狀態(tài)時,T1計數率為外部輸入頻率,此頻率應小于fosc/24。產生溢出所需周期與定時器T1的工作方式、T1的預置值有關。定時器T1工作于方式0:溢出所需周期數=8192-x 定時器T1工作于方式1:溢出所需周期數=65536-x定時器T1工作于方式2:溢出所需周期數=256-x因為方式2為自動重裝入初值的8位定時器/計數器模式,所以用它來做波特率發(fā)生器最恰當。當時鐘頻率選用11.0592MHZ時,取易獲得標準的波特率,所以很多單片機系統(tǒng)選用這個看起來“怪”的晶振就是這個道理。下表列出了定時器T

54、1工作于方式2常用波特率及初值。常用波特率Fosc(MHZ)SMODTH1初值1920011.05921FDH960011.05920FDH480011.05920FAH240011.05920F4h120011.05920E8h串行口應用編程實例1 串口方式0應用編程 8051單片機串行口方式0為移位寄存器方式,外接一個串入并出的移位寄存器,就可以擴展一個并行口。例:用8051串行口外接CD4094擴展8位并行輸出口,如圖所示,8位并行口的各位都接一個發(fā)光二極管,要求發(fā)光管呈流水燈狀態(tài)。 串行口方式0的數據傳送可采用中斷方式,也可采用查詢方式,無論哪種方式,都要借助于TI或RI標志。串行發(fā)送

55、時,可以靠TI置位(發(fā)完一幀數據后)引起中斷申請,在中斷服務程序中發(fā)送下一幀數據,或者通過查詢TI的狀態(tài),只要TI為0就繼續(xù)查詢,TI為1就結束查詢,發(fā)送下一幀數據。在串行接收時,則由RI引起中斷或對RI查詢來確定何時接收下一幀數據。無論采用什么方式,在開始通訊之前,都要先對控制寄存器SCON進行初始化。在方式0中將,將00H送SCON就可以了。 ORG 2000H START: MOV SCON,#00H ;置串行口工作方式0 MOV A,#80H ;最高位燈先亮 CLR P1.0 ;關閉并行輸出(避象傳輸過程中,各LED的暗紅現象)OUT0: MOV SBUF,A ;開始串行輸出 OUT1

56、: JNB TI,OUT1 ;輸出完否 CLR TI ;完了,清TI標志,以備下次發(fā)送 SETB P1.0 ;打開并行口輸出 ACALL DELAY ;延時一段時間 RR A ;循環(huán)右移 CLR P1.0 ;關閉并行輸出 JMP OUT0 ;循環(huán) 說明:DELAY延時子程序可以用前面我們講P1口流水燈時用的延時子程序,這里就不給出了。 二、異步通訊org 0000HAJMP STARTORG 30HSTART: mov SP,#5fh ;mov TMOD,#20h ;T1: 工作模式2mov PCON,#80h ;SMOD=1mov TH1,#0FDH ;初始化波特率(參見表)mov SCON,#50h ;Standard UART settingsMOV R0,#0

溫馨提示

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

最新文檔

評論

0/150

提交評論