<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)學(xué)習(xí)之十四:定時(shí)器應(yīng)用(模式1)

          單片機(jī)學(xué)習(xí)之十四:定時(shí)器應(yīng)用(模式1)

          作者: 時(shí)間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
          一、實(shí)驗(yàn)現(xiàn)象:

          本文引用地址:http://www.ex-cimer.com/article/201611/315889.htm

          開機(jī)后程序作如下的燈光變換:第一次led0、led2亮;第二次led1、led3亮;第三次led4、led6亮;第四次led5、led7亮;第五次led0、led2、led4、led6亮;第六次led1、led3、led5、led7亮;第七次8個(gè)二極管全亮;第八次8個(gè)二極管全滅。然后重頭開始循環(huán)。每次狀態(tài)轉(zhuǎn)換間隔時(shí)間是50ms。

          二、實(shí)驗(yàn)?zāi)康?/p>

          掌握內(nèi)部定時(shí)/計(jì)數(shù)器的作定時(shí)功能(模式1)的應(yīng)用

          三、實(shí)驗(yàn)任務(wù)分析:

          看到這個(gè)實(shí)驗(yàn)題目,大家可能會(huì)說,這個(gè)試驗(yàn)難度不大,我們只要把這幾種燈光對(duì)應(yīng)的輸出存到一個(gè)表里面,然后查表就可以啦,燈光轉(zhuǎn)換之間調(diào)用50ms的延時(shí)程序即可。 這樣的思路當(dāng)然可以,但是,如果這樣作,我們就沒有必要寫這個(gè)試驗(yàn)啦。今天,我們要老瓶裝新酒,看看這個(gè)50ms的定時(shí)時(shí)間除了用延時(shí)程序完成,還有沒有別的方法。以前的定時(shí),我們常常采用延時(shí)程序來完成。其實(shí)這種方法不是很完美,由于程序的指令中還包含其他的判斷指令,所以延時(shí)程序作定時(shí)不是非常精確。由于日常的電子系統(tǒng)常常需要定時(shí)和計(jì)數(shù)的功能,所以MCS-51單片機(jī)內(nèi)部就自帶了兩個(gè)16位的寄存器,用來作定時(shí)/計(jì)數(shù)器,我們給它們起了名字,T0、T1。(我們的AT89S52里面有3個(gè)定時(shí)器,一般的程序兩個(gè)就夠啦,我們先介紹這兩個(gè)吧。)
          現(xiàn)在就來學(xué)習(xí)這兩個(gè)定時(shí)/計(jì)數(shù)器的用法。這個(gè)試驗(yàn)的實(shí)質(zhì),就是利用自帶的定時(shí)/計(jì)數(shù)器來產(chǎn)生50ms的定時(shí)。
          先來看看這兩個(gè)定時(shí)/計(jì)數(shù)器的結(jié)構(gòu)吧,如下圖所示。

          1、定時(shí)器的結(jié)構(gòu):

          從圖上可以看出,定時(shí)/計(jì)數(shù)器的核心是一個(gè)加1計(jì)數(shù)器(注:16位,計(jì)數(shù)范圍從0000h~ffffh),根據(jù)K0開關(guān)的不同方向,這個(gè)計(jì)數(shù)器可以對(duì)兩個(gè)脈沖來源計(jì)數(shù),一個(gè)是系統(tǒng)的時(shí)鐘振蕩器,另外一個(gè)是外部的脈沖源。

          2、定時(shí)器的工作方式

          當(dāng)計(jì)數(shù)器對(duì)系統(tǒng)時(shí)鐘脈沖計(jì)數(shù)的時(shí)候,由于系統(tǒng)時(shí)鐘是一個(gè)時(shí)間基準(zhǔn),所以脈沖數(shù)×脈沖周期就是一段固定時(shí)間,因此工作于定時(shí)方式;當(dāng)計(jì)數(shù)器對(duì)外部的脈沖進(jìn)行計(jì)數(shù)的時(shí)候(也就是對(duì)TX端計(jì)數(shù),TX端我們用到的時(shí)候再解釋吧),就可用于對(duì)外部事件計(jì)數(shù),工作于計(jì)數(shù)方式。我們這個(gè)試驗(yàn)要產(chǎn)生50ms的定時(shí),用的是定時(shí)功能,在后面的試驗(yàn)里我們還要作計(jì)數(shù)功能的試驗(yàn)。

          我們發(fā)現(xiàn),當(dāng)k0向上打的時(shí)候,工作于定時(shí)方式,向下打的時(shí)候工作于計(jì)數(shù)方式。那么k0又是由什么控制的呢?
          K0是一位模擬開關(guān),方向受 這一位的控制,當(dāng) =0時(shí),K0向上,工作于定時(shí)方式;當(dāng) =1時(shí),K0向下,工作于計(jì)數(shù)方式。(注:數(shù)電教材的《AD轉(zhuǎn)換》一章有模擬開關(guān)的原理,大家可以查閱),
          那么, 又是什么呢,它是特殊功能寄存器tmod中的一位。tmod是用來控制定時(shí)/計(jì)數(shù)器的工作方式的,是一個(gè)8位的寄存器,它的各位情況如下圖所示:


          (注:tmod是我們又新接觸的一個(gè)特殊功能寄存器,和別的特殊功能寄存器一樣,在內(nèi)部RAM的特殊功能寄存器區(qū)。)
          看到了吧, 是tmod寄存器的D2和D6位,所以,如果我們想讓T0工作于定時(shí)方式,就應(yīng)該把D2置0;如果要讓T0工作于計(jì)數(shù)方式,就應(yīng)該把D2置1。對(duì)T1的控制也是一樣的。
          注意,在這里我要特別說明一點(diǎn),我們不能用setb指令給tmod的某一位置1,也不能用clr指令給某一位置0。為什么呢?記得我們以前對(duì)ie寄存器可以這樣作:setb ea(開中斷),clr ea(關(guān)中斷),那么tmod寄存器為什么不行呢?
          這是因?yàn)閠mod寄存器是不能夠“位尋址”的,也就是說,我們不能單獨(dú)的對(duì)其中一位進(jìn)行操作,而必須對(duì)整個(gè)寄存器進(jìn)行賦值。而以前我們學(xué)過的ie、psw、tcon、acc這幾個(gè)特殊功能寄存器卻是可以“位尋址”的。具體的哪些寄存器可以位尋址,而哪些寄存器不行,大家可以參照相關(guān)教材,有很詳細(xì)的說明。
          再看一下k1,它也是一個(gè)模擬開關(guān),當(dāng)與門輸出是1的時(shí)候,開關(guān)閉合,啟動(dòng)計(jì)數(shù)器;當(dāng)與門輸出是0的時(shí)候,開關(guān)打開,計(jì)數(shù)器停止。至于它如何控制我們稍后介紹。

          3、定時(shí)時(shí)間的計(jì)算

          好啦,知道了怎樣選擇定時(shí)還是計(jì)數(shù)方式,我們就要考慮一下定時(shí)時(shí)間的計(jì)算了。要計(jì)算定時(shí)時(shí)間,我們就要知道計(jì)數(shù)器的輸入脈沖周期是多少。實(shí)際上,計(jì)數(shù)器是對(duì)機(jī)器周期計(jì)數(shù)的,而我們也知道,1個(gè)機(jī)器周期=12×振蕩周期,所以,計(jì)數(shù)器的輸入脈沖周期是:12×(1/12MHZ)=1us。

          可見,要產(chǎn)生50ms的定時(shí),只要計(jì)數(shù)器記50000個(gè)脈沖就可以啦。那么,怎樣讓計(jì)數(shù)器在記入了50000個(gè)脈沖后,向單片機(jī)發(fā)出一個(gè)消息,表示定時(shí)時(shí)間到呢?這就要用到我們以前學(xué)習(xí)過的概念-中斷啦。我們以前說過,單片機(jī)有5個(gè)中斷源,兩個(gè)是外部中斷 和 ,兩個(gè)是T0和T1的溢出中斷,還有一個(gè)是串行口中斷。我們以前用過外部中斷 ,這個(gè)試驗(yàn)我們要用到T0的溢出中斷。

          16位的計(jì)數(shù)器從0開始,記入216=65536個(gè)脈沖的時(shí)候,會(huì)向外面產(chǎn)生溢出,這個(gè)溢出把TFX置一,(注:TF0是T0的溢出中斷標(biāo)志,TF1是T1的溢出中斷標(biāo)志),從而向CPU申請(qǐng)中斷,在進(jìn)入中斷處理程序后,由硬件對(duì)TFX清0,不需要我們操作。(注:順便說一下TF0和TF1,它是我們以前接觸過的tcon特殊功能寄存器中的兩位,tcon是一個(gè)可以“位尋址”的特殊功能寄存器,我們?cè)谠囼?yàn)七中用這個(gè)寄存器設(shè)置過外部中斷的觸發(fā)方式,想不起來的話,回頭看看前面的實(shí)驗(yàn)吧。)

          4、計(jì)數(shù)初值的計(jì)算

          繼續(xù)剛才的問題,16位的計(jì)數(shù)器要記入65536個(gè)脈沖才會(huì)產(chǎn)生溢出中斷,那么怎樣讓它在記入50000個(gè)脈沖后產(chǎn)生中斷呢?這就要用到我們?cè)跀?shù)電中間學(xué)習(xí)過的內(nèi)容啦。我們可以給計(jì)數(shù)器置一個(gè)初值65536-50000=15536,這樣計(jì)數(shù)器在記入50000個(gè)脈沖之后就會(huì)產(chǎn)生溢出中斷了。

          那么,怎樣給計(jì)數(shù)器置初值呢?T0和T1是兩個(gè)16位的計(jì)數(shù)器,我們可以把它們分為高8位THX和低8位TLX。Cpu和T0、T1之間的關(guān)系如下圖所示(注:其中,P3.4和P3.5用作第二功能,是工作于計(jì)數(shù)方式的時(shí)候,外部的計(jì)數(shù)脈沖輸入,也就是定時(shí)/計(jì)數(shù)器結(jié)構(gòu)圖10-1中的TX端。)

          我們以T0為例,要給它置入初值15536,就要對(duì)高8位的TH0和低8位的TL0分別置數(shù)。15536變換成16進(jìn)制的數(shù)是3CB0(注:轉(zhuǎn)換方法可以查閱數(shù)電教材《進(jìn)制轉(zhuǎn)換》一章),所以我們就這樣給T0置初值:mov th0,#3ch ;mov tl0,#0b0h,就可以啦。

          5、計(jì)數(shù)器的啟動(dòng)和停止

          在給T0置入初值之后,并且在允許T0溢出中斷(注:由IE寄存器中的ET0控制,詳細(xì)說明可見試驗(yàn)7),和cpu開啟中斷的前提下,我們就要啟動(dòng)T0開始定時(shí)了。我們前面說過T0的啟動(dòng)和停止是由圖10-1中與門的輸出決定的。當(dāng)與門輸出是1的時(shí)候,T0啟動(dòng);當(dāng)與門輸出是0的時(shí)候,T0停止。
          那么什么時(shí)候與門輸出是1呢?從圖上可知有兩種情況。
          (1)、當(dāng)gate=0時(shí),只需要tr0=1,即可啟動(dòng)T0計(jì)數(shù)
          (2)、當(dāng)gate=1,并且tr0=1的時(shí)候,還需要int0=1才能啟動(dòng)T0計(jì)數(shù)

          在該試驗(yàn)中,我們用到第一種情況,也就是我們把gate賦值0,然后通過對(duì)tr0的置1和置0來啟動(dòng)和停止計(jì)數(shù)器。這是一種常用的方式,至于第二種方式,我們以后通過試驗(yàn)給大家分析它們之間的不同。

          Gate在哪里呢?大家再看看上面給出的tmod寄存器圖,就是d3和d7位。所以我們?cè)趯?duì)T0初始化的時(shí)候,要給d3賦值0。至于d4~d7都和T0沒有關(guān)系,可以是任何狀態(tài)。
          再說說tr0的問題,它也是tcon寄存器中的一位,它的各位功能如下圖所示,我們把用到的作個(gè)簡(jiǎn)單介紹。


          1、TF0:T0的溢出中斷,當(dāng)T0溢出的時(shí)候由硬件置位,在進(jìn)入中斷服務(wù)程序后,由硬件清0,不用我們操作;TF1類似。(注:如果我們采用查詢方式,通過查詢TFx的狀態(tài)判斷是否到達(dá)定時(shí),而不進(jìn)入中斷服務(wù)程序,那就要對(duì)這1位用軟件清0啦!可不要忘啦!)
          TR0:當(dāng)gate=0時(shí),置一啟動(dòng)T0計(jì)數(shù),置0停止T0計(jì)數(shù);TR1類似

          好啦,現(xiàn)在基本上分析清楚了,我們來看看主程序和中斷服務(wù)程序的流程圖吧。

          四、程序流程圖:

          五、實(shí)驗(yàn)程序
          (注意:在作這個(gè)試驗(yàn)的時(shí)候,不要忘了把JMP0跳線置于1、2的位置,選擇二極管顯示單元)
          org 0000h
          ajmp main

          org 000bh ;T0溢出中斷入口地址
          ajmp time0

          org 0020h
          main: clr p1.5
          mov r1,#0ffh
          mov sp,#70h ;設(shè)置堆棧
          mov tmod,#01h ;T0初始化,工作于定時(shí)方式,詳細(xì)解釋見注釋
          mov th0,#3ch ;T0置計(jì)數(shù)初值
          mov tl0,#0b0h
          setb et0 ;允許T0溢出中斷
          setb ea ;cpu開中斷
          setb tr0 ;啟動(dòng)T0計(jì)數(shù)
          ajmp $ ;等待

          time0:inc r1 ;查表求燈光,輸出到p0口,詳細(xì)解釋見多位數(shù)碼顯示試驗(yàn)
          mov a,r1
          mov dptr,#tab
          movc a,@a+dptr
          mov p0,a
          cjne a,#0ffh,next
          mov r1,#0ffh
          next: mov th0,#3ch ;由于計(jì)數(shù)器已經(jīng)溢出,所以需要重設(shè)計(jì)數(shù)初值
          mov tl0,#0b0h
          reti

          tab: db 0fah,0f5h,0afh,05fh ;按順序存儲(chǔ)燈光的表格
          db 0aah,55h,00h,0ffh
          end

          六、幾點(diǎn)說明
          我們來看看T0初始化的語句mov tmod,#01h,現(xiàn)在我們把tmod的各位功能詳細(xì)說明一下。

          (1) d2是定時(shí)/計(jì)數(shù)方式選擇,這里應(yīng)該把d2置0,選擇T0工作于定時(shí)方式
          (2)d3也應(yīng)該置0,這樣通過控制tr0即可啟動(dòng)T0
          (3)d1d0(M1M0)用來指明T0的位數(shù),說明如下:
          M1M0=00:13位的計(jì)數(shù)器;
          M1M0=01:16位計(jì)數(shù)器;
          M1M0=10:可自動(dòng)再裝入的8位計(jì)數(shù)器
          M1M0=11:把定時(shí)器0分成兩個(gè)8位的計(jì)數(shù)器,或者關(guān)閉定時(shí)器1

          (2) 在這個(gè)試驗(yàn)中,由于定時(shí)50ms需要16位的計(jì)數(shù)器,故d1d0=01
          從上面的分析可見,我們給tmod可以賦值:XXXX0001,可以是01h,也可以是0f1h,大家隨便吧。

          現(xiàn)在把這個(gè)程序下載到學(xué)習(xí)板上,看看效果吧。我們發(fā)現(xiàn),燈光變換的速度太快啦,幾乎沒有辦法看清楚,原因很簡(jiǎn)單,因?yàn)?0ms的定時(shí)太短了。16位的計(jì)數(shù)器定時(shí)最多能夠達(dá)到65.536ms,那么如果我們需要更長(zhǎng)時(shí)間的定時(shí),比如仍然是剛才的試驗(yàn),但是時(shí)間要求是1s,該怎么辦呢?

          其實(shí)也很簡(jiǎn)單,我們?cè)O(shè)一個(gè)計(jì)數(shù)器,初值是0,每次T0溢出中斷的時(shí)候,給這個(gè)計(jì)數(shù)器加一。在主程序里,我們反復(fù)檢測(cè)這個(gè)計(jì)數(shù)器的值,達(dá)到20的時(shí)候調(diào)用燈光子程序就可以啦。
          下面就是這個(gè)定時(shí)1s的程序,其中,我們用r2作這個(gè)計(jì)數(shù)器。
          org 0000h
          ajmp main

          org 000bh ;T0溢出中斷入口地址·
          ajmp time0

          org 0020h
          main: clr p1.5
          mov r1,#0ffh
          mov r2,#00h ;給計(jì)數(shù)器r2賦初值0

          mov sp,#70h ;設(shè)置堆棧
          mov tmod,#01h ;設(shè)置T0工作方式
          mov th0,#3ch ;T0置計(jì)數(shù)初值
          mov tl0,#0b0h
          setb et0 ;允許T0溢出中斷
          setb ea ;cpu開中斷
          setb tr0 ;啟動(dòng)T0開始計(jì)數(shù)

          wait: cjne r2,#20,wait ;定時(shí)時(shí)間未到,繼續(xù)查詢等待
          acall light ;定時(shí)時(shí)間到,調(diào)用查表求燈光子程序
          ajmp wait

          ;以下是查表求燈光子程序
          light: mov r2,#00h ;計(jì)數(shù)器重新賦初值

          inc r1 ;查表求燈光,詳細(xì)解釋見試驗(yàn)5“多位數(shù)碼顯示”
          mov a,r1
          mov dptr,#tab
          movc a,@a+dptr
          mov p0,a
          cjne a,#0ffh,next
          mov r1,#0ffh
          next: ret ;子程序返回

          ;以下是中斷服務(wù)程序
          time0: inc r2 ;計(jì)數(shù)器加1
          mov th0,#3ch ;重置計(jì)數(shù)初值
          mov tl0,#0b0h
          reti ;中斷返回

          tab: db 0fah,0f5h,0afh,05fh ;燈光變換表格
          db 0aah,55h,00h,0ffh
          end

          好啦,把這個(gè)程序下載到學(xué)習(xí)板上,就會(huì)很清楚的看到燈光的變換方式啦。

          在這個(gè)試驗(yàn)里面,由于我們的定時(shí)時(shí)間較長(zhǎng),所以采用了16位的計(jì)數(shù)器,假如定時(shí)時(shí)間短的話,定時(shí)/計(jì)數(shù)器還可以采用別的工作方式,例如13位,或者8位等。



          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();