<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

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

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

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

本文引用地址:http://dyxdggzs.com/article/201611/315889.htm

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

二、實(shí)驗目的

掌握內部定時(shí)/計數器的作定時(shí)功能(模式1)的應用

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

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

1、定時(shí)器的結構:

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

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

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

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


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

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

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

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

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

4、計數初值的計算

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

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

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

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

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

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

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


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

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

四、程序流程圖:

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

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

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

time0:inc r1 ;查表求燈光,輸出到p0口,詳細解釋見(jià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īng)溢出,所以需要重設計數初值
mov tl0,#0b0h
reti

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

六、幾點(diǎn)說(shuō)明
我們來(lái)看看T0初始化的語(yǔ)句mov tmod,#01h,現在我們把tmod的各位功能詳細說(shuō)明一下。

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

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

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

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

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

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

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

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

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

inc r1 ;查表求燈光,詳細解釋見(jiàn)試驗5“多位數碼顯示”
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 ;計數器加1
mov th0,#3ch ;重置計數初值
mov tl0,#0b0h
reti ;中斷返回

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

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

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



關(guān)鍵詞: 單片機定時(shí)器模式

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>