單片機(jī)學(xué)習(xí)知識點(diǎn)全攻略(三)
導(dǎo)語:本期主要知識點(diǎn)為單片機(jī)定時(shí)計(jì)數(shù)器、中斷和串行口的學(xué)習(xí)。單片機(jī)對于初學(xué)者來說確 實(shí)很難理解,不少學(xué)過單片機(jī)的同學(xué)或電子愛好者,甚至在畢業(yè)時(shí)仍舊是一無所獲?;诖耍娮影l(fā)燒友網(wǎng)將整合《單片機(jī)學(xué)習(xí)知識點(diǎn)全攻略》,共分為四個(gè)系列, 以饗讀者,敬請期待!此系列對于業(yè)內(nèi)電子工程師也有收藏和參考價(jià)值。 參閱相關(guān)系列 單片機(jī)學(xué)習(xí)知識點(diǎn)全攻略(一) 單片機(jī)學(xué)習(xí)知識點(diǎn)全攻略(二) 系列三主要知識點(diǎn): 15:單片機(jī)位操作指令 16:單片機(jī)定時(shí)器與計(jì)數(shù)器 17:單片機(jī)定時(shí)器/計(jì)數(shù)器的方式 18:單片機(jī)的中斷系統(tǒng) 19:單片機(jī)定時(shí)器、中斷試驗(yàn) 20:單片機(jī)定時(shí)/計(jì)數(shù)器實(shí)驗(yàn) 21:單片機(jī)串行口介紹 15、單片機(jī)位操作指令 前面那些流水燈的例程,我們已經(jīng)習(xí)慣了“位”一位就是一盞燈的亮和滅,而我們學(xué)的指令卻全都是用“字節(jié)”來介紹的:字節(jié)的移動(dòng)、加法、減法、邏輯運(yùn) 算、移位等等。用字節(jié)來處理一些數(shù)學(xué)問題,比如說:控制冰箱的溫度、電視的音量等等很直觀,能直接用數(shù)值來表在??墒侨绻盟鼇砜刂埔恍╅_關(guān)的打開和合 上,燈的亮和滅,就有些不直接了,記得我們上次課上的流水燈的例程嗎?我們知道送往P1口的數(shù)值后并不能馬上知道哪個(gè)燈亮和來滅,而是要化成二進(jìn)制才知 道。工業(yè)中有很多場合需要處理這類開關(guān)輸出,繼電器吸合,用字節(jié)來處理就顯示有些麻煩,所以在8031單片機(jī)中特意引入一個(gè)位處理機(jī)制。 位尋址區(qū) 在8031中,有一部份RAM和一部份SFR是具有位尋址功能的,也就是說這些RAM的每一個(gè)位都有自已的地址,能直接用這個(gè)地址來對此進(jìn)行操作。 內(nèi)部RAM的20H-2FH這16個(gè)字節(jié),就是8031的位尋址區(qū)??磮D1??梢娺@里面的每一個(gè)RAM中的每個(gè)位我們都可能直接用位地址來找到它們,而不必用字節(jié)地址,然后再用邏輯指令的方式。 能位尋址的特殊功能寄存器 8031中有一些SFR是能進(jìn)行位尋址的,這些SFR的特點(diǎn)是其字節(jié)地址均可被8整除,如A累加器,B寄存器、PSW、IP(中斷優(yōu)先級控制寄存 器)、IE(中斷允許控制寄存器)、SCON(串行口控制寄存器)、TCON(定時(shí)器/計(jì)數(shù)器控制寄存器)、P0-P3(I/O端口鎖存器)。以上的一些 SFR我們還不熟,等我們講解相關(guān)內(nèi)容時(shí)再作詳細(xì)解釋。 位操作指令 MCS-51單片機(jī)的硬件結(jié)構(gòu)中,有一個(gè)位處理器(又稱布爾處理器),它有一套位變量處理的指令集。在進(jìn)行位處理時(shí),CY(就是我們前面講的進(jìn)位位) 稱“位累加器”。有自已的位RAM,也就是我們剛講的內(nèi)部RAM的20H-2FH這16個(gè)字節(jié)單元即128個(gè)位單元,還有自已的位I/O空間(即 P0.0…。.P0.7,P1.0…….P1.7,P2.0……。.P2.7,P3.0……。.P3.7)。當(dāng)然在物理實(shí)體上它們與原來的以字節(jié)尋址用的 RAM,及端口是完全相同的,或者說這些RAM及端口都能有兩種使用辦法。 位傳送指令 MOV C,BIT MOV BIT,C 這組指令的功能是實(shí)現(xiàn)位累加器(CY)和其它位地址之間的數(shù)據(jù)傳遞。 例:MOV P1.0,CY ;將CY中的狀態(tài)送到P1.0管腳上去(如果是做算術(shù)運(yùn)算,我們就能通過觀察知道現(xiàn)在CY是多少啦)。 MOV P1.0,CY ;將P1.0的狀態(tài)送給CY。 位修正指令 位清0指令 CLR C ;使CY=0 CLR bit ;使指令的位地址等于0。例:CLR P1.0 ;即使P1.0變?yōu)? 位置1指令 SETB C ;使CY=1 SETB bit ;使指定的位地址等于1。例:SETB P1.0 ;使P.0變?yōu)? 位取反指令 CPL C ;使CY等于原來的相反的值,由1變?yōu)?,由0變?yōu)?。 CPL bit ;使指定的位的值等于原來相反的值,由0變?yōu)?,由1變?yōu)?。 例:CPL P1.0 以我們做過的實(shí)驗(yàn)為例,如果原來燈是亮的,則執(zhí)行本指令后燈滅,反之原來燈是滅的,執(zhí)行本指令后燈亮。 位邏輯運(yùn)算指令 位與指令 ANL C,bit ;CY與指定的位地址的值相與,結(jié)果送回CY
ANL C,/bit ;先將指定的位地址中的值取出后取反,再和CY相與,結(jié)果送回CY,但注意,指定的位地址中的值本身并不發(fā)生變化。
例:ANL C,/P1.0 設(shè)執(zhí)行本指令前,CY=1,P1.0等于1(燈滅),則執(zhí)行完本指令后CY=0,而P1.0也是等于1。 可用下列程序驗(yàn)證: ORG 0000H AJMP START ORG 30H START: MOV SP,#5FH MOV P1,#0FFH SETB C ANL C,/P1.0 MOV P1.1,C ;將做完的結(jié)果送P1.1,結(jié)果應(yīng)當(dāng)是P1.1上的燈亮,而P1.0上的燈還是不亮 位或指令 ORL C,bit ORL C,/bit 這個(gè)的功能大家自行分析吧,然后對照上面的例程,編一個(gè)驗(yàn)證程序,看看你相得對嗎? 位條件轉(zhuǎn)移指令 判CY轉(zhuǎn)移指令 JC rel JNC rel 第一條指令的功能是如果CY等于1就轉(zhuǎn)移,如果不等于1就次序執(zhí)行。那么轉(zhuǎn)移到什么地方去呢?我們能這樣理解:JC 標(biāo)號,如果等于1就轉(zhuǎn)到標(biāo)號處執(zhí)行。這條指令我們在上節(jié)課中已講到,不再重復(fù)。 第二條指令則和第一條指令相反,即如果CY=0就轉(zhuǎn)移,不等于0就次序執(zhí)行,當(dāng)然,我們也同樣理解: JNC 標(biāo)號 判位變量轉(zhuǎn)移指令 JB bit,rel JNB bit,rel 第一條指令是如果指定的bit位中的值是1,則轉(zhuǎn)移,不然次序執(zhí)行。同樣,我們能這樣理解這條指令:JB bit,標(biāo)號 第二條指令請大家先自行分析 下面我們舉個(gè)例程說明: ORG 0000H LJMP START ORG 30H START:MOV SP,#5FH MOV P1,#0FFH MOV P3,#0FFH L1: JNB P3.2,L2 ;P3.2上接有一只按鈕,它按下時(shí),P3.2=0 JNB P3.3,L3 ;P3.3上接有一只按鈕,它按下時(shí),P3.3=0 LJM P L1 L2: MOV P1,#00H LJMP L1 L3: MOV P1,#0FFH LJMP L1 END 把上面的例程寫入片子,看看有什么現(xiàn)象……… 按下接在P3.2上的按鈕,P1口的燈全亮了,松開或再按,燈并不熄滅,然后按下接在P3.3上的按鈕,燈就全滅了。這像什么?這不就是工業(yè)現(xiàn)場經(jīng)常用到的“啟動(dòng)”、“停止”的功能嗎? 怎么做到的呢?一開始,將0FFH送入P3口,這樣,P3的所有引線都處于高電平,然后執(zhí)行L1,如果P3.2是高電平(鍵沒有按下),則次序執(zhí)行 JNB P3.3,L3語句,同樣,如果P3.3是高電平(鍵沒有按下),則次序執(zhí)行LJMP L1語句。這樣就不停地檢測P3.2、P3.3,如果有一次P3.2上的按鈕按下去了,則轉(zhuǎn)移到L2,執(zhí)行MOV P1,#00H,使燈全亮,然后又轉(zhuǎn)去L1,再次循環(huán),直到檢測到P3.3為0,則轉(zhuǎn)L3,執(zhí)行MOV P1,#0FFH,例燈全滅,再轉(zhuǎn)去L1,如此循環(huán)不已。大家能否稍加改動(dòng),將本程序用JB指令改寫? 一、計(jì)數(shù)概念的引入 從選票的統(tǒng)計(jì)談起:畫“正”。這就是計(jì)數(shù),生活中計(jì)數(shù)的例程處處可見。例:錄音機(jī)上的計(jì)數(shù)器、家里面用的電度表、汽車上的里程表等等,再舉一個(gè)工業(yè)生 產(chǎn)中的例程,線纜行業(yè)在電線生產(chǎn)出來之后要計(jì)米,也就是測量長度,怎么測法呢?用尺量?不現(xiàn)實(shí),太長不說,要一邊做一邊量呢,怎么辦呢?行業(yè)中有很巧妙的 辦法,用一個(gè)周長是1米的輪子,將電纜繞在上面一周,由線帶輪轉(zhuǎn),這樣輪轉(zhuǎn)一周不就是線長1米嘛,所以只要記下輪轉(zhuǎn)了多少圈,就能知道走過的線有多長了。 二、計(jì)數(shù)器的容量 從一個(gè)生活中的例程看起:一個(gè)水盆在水龍頭下,水龍沒關(guān)緊,水一滴滴地滴入盆中。水滴持續(xù)落下,盆的容量是有限的,過一段時(shí)間之后,水就會(huì)逐漸變滿。 錄音機(jī)上的計(jì)數(shù)器最多只計(jì)到999…。那么單片機(jī)中的計(jì)數(shù)器有多大的容量呢?8031單片機(jī)中有兩個(gè)計(jì)數(shù)器,分別稱之為T0和T1,這兩個(gè)計(jì)數(shù)器分別是由 兩個(gè)8位的RAM單元組成的,即每個(gè)計(jì)數(shù)器都是16位的計(jì)數(shù)器,最大的計(jì)數(shù)量是65536。 三、定時(shí) 8031中的計(jì)數(shù)器除了能作為計(jì)數(shù)之用外,還能用作時(shí)鐘,時(shí)鐘的用途當(dāng)然很大,如打鈴器,電視機(jī)定時(shí)關(guān)機(jī),空調(diào)定時(shí)開關(guān)等等,那么計(jì)數(shù)器是如何作為定時(shí)器來用的呢? 一個(gè)鬧鐘,我將它定時(shí)在1個(gè)小時(shí)后鬧響,換言之,也能說是秒針走了(3600)次,所以時(shí)間就轉(zhuǎn)化為秒針走的次數(shù)的,也就是計(jì)數(shù)的次數(shù)了,可見,計(jì)數(shù)的次數(shù)和時(shí)間之間的確十分相關(guān)。那么它們的關(guān)系是什么呢?那就是秒針每一次走動(dòng)的時(shí)間正好是1秒。 《單片機(jī)定時(shí)器記數(shù)器結(jié)構(gòu)》
16、單片機(jī)定時(shí)器與計(jì)數(shù)器
結(jié)論:只要計(jì)數(shù)脈沖的間隔相等,則計(jì)數(shù)值就代表了時(shí)間的流逝。由此,單片機(jī)中的定時(shí)器和計(jì)數(shù)器是一個(gè)東西,只不過計(jì)數(shù)器是記錄的外界發(fā)生的事情,而定 時(shí)器則是由單片機(jī)供給一個(gè)非常穩(wěn)定的計(jì)數(shù)源。那么供給組定時(shí)器的是計(jì)數(shù)源是什么呢?看圖1,原來就是由單片機(jī)的晶體震蕩器經(jīng)過12分頻后獲得的一個(gè)脈沖 源。晶體震蕩器的頻率當(dāng)然很準(zhǔn),所以這個(gè)計(jì)數(shù)脈沖的時(shí)間間隔也很準(zhǔn)。問題:一個(gè)12M的晶體震蕩器,它供給給計(jì)數(shù)器的脈沖時(shí)間間隔是多少呢?當(dāng)然這很不 難,就是12M/12等于1M,也就是1個(gè)微秒。結(jié)論:計(jì)數(shù)脈沖的間隔與晶體震蕩器有關(guān),12M的晶體震蕩器,計(jì)數(shù)脈沖的間隔是1微秒。
四、溢出 讓我們再來看水滴的例程,當(dāng)水持續(xù)落下,盆中的水持續(xù)變滿,最終有一滴水使得盆中的水滿了。這個(gè)時(shí)候如果再有一滴水落下,就會(huì)發(fā)生什么現(xiàn)象?水會(huì)漫出來,用個(gè)術(shù)語來講就是“溢出”。 水溢出是流到地上,而計(jì)數(shù)器溢出后將使得TF0變?yōu)?ldquo;1”。至于TF0是什么我們稍后再談。一旦TF0由0變成1,就是產(chǎn)生了變化,產(chǎn)生了變化就會(huì)引 發(fā)事件,就象定時(shí)的時(shí)間一到,鬧鐘就會(huì)響一樣。至于會(huì)引發(fā)什么事件,我們下次課再介紹,現(xiàn)在我們來研究另一個(gè)問題:要有多少個(gè)計(jì)數(shù)脈沖才會(huì)使TF0由0變 為1。 五、任意定時(shí)及計(jì)數(shù)的辦法 剛才已研究過,計(jì)數(shù)器的容量是16位,也就是最大的計(jì)數(shù)值到65536,因此計(jì)數(shù)計(jì)到65536就會(huì)產(chǎn)生溢出。這個(gè)沒有問題,問題是我們現(xiàn)實(shí)生活中,經(jīng)常 會(huì)有少于65536個(gè)計(jì)數(shù)值的要求,如包裝線上,一打?yàn)?2瓶,一瓶藥片為100粒,怎么樣來滿足這個(gè)要求呢? 提示:如果是一個(gè)空的盆要1萬滴水滴進(jìn)去才會(huì)滿,我在開始滴水之前就先放入一勺水,還需要10000滴嘛?對了,我們采用預(yù)置數(shù)的辦法,我要計(jì) 100,那我就先放進(jìn)65436,再來100個(gè)脈沖,不就到了65536了嗎。定時(shí)也是如此,每個(gè)脈沖是1微秒,則計(jì)滿65536個(gè)脈沖需時(shí)65.536 毫秒,但現(xiàn)在我只要10毫秒就能了,怎么辦?10個(gè)毫秒為10000個(gè)微秒,所以,只要在計(jì)數(shù)器里面放進(jìn)55536就能了。 17、單片機(jī)定時(shí)器/計(jì)數(shù)器的方式 從上一節(jié)我們已經(jīng)得知,單片機(jī)中的定時(shí)/計(jì)數(shù)器都能有多種用途,那么我怎樣才能讓它們工作于我所需要的用途呢?這就要通過定時(shí)/計(jì)數(shù)器的方式控制字來設(shè)置。 在單片機(jī)中有兩個(gè)特殊功能寄存器與定時(shí)/計(jì)數(shù)有關(guān),這就是TMOD和TCON。順便說一下,TMOD和TCON是名稱,我們在寫程序時(shí)就能直接用這個(gè) 名稱來指定它們,當(dāng)然也能直接用它們的地址89H和88H來指定它們(其實(shí)用名稱也就是直接用地址,匯編軟件幫你翻譯一下而已)。 《TMOD結(jié)構(gòu)》 從圖1中我們能看出,TMOD被分成兩部份,每部份4位。分別用于控制T1和T0,至于這里面是什么意思,我們下面介紹。 《TCON結(jié)構(gòu)》 從圖2中我們能看出,TCON也被分成兩部份,高4位用于定時(shí)/計(jì)數(shù)器,低4位則用于中斷(我們暫不管)。而TF1(0)我們上節(jié)課已提到了,當(dāng)計(jì)數(shù)溢出后TF1(0)就由0變?yōu)?。原來TF1(0)在這兒!那么TR0、TR1又是什么呢?看上節(jié)課的圖。 計(jì)數(shù)脈沖要進(jìn)入計(jì)數(shù)器還真不不難,有層層關(guān)要通過,最起碼,就是TR0(1)要為1,開關(guān)才能合上,脈沖才能過來。因此,TR0(1)稱之為運(yùn)行控制 位,可用指令SETB來置位以啟動(dòng)計(jì)數(shù)器/定時(shí)器運(yùn)行,用指令CLR來關(guān)閉定時(shí)/計(jì)數(shù)器的工作,一切盡在自已的掌握中。 《單片機(jī)定時(shí)器/計(jì)數(shù)器結(jié)構(gòu)》 定時(shí)/計(jì)數(shù)器的四種工作方式 工作方式0 定時(shí)器/計(jì)數(shù)器的工作方式0稱之為13位定時(shí)/計(jì)數(shù)方式。它由TL(1/0)的低5位和TH(0/1)的8位組成13位的計(jì)數(shù)器,此時(shí)TL(1/0)的高3位未用。 我們用這個(gè)圖來討論幾個(gè)問題: M1M0:定時(shí)/計(jì)數(shù)器一共有四種工作方式,就是用M1M0來控制的,2位正好是四種組合。 C/T:前面我們說過,定時(shí)/計(jì)數(shù)器即可作定時(shí)用也可用計(jì)數(shù)用,到底作什么用,由我們根據(jù)需要自行決定,也說是決定權(quán)在我 們#0;#0;編程者。如果C/T為0就是用作定時(shí)器(開關(guān)往上打),如果C/T為1就是用作計(jì)數(shù)器(開關(guān)往下打)。順便提一下:一 個(gè)定時(shí)/計(jì)數(shù)器同一時(shí)刻要么作定時(shí)用,要么作計(jì)數(shù)用,不能同時(shí)用的,這是個(gè)極普通的常識,幾乎沒有教材會(huì)提這一點(diǎn),但很多開始學(xué)習(xí)者卻會(huì)有此困惑。 GATE:看圖,當(dāng)我們選擇了定時(shí)或計(jì)數(shù)工作方式后,定時(shí)/計(jì)數(shù)脈沖卻不一定能到達(dá)計(jì)數(shù)器端,中間還有一個(gè)開關(guān),顯然這個(gè)開關(guān)不合上,計(jì)數(shù)脈沖就沒法過去,那么開關(guān)什么時(shí)候過去呢?有兩種情況 GATE=0,分析一下邏輯,GATE非后是1,進(jìn)入或門,或門總是輸出1,和或門的另一個(gè)輸入端INT1無關(guān),在這種情況下,開關(guān)的打開、合上只取 決于TR1,只要TR1是1,開關(guān)就合上,計(jì)數(shù)脈沖得以暢通無阻,而如果TR1等于0則開關(guān)打開,計(jì)數(shù)脈沖無法通過,因此定時(shí)/計(jì)數(shù)是否工作,只取決于 TR1。 GATE=1,在此種情況下,計(jì)數(shù)脈沖通路上的開關(guān)不僅要由TR1來控制,而且還要受到INT1管腳的控制,只有TR1為1,且INT1管腳也是高電平,開關(guān)才合上,計(jì)數(shù)脈沖才得以通過。這個(gè)特性能用來測量一個(gè)信號的高電平的寬度,想想看,怎么測? 為什 么在這種模式下只用13位呢?干嗎不用16位,這是為了和51機(jī)的前輩48系列兼容而設(shè)的一種工作式,如果你覺得用得不順手,那就干脆用第二種工作方式。 工作方式1
工作方式1是16位的定時(shí)/計(jì)數(shù)方式,將M1M0設(shè)為01即可,其它特性與工作方式0相同。
工作方式2 在介紹這種式方式之前先讓我們思考一個(gè)問題:上一次課我們提到過任意計(jì)數(shù)及任意定時(shí)的問題,比如我要計(jì)1000個(gè)數(shù),可是16位的計(jì)數(shù)器要計(jì)到 65536才滿,怎么辦呢?我們討論后得出的辦法是用預(yù)置數(shù),先在計(jì)數(shù)器里放上64536,再來1000個(gè)脈沖,不就行了嗎?是的,但是計(jì)滿了之后我們又 該怎么辦呢?要知道,計(jì)數(shù)總是持續(xù)重復(fù)的,流水線上計(jì)滿后馬上又要開始下一次計(jì)數(shù),下一次的計(jì)數(shù)還是1000嗎?當(dāng)計(jì)滿并溢出后,計(jì)數(shù)器里面的值變成了 0(為什么,能參考前面課程的說明),因此下一次將要計(jì)滿65536后才會(huì)溢出,這可不符合要求,怎么辦?當(dāng)然辦法很簡單,就是每次一溢出時(shí)執(zhí)行一段程序 (這常常是需要的,要不然要溢出干嗎?)能在這段程序中做把預(yù)置數(shù)64536送入計(jì)數(shù)器中的事情。所以采用工作方式0或1都要在溢出后做一個(gè)重置預(yù)置數(shù)的 工作,做工作當(dāng)然就得要時(shí)間,一般來說這點(diǎn)時(shí)間不算什么,可是有一些場合我們還是要計(jì)較的,所以就有了第三種工作方式#0;#0;自 動(dòng)再裝入預(yù)置數(shù)的工作方式。 既然要自動(dòng)得新裝入預(yù)置數(shù),那么預(yù)置數(shù)就得放在一個(gè)地方,要不然裝什么呢?那么預(yù)置數(shù)放在什么地方呢?它放在T(0/1)的高8位,那么這樣高8位不 就不能參與計(jì)數(shù)了嗎?是的,在工作方式2,只有低8位參與計(jì)數(shù),而高8位不參與計(jì)數(shù),用作預(yù)置數(shù)的存放,這樣計(jì)數(shù)范圍就小多了,當(dāng)然做任可事總有代價(jià)的, 關(guān)鍵是看值不值,如果我根本不需要計(jì)那么多數(shù),那么就能用這種方式。看圖4,每當(dāng)計(jì)數(shù)溢出,就會(huì)打開T(0/1)的高、低8位之間的開關(guān),計(jì)預(yù)置數(shù)進(jìn)入低 8位。這是由硬件自動(dòng)完成的,不需要由人工干預(yù)。 常常這種式作方式用于波特率發(fā)生器(我們將在串行接口中講解),用于這種用途時(shí),定時(shí)器就是為了供給一個(gè)時(shí)間基準(zhǔn)。計(jì)數(shù)溢出后不需要做事情,要做的僅僅只有一件,就是重新裝入預(yù)置數(shù),再開始計(jì)數(shù),而且中間不要任何延遲,可見這個(gè)任務(wù)用工作方式2來完成是最妙不過了。 工作方式3 這種式作方式之下,定時(shí)/計(jì)數(shù)器0被拆成2個(gè)獨(dú)立的定時(shí)/計(jì)數(shù)器來用。其中,TL0能組成8位的定時(shí)器或計(jì)數(shù)器的工作方式,而TH0則只能作為定時(shí)器 來用。我們知道作定時(shí)、計(jì)數(shù)器來用,需要控制,計(jì)滿后溢出需要有溢出標(biāo)記,T0被分成兩個(gè)來用,那就要兩套控制及、溢出標(biāo)記了,從何而來呢?TL0還是用 原來的T0的標(biāo)記,而TH0則借用T1的標(biāo)記。如此T1不是無標(biāo)記、控制可用了嗎?是的。 一般情況處,只有在T1以工作方式2運(yùn)行(當(dāng)波特率發(fā)生器用)時(shí),才讓T0工作于方式3的。 定時(shí)器/計(jì)數(shù)器的定時(shí)/計(jì)數(shù)范圍 工作方式0:13位定時(shí)/計(jì)數(shù)方式,因此,最多能計(jì)到2的13次方,也就是8192次。 工作方式1:16位定時(shí)/計(jì)數(shù)方式,因此,最多能計(jì)到2的16次方,也就是65536次。 工作方式2和工作方式3,都是8位的定時(shí)/計(jì)數(shù)方式,因此,最多能計(jì)到2的8次方,也說是256次。 預(yù)置值計(jì)算:用最大計(jì)數(shù)量減去需要的計(jì)數(shù)次數(shù)即可。 例:流水線上一個(gè)包裝是12盒,要求每到12盒就產(chǎn)生一個(gè)動(dòng)作,用單片機(jī)的工作方式0來控制,應(yīng)當(dāng)預(yù)置多大的值呢?對了,就是8192-12=8180。 以上是計(jì)數(shù),明白了這個(gè)道理,定時(shí)也是一樣。這在前面的課程已提到,我們不再重復(fù),請參考前面的例程。 18、單片機(jī)的中斷系統(tǒng) 有關(guān)單片機(jī)中斷系統(tǒng)的概念:什么是中斷,我們從一個(gè)生活中的例程引入。你正在家中看書,突然電話鈴響了,你放下書本,去接電話,和來電話的人交談,然 后放下電話,回來繼續(xù)看你的書。這就是生活中的“中斷”的現(xiàn)象,就是正常的工作過程被外部的事件打斷了。仔細(xì)研究一下生活中的中斷,對于我們學(xué)習(xí)單片機(jī)的 中斷也很有好處。 第一、什么可經(jīng)引起中斷,生活中很多事件能引起中斷:有人按了門鈴了,電話鈴響了,你的鬧鐘鬧響了,你燒的水開了…。等等諸如此類的事件,我們把能引 起中斷的稱之為中斷源,單片機(jī)中也有一些能引起中斷的事件,8031中一共有5個(gè):兩個(gè)外部中斷,兩個(gè)計(jì)數(shù)/定時(shí)器中斷,一個(gè)串行口中斷。 第二、中斷的嵌套與優(yōu)先級處理:設(shè)想一下,我們正在看書,電話鈴響了,同時(shí)又有人按了門鈴,你該先做那樣呢?如果你正是在等一個(gè)很重要的電話,你一般 不會(huì)去理會(huì)門鈴的,而反之,你正在等一個(gè)重要的客人,則可能就不會(huì)去理會(huì)電話了。如果不是這兩者(即不等電話,也不是等人上門),你可能會(huì)按你常常的習(xí)慣 去處理??傊@里存在一個(gè)優(yōu)先級的問題,單片機(jī)中也是如此,也有優(yōu)先級的問題。優(yōu)先級的問題不僅僅發(fā)生在兩個(gè)中斷同時(shí)產(chǎn)生的情況,也發(fā)生在一個(gè)中斷已產(chǎn) 生,又有一個(gè)中斷產(chǎn)生的情況,比如你正接電話,有人按門鈴的情況,或你正開門與人交談,又有電話響了情況??紤]一下我們會(huì)怎么辦吧。
第三、中斷的響應(yīng)過程:當(dāng)有事件產(chǎn)生,進(jìn)入中斷之前我們必須先記住現(xiàn)在看書的第幾頁了,或拿一個(gè)書簽放在當(dāng)前頁的位置,然后去處理不一樣的事情(因?yàn)?處理完了,我們還要回來繼續(xù)看書):電話鈴響我們要到放電話的地方去,門鈴響我們要到門那邊去,也說是不一樣的中斷,我們要在不一樣的地點(diǎn)處理,而這個(gè)地 點(diǎn)常常還是固定的。計(jì)算機(jī)中也是采用的這種辦法,五個(gè)中斷源,每個(gè)中斷產(chǎn)生后都到一個(gè)固定的地方去找處理這個(gè)中斷的程序,當(dāng)然在去之前首先要保存下面將執(zhí) 行的指令的地址,以便處理完中斷后回到原來的地方繼續(xù)往下執(zhí)行程序。具體地說,中斷響應(yīng)能分為以下幾個(gè)步驟:1、保護(hù)斷點(diǎn),即保存下一將要執(zhí)行的指令的地 址,就是把這個(gè)地址送入堆棧。2、尋找中斷入口,根據(jù)5個(gè)不一樣的中斷源所產(chǎn)生的中斷,查找5個(gè)不一樣的入口地址。以上工作是由計(jì)算機(jī)自動(dòng)完成的,與編程 者無關(guān)。在這5個(gè)入口地址處存放有中斷處理程序(這是程序編寫時(shí)放在那兒的,如果沒把中斷程序放在那兒,就錯(cuò)了,中斷程序就不能被執(zhí)行到)。3、執(zhí)行中斷 處理程序。4、中斷返回:執(zhí)行完中斷指令后,就從中斷處返回到主程序,繼續(xù)執(zhí)行。究竟單片機(jī)是怎么樣找到中斷程序所在位置,又怎么返回的呢?我們稍后再 談。
MCS-51單片機(jī)中斷系統(tǒng)的結(jié)構(gòu): 5個(gè)中斷源的符號、名稱及產(chǎn)生的條件如下。 INT0:外部中斷0,由P3.2端口線引入,低電平或下跳沿引起。 INT1:外部中斷1,由P3.3端口線引入,低電平或下跳沿引起。 T0:定時(shí)器/計(jì)數(shù)器0中斷,由T0計(jì)滿回零引起。 T1:定時(shí)器/計(jì)數(shù)器l中斷,由T1計(jì)滿回零引起。 TI/RI:串行I/O中斷,串行端口完成一幀字符發(fā)送/接收后引起。 整個(gè)中斷系統(tǒng)的結(jié)構(gòu)框圖見下圖一所示。 《51單片機(jī)中斷系統(tǒng)結(jié)構(gòu)》 如圖所示,由與中斷有關(guān)的特殊功能寄存器、中斷入口、次序查詢邏輯電路等組成,包括5個(gè)中斷請求源,4個(gè)用于中斷控制的寄存器IE、IP、ECON和SCON來控制中斷類弄、中斷的開、關(guān)和各種中斷源的優(yōu)先級確定。 中斷請求源: ?。?)外部中斷請求源:即外中斷0和1,經(jīng)由外部管腳引入的,在單片機(jī)上有兩個(gè)管腳,名稱為INT0、INT1,也就是P3.2、P3.3這兩個(gè)管 腳。在內(nèi)部的TCON中有四位是與外中斷有關(guān)的。IT0:INT0觸發(fā)方式控制位,可由軟件進(jìn)和置位和復(fù)位,IT0=0,INT0為低電平觸發(fā)方 式,IT0=1,INT0為負(fù)跳變觸發(fā)方式。這兩種方式的差異將在以后再談。IE0:INT0中斷請求標(biāo)志位。當(dāng)有外部的中斷請求時(shí),這位就會(huì)置1(這由 硬件來完成),在CPU響應(yīng)中斷后,由硬件將IE0清0。IT1、IE1的用途和IT0、IE0相同。(2)內(nèi)部中斷請求源TF0:定時(shí)器T0的溢出中斷 標(biāo)記,當(dāng)T0計(jì)數(shù)產(chǎn)生溢出時(shí),由硬件置位TF0。當(dāng)CPU響應(yīng)中斷后,再由硬件將TF0清0。TF1:與TF0類似。TI、RI:串行口發(fā)送、接收中斷, 在串行口中再講解。2、中斷允許寄存器IE在MCS-51中斷系統(tǒng)中,中斷的允許或禁止是由片內(nèi)可進(jìn)行位尋址的8位中斷允許寄存器IE來控制的。見下表 EAX 其中EA是總開關(guān),如果它等于0,則所有中斷都不允許。ES-串行口中斷允許ET1-定時(shí)器1中斷允許EX1-外中斷1中斷允許。ET0-定時(shí)器0中斷允許EX0-外中斷0中斷允許。如果我們要設(shè)置允許外中斷1,定時(shí)器1中斷允許,其它不允許,則IE能是EAX 即8CH,當(dāng)然,我們也能用位操作指令SETB EA SETB ET1SETB EX1 來實(shí)現(xiàn)它。3、五個(gè)中斷源的自然優(yōu)先級與中斷服務(wù)入口地址外中斷0:0003H定時(shí)器0:000BH外中斷1:0013H定時(shí)器1:001BH串行口:0023H它們的自然優(yōu)先級由高到低排列。寫到這里,大家應(yīng)當(dāng)明白,為什么前面有一些程序一始我們這樣寫: ORG 0000HLJMP START ORG 0030H START:。 這樣寫的目的,就是為了讓出中斷源所占用的向量地址。當(dāng)然,在程序中沒用中斷時(shí),直接從0000H開始寫程序,在原理上并沒有錯(cuò),但在實(shí)際工作中最好 不這樣做。優(yōu)先級:單片機(jī)采用了自然優(yōu)先級和人工設(shè)置高、低優(yōu)先級的策略,即能由程序員設(shè)定那些中斷是高優(yōu)先級、哪些中斷是低優(yōu)先級,由于只有兩級,必有 一些中斷處于同一級別,處于同一級別的,就由自然優(yōu)先級確定。 開機(jī)時(shí),每個(gè)中斷都處于低優(yōu)先級,我們能用指令對優(yōu)先級進(jìn)行設(shè)置??幢?中斷優(yōu)先級中由中斷優(yōu)先級寄存器IP來高置的,IP中某位設(shè)為1,對應(yīng)的中斷就是高優(yōu)先級,不然就是低優(yōu)先級。 XX X PS PT1 PX1 PT0 PX0 例:設(shè)有如下要求,將T0、外中斷1設(shè)為高優(yōu)先級,其它為低優(yōu)先級,求IP的值。IP的首3位沒用,可任意取值,設(shè)為000,后面根據(jù)要求寫就能了XX 因此,最終,IP的值就是06H。例:在上例中,如果5個(gè)中斷請求同時(shí)發(fā)生,求中斷響應(yīng)的次序。響應(yīng)次序?yàn)椋憾〞r(shí)器0->外中斷1->外中斷0->實(shí)時(shí)器1->串行中斷。 MCS-51的中斷響應(yīng)過程: 1、中斷響應(yīng)的條件:講到這兒,我們依然對于計(jì)算機(jī)響應(yīng)中斷感到神奇,我們?nèi)四茼憫?yīng)外界的事件,是因?yàn)槲覀冇卸喾N“傳感器“DD眼、耳能接受不一樣的 信息,計(jì)算機(jī)是如何做到這點(diǎn)的呢?其實(shí)說穿了,一點(diǎn)都不希奇,MCS51工作時(shí),在每個(gè)機(jī)器周期中都會(huì)去查詢一下各個(gè)中斷標(biāo)記,看他們是否是“1“,如果 是1,就說明有中斷請求了,所以所謂中斷,其實(shí)也是查詢,不過是每個(gè)周期都查一下而已。這要換成人來說,就相當(dāng)于你在看書的時(shí)候,每一秒鐘都會(huì)抬起頭來看 一看,查問一下,是不是有人按門鈴,是否有電話。。。。很蠢,不是嗎?可計(jì)算機(jī)本來就是這樣,它根本沒人聰明。了解了上述中斷的過程,就不難解中斷響應(yīng)的 條件了。在下列三種情況之一時(shí),CPU將封鎖對中斷的響應(yīng): CPU正在處理一個(gè)同級或更高級別的中斷請求。 現(xiàn)行的機(jī)器周期不是當(dāng)前正執(zhí)行指令的最后一個(gè)周期。我們知道,單片機(jī)有單周期、雙周期、三周期指令,當(dāng)前執(zhí)行指令是單字節(jié)沒有關(guān)系,如果是雙字節(jié)或四字節(jié)的,就要等整條指令都執(zhí)行完了,才能響應(yīng)中斷(因?yàn)橹袛嗖樵兪窃诿總€(gè)機(jī)器周期都可能查到的)。
當(dāng)前正執(zhí)行的指令是返回批令(RETI)或訪問IP、IE寄存器的指令,則CPU至少再執(zhí)行一條指令才應(yīng)中斷。這些都是與中斷有關(guān)的,如果正訪問 IP、IE則可能會(huì)開、關(guān)中斷或改變中斷的優(yōu)先級,而中斷返回指令則說明本次中斷還沒有處理完,所以都要等本指令處理結(jié)束,再執(zhí)行一條指令才能響應(yīng)中斷。
2、中斷響應(yīng)過程CPU響應(yīng)中斷時(shí),首先把當(dāng)前指令的下一條指令(就是中斷返回后將要 執(zhí)行的指令)的地址送入堆棧,然后根據(jù)中斷標(biāo)記,將對應(yīng)的中斷入口地址送入PC,PC是程序指針,CPU取指令就根據(jù)PC中的值,PC中是什么值,就會(huì)到 什么地方去取指令,所以程序就會(huì)轉(zhuǎn)到中斷入口處繼續(xù)執(zhí)行。這些工作都是由硬件來完成的,不必我們?nèi)タ紤]。這里還有個(gè)問題,大家是否注意到,每個(gè)中斷向量地 址只間隔了8個(gè)單元,如0003-000B,在如此少的空間中如何完成中斷程序呢?很簡單,你在中斷處安排一個(gè)LJMP指令,不就能把中斷程序跳轉(zhuǎn)到任何 地方了嗎?一個(gè)完整的主程序看起來應(yīng)該是這樣的: ORG 0000HLJMP START ORG 0003H LJMP INT0 ;轉(zhuǎn)外中斷0ORG 000BH RETI ;沒有用定時(shí)器0中斷,在此放一條RETI,萬一 “不小心“產(chǎn)生了中斷,也不會(huì)有太大的后果。。 中斷程序完成后,一定要執(zhí)行一條RETI指令,執(zhí)行這條指令后,CPU將會(huì)把堆棧中保存著的地址取出,送回PC,那么程序就會(huì)從主程序的中斷處繼續(xù)往 下執(zhí)行了。注意:CPU所做的保護(hù)工作是很有限的,只保護(hù)了一個(gè)地址,而其它的所有東西都不保護(hù),所以如果你在主程序中用到了如A、PSW等,在中斷程序 中又要用它們,還要保證回到主程序后這里面的數(shù)據(jù)還是沒執(zhí)行中斷以前的數(shù)據(jù),就得自己保護(hù)起來。 中斷系統(tǒng)的控制寄存器: 中斷系統(tǒng)有兩個(gè)控制寄存器IE和IP,它們分別用來設(shè)定各個(gè)中斷源的打開/關(guān)閉和中斷優(yōu)先級。此外,在TCON中另有4位用于選擇引起外部中斷的條件并作為標(biāo)志位。 1.中斷允許寄存器--IE IE在特殊功能寄存器中,字節(jié)地址為A8H,位地址(由低位到高位)分別是A8H-AFH。 IE用來打開或關(guān)斷各中斷源的中斷請求,基本格式如下圖二所示: EA:全局中斷允許位。EA=0,關(guān)閉全部中斷;EA=1,打開全局中斷控制,在此條件下,由各個(gè)中斷控制位確定相應(yīng)中斷的打開或關(guān)閉。 ×:無效位。 ES:串行I/O中斷允許位。ES=1,打開串行I/O中斷;ES=0,關(guān)閉串行I/O中斷。 ETl;定時(shí)器/計(jì)數(shù)器1中斷允許位。ETl=1,打開T1中斷;ETl=O,關(guān)閉T1中斷。 EXl:外部中斷l(xiāng)中斷允許位。EXl=1,打開INT1;EXl=0,關(guān)閉INT1。 ET0:定時(shí)器/計(jì)數(shù)器0中斷允許位。ET0=1,打開T0中斷;ET0=0,關(guān)閉TO中斷。 EXO:外部中斷0中斷允許位。Ex0=1,打開INT0;EX0=0,關(guān)閉INT0. 中斷優(yōu)先寄存器--IP: IP在特殊功能寄存器中,字節(jié)地址為B8H,位地址(由低位到高位)分別是B8H一BFH,IP用來設(shè)定各個(gè)中斷源屬于兩級中斷中的哪一級,IP的基本格式如下圖三所示: ×:無效位。 PS:串行I/O中斷優(yōu)先級控制位。PS=1,高優(yōu)先級;PS=0,低優(yōu)先級。 PTl:定時(shí)器/計(jì)數(shù)器1中斷優(yōu)先級控制位。PTl=1,高優(yōu)先級;PTl=0,低優(yōu)先級。 Pxl:外部中斷1中斷優(yōu)先級控制位。Pxl=1,高優(yōu)先級;PXl=O,低優(yōu)先級。 PT0:定時(shí)器/計(jì)數(shù)器o中斷優(yōu)先級控制位。PT0=1,高優(yōu)先級;PTO=0,低優(yōu)先級。 Px0:外部中斷0中斷優(yōu)先級控制位。Px0=1,高優(yōu)先級;Px0=0,傷優(yōu)先級。 在MCS-51單片機(jī)系列中,高級中斷能夠打斷低級中斷以形成中斷嵌套;同級中斷之間,或低級對高級中斷則不能形成中斷嵌套。若幾個(gè)同級中斷同時(shí)向CPU請求中斷響應(yīng),則CPU按如下順序確定響應(yīng)的先后順序: INT0一T0---INT1一T1一RI/T1. 中斷的響應(yīng)過程 若某個(gè)中斷源通過編程設(shè)置,處于被打開的狀態(tài),并滿足中斷響應(yīng)的條件,而且①當(dāng)前正在執(zhí)行的那條指令已被執(zhí)行完 1、當(dāng)前末響應(yīng)同級或高級中斷 2、不是在操作IE,IP中斷控制寄存器或執(zhí)行REH指令則單片機(jī)響應(yīng)此中斷。 在正常的情況下,從中斷請求信號有效開始,到中斷得到響應(yīng),通常需要3個(gè)機(jī)器周期到8個(gè)機(jī)器周期。中斷得到響應(yīng)后,自動(dòng)清除中斷請求標(biāo)志(對串行 I/O端口的中斷標(biāo)志,要用軟件清除),將斷點(diǎn)即程序計(jì)數(shù)器之值(PC)壓入堆棧(以備恢復(fù)用);然后把相應(yīng)的中斷入口地址裝入PC,使程序轉(zhuǎn)入到相應(yīng)的 中斷服務(wù)程序中去執(zhí)行。 各個(gè)中斷源在程序存儲(chǔ)器中的中斷入口地址如下: 中斷源 入口地址 INT0(外部中斷0) 0003H TF0(TO中斷) 000BH INT1(外部中斷1) 0013H TFl(T1中斷) 001BH RI/TI(串行口中斷) 0023H 由于各個(gè)中斷入口地址相隔甚近,不便于存放各個(gè)較長的中斷服務(wù)程序,故通常在中斷入口地址開始的二三個(gè)單元中,安排一條轉(zhuǎn)移類指令,以轉(zhuǎn)入到安排在那兒的中斷服務(wù)程序。以T1中斷為例,其過程下如圖四所示。
由于5個(gè)中斷源各有其中斷請求標(biāo)志0,TF0,IEl,TFl以及RI/TI,在中斷源滿足中斷請求的條件下,各標(biāo)志自動(dòng)置1,以向CPU請求中斷。 如果某一中斷源提出中斷請求后,CPU不能立即響應(yīng),只要該中斷請求標(biāo)志不被軟件人為清除,中斷請求的狀態(tài)就將一直保持,直到CPU響應(yīng)了中斷為止,對串 行口中斷而言,這一過程與其它4個(gè)中斷的不同之處在于;即使CPU響應(yīng)了中斷,其中斷標(biāo)志RI/TI也不會(huì)自動(dòng)清零,必須在中斷服務(wù)程序中設(shè)置清除 RI/TI的指令后,才會(huì)再一次地提出中斷請求。
CPU的現(xiàn)場保護(hù)和恢復(fù)必須由被響應(yīng)的相應(yīng)中斷服務(wù)程序去完成,當(dāng)執(zhí)行RETI中斷返回指令后,斷點(diǎn)值自動(dòng)從棧頂2字節(jié)彈出,并裝入PC寄存器,使CPU繼續(xù)執(zhí)行被打斷了的程序。 下面給出一個(gè)應(yīng)用定時(shí)器中斷的實(shí)例。 現(xiàn)要求編制一段程序,使P1.0端口線上輸出周期為2ms的方波脈沖。設(shè)單片機(jī)晶振頻率 Fosc=6MHZ. 1、方法:利用定時(shí)器T0作1ms定時(shí),達(dá)到定時(shí)值后引起中斷,在中斷服務(wù)程序中,使P1.0的狀態(tài)取一次反,并再次定時(shí)1ms。 2、定時(shí)初值:機(jī)器周期MC=12/fosc=2us。所以定時(shí)lms所需的機(jī)器周期個(gè)數(shù)為500D,亦即0lF4H。設(shè)T0為工作方式1(16位方式),則定時(shí)初值是(01F4H)求補(bǔ)=FEOCH 串行端口的控制寄存器: 串行端口共有2個(gè)控制寄存器SCON和PCON,用以設(shè)置串行端口的工作方式、接收/發(fā)送的運(yùn)行狀態(tài)、接收/發(fā)送數(shù)據(jù)的特征、波特率的大小,以及作為運(yùn)行的中斷標(biāo)志等。 ①串行口控制寄存器SCON SCON的字節(jié)地址是98H,位地址(由低位到高位)分別是98H一9FH。SCON的格式如圖五所示。 SMo,SMl: 串行口工作方式控制位。 00--方式0;01--方式1; 10--方式2;11--方式3。 SM2: 僅用于方式2和方式3的多機(jī)通訊控制位 發(fā)送機(jī)SM2=1(要求程控設(shè)置)。 當(dāng)為方式2或方式3時(shí): 接收機(jī) SM2=1時(shí),若RB8=1,可引起串行接收中斷;若RB8=0,不 引起串行接收中斷。SM2=0時(shí),若RB8=1,可引起串行接收中斷;若 RB8=0,亦可引起串行接收中斷。 REN: 串行接收允許位。 0--禁止接收;1--允許接收。 TB8: 在方式2,3中,TB8是發(fā)送機(jī)要發(fā)送的第9位數(shù)據(jù)。 RB8: 在方式2,3中,RB8是接收機(jī)接收到的第9位數(shù)據(jù),該數(shù)據(jù)正好來自發(fā) 送機(jī)的TB8。 TI: 發(fā)送中斷標(biāo)志位。發(fā)送前必須用軟件清零,發(fā)送過程中TI保持零電平, 發(fā)送完一幀數(shù)據(jù)后,由硬件自動(dòng)置1。如要再發(fā)送,必須用軟件再清零。 RI: 接收中斷標(biāo)志位。接收前,必須用軟件清零,接收過程中RI保持零電 平,接收完一幀數(shù)據(jù)后,由片內(nèi)硬件自動(dòng)置1。如要再接收,必須用軟件 再清零。 電源控制寄存器PCON PCON的字節(jié)地址為87H,無位地址,PCON的格式如圖六所示。需指出的是,對80C31單片機(jī)而言,PCON還有幾位有效控制位。 SMOD:波特率加倍位。在計(jì)算串行方式1,2,3的波特率時(shí);0---不加倍;1---加倍。 串行中斷的應(yīng)用特點(diǎn): 8031單片機(jī)的串行I/O端口是一個(gè)中斷源,有兩個(gè)中斷標(biāo)志RI和TI,RI用于接收,TI用于發(fā)送。 串行端口無論在何種工作方式下,發(fā)送/接收前都必須對TI/RI清零。當(dāng)一幀數(shù)據(jù)發(fā)送/接收完后,TI/RI自動(dòng)置1,如要再發(fā)送/接收,必須先用軟件將其清除。 在串行中斷被打開的條件下,對方式0和方式1來說,一幀數(shù)據(jù)發(fā)送/接收完后,除置位TI/RI外,還會(huì)引起串行中斷請求,并執(zhí)行串行中側(cè)目務(wù)程序。但對方式2和方式3的接收機(jī)而言,還要視SM2和RB8的狀態(tài),才可確定RI是否被置位以及串行中斷的開放: SM2 RB8 接收機(jī)中斷標(biāo)志與中斷狀態(tài) 0 1 激活RI,引起中斷 1 0 不激活RI,不引起中斷 1 1 激活RI,引起中斷 單片機(jī)正是利用方式2,3的這一特點(diǎn),實(shí)現(xiàn)多機(jī)間的通信。串行端口的常用應(yīng)用方法見相關(guān)章節(jié)。 波特率的確定: 對方式0來說,波特率已固定成fosc/12,隨著外部晶振的頻率不同,波特率亦不相同。常用的fosc有12MHz和6MHz,所以波特率相應(yīng)為1000×103和500×103位/s。在此方式下,數(shù)據(jù)將自動(dòng)地按固定的波特率發(fā)送/接收,完全不用設(shè)置。 對方式2而言,波特率的計(jì)算式為2SMOD·fosc/64。當(dāng)SMOD=0時(shí),波特率為fm/64;當(dāng)SMOD=1時(shí),波特率為fosc/32。在此方式下,程控設(shè)置SMOD位的狀態(tài)后,波特率就確定了,不需要再作其它設(shè)置。 對方式1和方式3來說,波特率的計(jì)算式為2SMOD/32×T1溢出率,根據(jù)SMOD狀態(tài)位的不同,波特率有Tl/32溢出率和T1/16溢出率兩種。由于T1溢出率的設(shè)置是方便的,因而波特率的選擇將十分靈活。 前已敘及,定時(shí)器Tl有4種工作方式,為了得到其溢出率,而又不必進(jìn)入中斷服務(wù)程序,往往使T1設(shè)置在工作方式2的運(yùn)行狀態(tài),也就是8位自動(dòng)加入時(shí)間常數(shù)的方式。由于在這種方式下,T1的溢出率(次/秒)計(jì)算式可表達(dá)成:
下面一段主程序和中斷服務(wù)程序,是利用串行方式l從數(shù)據(jù)00H開始連續(xù)不斷增大地串行發(fā)送一片數(shù)據(jù)的程序例。設(shè)單片機(jī)晶振的頻率為6MHZ,波特率為1200位/秒。 19、單片機(jī)定時(shí)器、中斷試驗(yàn) 我們在學(xué)單片機(jī)時(shí)我們第一個(gè)例程就是燈的閃爍,那是用延時(shí)程序做的,現(xiàn)在回想起來,這樣做不很恰當(dāng),為什么呢?我們的主程序做了燈的閃爍,就不能再干其它的事了,難道單片機(jī)只能這樣工作嗎?當(dāng)然不是,我們能用定時(shí)器來實(shí)現(xiàn)燈的閃爍的功能。 例1:查詢方式 ORG 0000H AJMP START ORG 30H START: MOV P1,#0FFH ;關(guān)所 燈 MOV TMOD,#00000001B ;定時(shí)/計(jì)數(shù)器0工作于方式1 MOV TH0,#15H MOV TL0,#0A0H ;即數(shù)5536 SETB TR0 ;定時(shí)/計(jì)數(shù)器0開始運(yùn)行 LOOP:JBC TF0,NEXT ;如果TF0等于1,則清TF0并轉(zhuǎn)NEXT處 AJMP LOOP ;不然跳轉(zhuǎn)到LOOP處運(yùn)行 NEXT:CPL P1.0 MOV TH0,#15H MOV TL0,#9FH;重置定時(shí)/計(jì)數(shù)器的初值 AJMP LOOP END AJMP LOOP END 鍵入程序,看到了什么?燈在閃爍了,這可是用定時(shí)器做的,不再是主程序的循環(huán)了。簡單地分析一下程序,為什么用JBC呢?TF0是定時(shí)/計(jì)數(shù)器0的溢 出標(biāo)記位,當(dāng)定時(shí)器產(chǎn)生溢出后,該位由0變1,所以查詢該位就可知宇時(shí)時(shí)間是否已到。該位為1后,要用軟件將標(biāo)記位清0,以便下一次定時(shí)是間到時(shí)該位由0 變1,所以用了JBC指令,該指位在判1轉(zhuǎn)移的同時(shí),還將該位清0。 以上程序是能實(shí)現(xiàn)燈的閃爍了,可是主程序除了讓燈閃爍外,還是不能做其他的事啊!不,不對,我們能在LOOP:……和AJMP LOOP指令之間插入一些指令來做其他的事情,只要保證執(zhí)行這些指令的時(shí)間少于定時(shí)時(shí)間就行了。那我們在用軟件延時(shí)程序的時(shí)候不是也能用一些指令來替代 DJNZ嗎?是的,但是那就要求你精確計(jì)算所用指令的時(shí)間,然后再減去對應(yīng)的DJNZ循環(huán)次數(shù),很不方便,而現(xiàn)在只要求所用指令的時(shí)間少于定時(shí)時(shí)間就行, 顯然要求低了。當(dāng)然,這樣的辦法還是不好,所以我們常用以下的辦法來實(shí)現(xiàn)。 程序2:用中斷實(shí)現(xiàn) ORG 0000H ,http://www.51hei.com AJMP START ORG 000BH ;定時(shí)器0的中斷向量地址 AJMP TIME0 ;跳轉(zhuǎn)到真正的定時(shí)器程序處 ORG 30H START: MOV P1,#0FFH ;關(guān)所 燈 MOV TMOD,#00000001B ;定時(shí)/計(jì)數(shù)器0工作于方式1 MOV TH0,#15H MOV TL0,#0A0H ;即數(shù)5536 SETB EA ;開總中斷允許 SETB ET0 ;開定時(shí)/計(jì)數(shù)器0允許 SETB TR0 ;定時(shí)/計(jì)數(shù)器0開始運(yùn)行 LOOP: AJMP LOOP ;真正工作時(shí),這里可寫任意程序 TIME0: ;定時(shí)器0的中斷處理程序 PUSH ACC PUSH PSW ;將PSW和ACC推入堆棧保護(hù) CPL P1.0 MOV TH0,#15H MOV TL0,#0A0H ;重置定時(shí)常數(shù) POP PSW POP ACC RETI END 上面的例程中,定時(shí)時(shí)間一到,TF0由0變1,就會(huì)引發(fā)中斷,CPU將自動(dòng)轉(zhuǎn)至000B處尋找程序并執(zhí)行,由于留給定時(shí)器中斷的空間只有8個(gè)字節(jié),顯 然不足以寫下所有有中斷處理程序,所以在000B處安排一條跳轉(zhuǎn)指令,轉(zhuǎn)到實(shí)際處理中斷的程序處,這樣,中斷程序能寫在任意地方,也能寫任意長度了。進(jìn)入 定時(shí)中斷后,首先要保存當(dāng)前的一些狀態(tài),程序中只演示了保存存ACC和PSW,實(shí)際工作中應(yīng)該根據(jù)需要將可能會(huì)改變的單元的值都推入堆棧進(jìn)行保護(hù)(本程序 中實(shí)際不需保存護(hù)任何值,這里只作個(gè)演示)。 上面的兩個(gè)單片機(jī)程序運(yùn)行后,我們發(fā)現(xiàn)燈的閃爍非???,根本分辨不出來,只是視覺上感到燈有些晃動(dòng)而已,為什么呢?我們能計(jì)算一下,定時(shí)器中預(yù)置的數(shù) 是5536,所以每計(jì)60000個(gè)脈沖就是定時(shí)時(shí)間到,這60000個(gè)脈沖的時(shí)間是多少呢?我們的晶體震蕩器是12M,所以就是60000微秒,即60毫 秒,因此速度是非??斓?。如果我想實(shí)現(xiàn)一個(gè)1S的定時(shí),該怎么辦呢?在該晶體震蕩器瀕率下,最長的定時(shí)也就是65。536個(gè)毫秒??!上面給出一個(gè)例程。 ORG 0000H AJMP START ORG 000BH ;定時(shí)器0的中斷向量地址 AJMP TIME0 ;跳轉(zhuǎn)到真正的定時(shí)器程序處 ORG 30H START: MOV P1,#0FFH ;關(guān)所 燈 MOV 30H,#00H ;軟件計(jì)數(shù)器預(yù)清0 MOV TMOD,#00000001B ;定時(shí)/計(jì)數(shù)器0工作于方式1 MOV TH0,#3CH MOV TL0,#0B0H ;即數(shù)15536 SETB EA ;開總中斷允許 SETB ET0 ;開定時(shí)/計(jì)數(shù)器0允許 SETB TR0 ;定時(shí)/計(jì)數(shù)器0開始運(yùn)行 LOOP: AJMP LOOP ;真正工作時(shí),這里可寫任意程序 TIME0: ;定時(shí)器0的中斷處理程序 PUSH ACC PUSH PSW ;將PSW和ACC推入堆棧保護(hù) INC 30H MOV A,30H CJNE A,#20,T_RET ;30H單元中的值到了20了嗎? T_L1: CPL P1.0 ;到了,取反P10 MOV 30H,#0 ;清軟件計(jì)數(shù)器 T_RET: MOV TH0,#15H
MOV TL0,#9FH ;重置定時(shí)常數(shù)
POP PSW POP ACC RETI END 先自己分析一下,看看是怎么實(shí)現(xiàn)的?這里采用了軟件計(jì)數(shù)器的概念,思路是這樣的,先用定時(shí)/計(jì)數(shù)器0做一個(gè)50毫秒的定時(shí)器,定時(shí)是間到了以后并不是 立即取反P10,而是將軟件計(jì)數(shù)器中的值加1,如果軟件計(jì)數(shù)器計(jì)到了20,就取反P10,并清掉軟件計(jì)數(shù)器中的值,不然直接返回,這樣,就變成了20次定 時(shí)中斷才取反一次P10,因此定時(shí)時(shí)間就延長了成了20*50即1000毫秒了。 這個(gè)思路在工程中是非常有用的,有的時(shí)候我們需要若干個(gè)定時(shí)器,可51中總共才有2個(gè),怎么辦呢?其實(shí),只要這幾個(gè)定時(shí)的時(shí)間有一定的公約數(shù),我們就 能用軟件定時(shí)器加以實(shí)現(xiàn),如我要實(shí)現(xiàn)P10口所接燈按1S每次,而P11口所接燈按2S每次閃爍,怎么實(shí)現(xiàn)呢?對了我們用兩個(gè)計(jì)數(shù)器,一個(gè)在它計(jì)到20 時(shí),取反P10,并清零,就如上面所示,另一個(gè)計(jì)到40取反P11,然后清0,不就行了嗎?這部份的程序如下 ORG 0000H AJMP START ORG 000BH ;定時(shí)器0的中斷向量地址 AJMP TIME0 ;跳轉(zhuǎn)到真正的定時(shí)器程序處 ORG 30H START: MOV P1,#0FFH ;關(guān)所 燈 MOV 30H,#00H ;軟件計(jì)數(shù)器預(yù)清0 MOV TMOD,#00000001B ;定時(shí)/計(jì)數(shù)器0工作于方式1 MOV TH0,#3CH MOV TL0,#0B0H ;即數(shù)15536 SETB EA ;開總中斷允許 SETB ET0 ;開定時(shí)/計(jì)數(shù)器0允許 SETB TR0 ;定時(shí)/計(jì)數(shù)器0開始運(yùn)行 LOOP: AJMP LOOP ;真正工作時(shí),這里可寫任意程序 TIME0: ;定時(shí)器0的中斷處理程序 PUSH ACC PUSH PSW ;將PSW和ACC推入堆棧保護(hù) INC 30H INC 31H ;兩個(gè)計(jì)數(shù)器都加1 MOV A,30H CJNE A,#20,T_NEXT ;30H單元中的值到了20了嗎? T_L1: CPL P1.0 ;到了,取反P10 MOV 30H,#0 ;清軟件計(jì)數(shù)器 T_NEXT: MOV A,31H CJNE A,#40,T_RET ;31h單元中的值到40了嗎? T_L2: CPL P1.1 MOV 31H,#0 ;到了,取反P11,清計(jì)數(shù)器,返回 T_RET: MOV TH0,#15H MOV TL0,#9FH ;重置定時(shí)常數(shù) POP PSW POP ACC RETI END 您能用定時(shí)器的辦法實(shí)現(xiàn)前面講的流水燈嗎?試試看。 20、單片機(jī)定時(shí)/計(jì)數(shù)器實(shí)驗(yàn) 前面我們做了定時(shí)器的實(shí)驗(yàn),現(xiàn)在來看一看計(jì)數(shù)實(shí)驗(yàn),在工作中計(jì)數(shù)常常會(huì)有兩種要求:第一、將計(jì)數(shù)的值顯示出來,第二、計(jì)數(shù)值到一定程度即中斷報(bào)警。第 一種如各種計(jì)數(shù)器、里程表,第二種如前面例中講到的生產(chǎn)線上的計(jì)數(shù)。先看第一種吧。我們的硬件中是這樣連線的:324組成的振蕩器連到定時(shí)/計(jì)數(shù)器1的外 部管腳T1上面,我們就利用這個(gè)來做一個(gè)計(jì)數(shù)實(shí)驗(yàn),要將計(jì)數(shù)的值顯示出來,當(dāng)然最好用數(shù)碼管了,可我們還沒講到這一部份,為了避免把問題復(fù)雜化,我們用 P1口的8個(gè)LED來顯示計(jì)到的數(shù)據(jù)。 程序如下: ORG 0000H ,http://www.51hei.com AJMP START ORG 30H START: MOV SP,#5FH MOV TMOD,#01000000B ;定時(shí)/計(jì)數(shù)器1作計(jì)數(shù)用,0不用全置0 SETB TR1 ;啟動(dòng)計(jì)數(shù)器1開始運(yùn)行。 LOOP: MOV A,TL0 MOV P1,A AJMP LOOP END 在硬件上用線將324的輸出與T1連通(印板上有焊盤)運(yùn)行這種程序,注意將板按正確的位置放置(LM324放在左手邊,LED排列是按從高位到低們排列)看到什么?隨著324后接的LED的閃爍,單片機(jī)的8只LED也在持續(xù)變化,注意觀察,是不是按二進(jìn)制: 00000000 00000001 00000010 00000011 這樣的次序在變呢?這就對了,這就是TL0中的數(shù)據(jù)。 程序二: ORG 0000H AJMP START ORG 001BH AJMP TIMER1 ;定時(shí)器1的中斷處理 ORG 30H START: MOV SP,#5FH MOV TMOD,#01010000B ;定時(shí)/計(jì)數(shù)器1作計(jì)數(shù)用,模式1,0不用全置0 MOV TH1,#0FFH MOV TL1,#0FAH ;預(yù)置值,要求每計(jì)到6個(gè)脈沖即為一個(gè)事件 SETB EA SETB ET1 ;開總中斷和定時(shí)器1中斷允許 SETB TR1 ;啟動(dòng)計(jì)數(shù)器1開始運(yùn)行。 AJMP $ TIMER1: PUSH ACC PUSH PSW CPL P1.0 ;計(jì)數(shù)值到,即取反P1.0 MOV TH1,#0FFH MOV TL1,#0FAH ;重置計(jì)數(shù)初值 POP PSW POP ACC RETI END 上面這個(gè)單片機(jī)程序完成的工作很簡單,就是在每6個(gè)脈沖到來后取反一次P1。0,因此實(shí)驗(yàn)的結(jié)果應(yīng)當(dāng)是:LM324后接的LED亮、滅6次,則P1。0口所接LED亮或滅一次。這實(shí)際就是我們上面講的計(jì)數(shù)器的第二種應(yīng)用。 程序三:外部中斷實(shí)驗(yàn) ORG 0000H AJMP START 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,因此理論上按一下燈亮,按一下燈滅,但在實(shí)際做實(shí)驗(yàn)時(shí), 可能會(huì)發(fā)覺有時(shí)不“靈”,按了它沒反應(yīng),但在大部份時(shí)候是對的,這是怎么回事呢?我們在講解鍵盤時(shí)再作解釋,這個(gè)程序本身是沒有問題的。 21、單片機(jī)串行口介紹 介紹:串行口是單片機(jī)與外界進(jìn)行信息交換的工具。 8051單片機(jī)的通信方式有兩種: 并行通信:數(shù)據(jù)的各位同時(shí)發(fā)送或接收。 串行通信:數(shù)據(jù)一位一位次序發(fā)送或接收。參看下圖: 串行通信的方式: 異步通信:它用一個(gè)起始位表示字符的開始,用停止位表示字符的結(jié)束。其每幀的格式如下: 在一幀格式中,先是一個(gè)起始位0,然后是8個(gè)數(shù)據(jù)位,規(guī)定低位在前,高位在后,接下來是奇偶校驗(yàn)位(能省略),最后是停止位1。用這種格式表示字符,則字符能一個(gè)接一個(gè)地傳送。 在異步通信中,CPU與外設(shè)之間必須有兩項(xiàng)規(guī)定,即字符格式和波特率。字符格式的規(guī)定是雙方能夠在對同一種0和1的串理解成同一種意義。原則上字符格式能由通信的雙方自由制定,但從通用、方便的角度出發(fā),一般還是使用一些標(biāo)準(zhǔn)為好,如采用ASCII標(biāo)準(zhǔn)。 波特率即數(shù)據(jù)傳送的速率,其定義是每秒鐘傳送的二進(jìn)制數(shù)的位數(shù)。例如,數(shù)據(jù)傳送的速率是120字符/s,而每個(gè)字符如上述規(guī)定包含10數(shù)位,則傳送波特率為1200波特。 同步通信:在同步通信中,每個(gè)字符要用起始位和停止位作為字符開始和結(jié)束的標(biāo)志,占用了時(shí)間;所以在數(shù)據(jù)塊傳遞時(shí),為了提高速度,常去掉這些標(biāo)志,采用同步傳送。由于數(shù)據(jù)塊傳遞開始要用同步字符來指示,同時(shí)要求由時(shí)鐘來實(shí)現(xiàn)發(fā)送端與接收端之間的同步,故硬件較復(fù)雜。 通信方向:在串行通信中,把通信接口只能發(fā)送或接收的單向傳送辦法叫單工傳送;而把數(shù)據(jù)在甲乙兩機(jī)之間的雙向傳遞,稱之為雙工傳送。在雙工傳送方式中又分為半雙工傳送和全雙工傳送。半雙工傳送是兩機(jī)之間不能同時(shí)進(jìn)行發(fā)送和接收,任一時(shí)該,只能發(fā)或者只能收信息。 2.8051單片機(jī)的串行接口結(jié)構(gòu) 8051單片機(jī)串行接口是一個(gè)可編程的全雙工串行通信接口。它可用作異步通信方式(UART),與串行傳送信息的外部設(shè)備相連接,或用于通過標(biāo)準(zhǔn)異步通信協(xié)議進(jìn)行全雙工的8051多機(jī)系統(tǒng)也能通過同步方式,使用TTL或CMOS移位寄存器來擴(kuò)充I/O口。 8051單片機(jī)通過管腳RXD(P3.0,串行數(shù)據(jù)接收端)和管腳TXD(P3.1,串行數(shù)據(jù)發(fā)送端)與外界通信。SBUF是串行口緩沖寄存器,包括 發(fā)送寄存器和接收寄存器。它們有相同名字和地址空間,但不會(huì)出現(xiàn)沖突,因?yàn)樗鼈儍蓚€(gè)一個(gè)只能被CPU讀出數(shù)據(jù),一個(gè)只能被CPU寫入數(shù)據(jù)。 串行口的控制與狀態(tài)寄存器 串行口控制寄存器SCON 它用于定義串行口的工作方式及實(shí)施接收和發(fā)送控制。字節(jié)地址為98H,其各位定義如下表: SM2:多機(jī)通信控制位。在方式0時(shí),SM2一定要等于0。在方式1中,當(dāng)(SM2)=1則只有接收到有效停止位時(shí),RI才置1。在方式2或方式3當(dāng)(SM2)=1且接收到的第九位數(shù)據(jù)RB8=0時(shí),RI才置1。 REN:接收允許控制位。由軟件置位以允許接收,又由軟件清0來禁止接收。 TB8: 是要發(fā)送數(shù)據(jù)的第9位。在方式2或方式3中,要發(fā)送的第9位數(shù)據(jù),根據(jù)需要由軟件置1或清0。例如,可約定作為奇偶校驗(yàn)位,或在多機(jī)通信中作為區(qū)別地址幀或數(shù)據(jù)幀的標(biāo)志位。 RB8:接收到的數(shù)據(jù)的第9位。在方式0中不使用RB8。在方式1中,若(SM2)=0,RB8為接收到的停止位。在方式2或方式3中,RB8為接收到的第9位數(shù)據(jù)。 TI:發(fā)送中斷標(biāo)志。在方式0中,第8位發(fā)送結(jié)束時(shí),由硬件置位。在其它方式的發(fā)送停止位前,由硬件置位。TI置位既表示一幀信息發(fā)送結(jié)束,同時(shí)也是 申請中斷,可根據(jù)需要,用軟件查詢的辦法獲得數(shù)據(jù)已發(fā)送完畢的信息,或用中斷的方式來發(fā)送下一個(gè)數(shù)據(jù)。TI必須用軟件清0。 RI:接收中斷標(biāo)志位。在方式0,當(dāng)接收完第8位數(shù)據(jù)后,由硬件置位。在其它方式中,在接收到停止位的中間時(shí)刻由硬件置位(例外情況見于SM2的說明)。RI置位表示一幀數(shù)據(jù)接收完畢,可用查詢的辦法獲知或者用中斷的辦法獲知。RI也必須用軟件清0。 特殊功能寄存器PCON PCON是為了在CHMOS的80C51單片機(jī)上實(shí)現(xiàn)電源控制而附加的。其中最高位是SMOD。 串行口的工作方式 8051單片機(jī)的全雙工串行口可編程為4種工作方式,現(xiàn)分述如下: 方式0為移位寄存器輸入/輸出方式。可外接移位寄存器以擴(kuò)展I/O口,也能外接同步輸入/輸出設(shè)備。8位串行數(shù)據(jù)者是從RXD輸入或輸出,TXD用來輸出同步脈沖。
輸出 串行數(shù)據(jù)從RXD管腳輸出,TXD管腳輸出移位脈沖。CPU將數(shù)據(jù)寫入發(fā)送寄存器時(shí),立即啟動(dòng)發(fā)送,將8位數(shù)據(jù)以fos/12的固定波特率從RXD輸出,低位在前,高位在后。發(fā)送完一幀數(shù)據(jù)后,發(fā)送中斷標(biāo)志TI由硬件置位。
輸入 當(dāng)串行口以方式0接收時(shí),先置位允許接收控制位REN。此時(shí),RXD為串行數(shù)據(jù)輸入端,TXD仍為同步脈沖移位輸出端。當(dāng)(RI)=0和(REN)=1同時(shí)滿足時(shí),開始接收。當(dāng)接收到第8位數(shù)據(jù)時(shí),將數(shù)據(jù)移入接收寄存器,并由硬件置位RI。
下面兩圖分別是方式0擴(kuò)展輸出和輸入的接線圖。
《單片機(jī)串行口接線圖》
方式1為波特率可變的10位異步通信接口方式。發(fā)送或接收一幀信息,包括1個(gè)起始位0,8個(gè)數(shù)據(jù)位和1個(gè)停止位1。
輸出 當(dāng)CPU執(zhí)行一條指令將數(shù)據(jù)寫入發(fā)送緩沖SBUF時(shí),就啟動(dòng)發(fā)送。串行數(shù)據(jù)從TXD管腳輸出,發(fā)送完一幀數(shù)據(jù)后,就由硬件置位TI。
輸入 在(REN)=1時(shí),串行口采樣RXD管腳,當(dāng)采樣到1至0的跳變時(shí),確認(rèn)是開始位0,就開始接收一幀數(shù)據(jù)。只有當(dāng)(RI)=0且停止位為1或者 (SM2)=0時(shí),停止位才進(jìn)入RB8,8位數(shù)據(jù)才能進(jìn)入接收寄存器,并由硬件置位中斷標(biāo)志RI;不然信息丟失。所以在方式1接收時(shí),應(yīng)先用軟件清零RI 和SM2標(biāo)志。
方式2
方式月為固定波特率的11位UART方式。它比方式1增加了一位可程控為1或0的第9位數(shù)據(jù)。
輸出: 發(fā)送的串行數(shù)據(jù)由TXD端輸出一幀信息為11位,附加的第9位來自SCON寄存器的TB8位,用軟件置位或復(fù)位。它可作為多機(jī)通信中地址/數(shù)據(jù)信息的標(biāo)志 位,也能作為數(shù)據(jù)的奇偶校驗(yàn)位。當(dāng)CPU執(zhí)行一條數(shù)據(jù)寫入SUBF的指令時(shí),就啟動(dòng)發(fā)送器發(fā)送。發(fā)送一幀信息后,置位中斷標(biāo)志TI。
輸入: 在(REN)=1時(shí),串行口采樣RXD管腳,當(dāng)采樣到1至0的跳變時(shí),確認(rèn)是開始位0,就開始接收一幀數(shù)據(jù)。在接收到附加的第9位數(shù)據(jù)后,當(dāng)(RI)=0 或者(SM2)=0時(shí),第9位數(shù)據(jù)才進(jìn)入RB8,8位數(shù)據(jù)才能進(jìn)入接收寄存器,并由硬件置位中斷標(biāo)志RI;不然信息丟失。且不置位RI。再過一位時(shí)間后, 不管上述條件時(shí)否滿足,接收電路即行復(fù)位,并重新檢測RXD上從1到0的跳變。
工作方式3
方式3為波特率可變的11位UART方式。除波特率外,其余與方式2相同。
波特率選擇
如前所述,在串行通信中,收發(fā)雙方的數(shù)據(jù)傳送率(波特率)要有一定的約定。在8051串行口的四種工作方式中,方式0和2的波特率是固定的,而方式1和3的波特率是可變的,由定時(shí)器T1的溢出率控制。
方式0
方式0的波特率固定為主振頻率的1/12。
方式2
方式2的波特率由PCON中的選擇位SMOD來決定,可由下式表示:
波特率=2的SMOD次方除以64再乘一個(gè)fosc,也就是當(dāng)SMOD=1時(shí),波特率為1/32fosc,當(dāng)SMOD=0時(shí),波特率為1/64fosc
3.方式1和方式3
定時(shí)器T1作為波特率發(fā)生器,其公式如下:
波特率=定時(shí)器T1溢出率
T1溢出率= T1計(jì)數(shù)率/產(chǎn)生溢出所需的周期數(shù)
式中T1計(jì)數(shù)率取決于它工作在定時(shí)器狀態(tài)還是計(jì)數(shù)器狀態(tài)。當(dāng)工作于定時(shí)器狀態(tài)時(shí),T1計(jì)數(shù)率為fosc/12;當(dāng)工作于計(jì)數(shù)器狀態(tài)時(shí),T1計(jì)數(shù)率為外部輸入頻率,此頻率應(yīng)小于fosc/24。產(chǎn)生溢出所需周期與定時(shí)器T1的工作方式、T1的預(yù)置值有關(guān)。
定時(shí)器T1工作于方式0:溢出所需周期數(shù)=8192-x
定時(shí)器T1工作于方式1:溢出所需周期數(shù)=65536-x
定時(shí)器T1工作于方式2:溢出所需周期數(shù)=256-x
因?yàn)榉绞?為自動(dòng)重裝入初值的8位定時(shí)器/計(jì)數(shù)器模式,所以用它來做波特率發(fā)生器最恰當(dāng)。
當(dāng)時(shí)鐘頻率選用11.0592MHZ時(shí),取易獲得標(biāo)準(zhǔn)的波特率,所以很多單片機(jī)系統(tǒng)選用這個(gè)看起來“怪”的晶體震蕩器就是這個(gè)道理。
下表列出了定時(shí)器T1工作于方式2常用波特率及初值。
電度表相關(guān)文章:電度表原理
評論