單片機(jī)學(xué)習(xí)之十一:中斷方式按鍵
1、 實驗現(xiàn)象
本文引用地址:http://butianyuan.cn/article/201609/310467.htm最右面的數(shù)碼管初始顯示0,每次按下外部按鍵K0執(zhí)行加一,計數(shù)到九時重新回零。
2、 實驗?zāi)康?/p>
掌握中斷方式響應(yīng)按鍵的原理
掌握中斷服務(wù)程序的具體編寫:如何進(jìn)行鍵的識別,如何去抖動
3、 實驗任務(wù)分析
上一個試驗我們了解了查詢方式按鍵的原理。當(dāng)單片機(jī)工作于查詢方式的時候,要不間斷的對外部按鍵進(jìn)行查詢,其間單片機(jī)不能干其他的任何工作。如果單片機(jī)的工作量較大,這種方式就很難適應(yīng)。
為了進(jìn)一步提高單片機(jī)的工作效率,可以采用中斷方式。
中斷方式的按鍵響應(yīng)過程如下:單片機(jī)處理自己的工作,如果有按鍵按下,向單片機(jī)發(fā)出中斷請求,單片機(jī)就會停下現(xiàn)在正在處理的工作,轉(zhuǎn)去執(zhí)行中斷程序,執(zhí)行之后回來繼續(xù)剛才的工作;如果沒有按鍵按下,單片機(jī)就作自己的工作,不理睬外部鍵盤。
怎樣向單片機(jī)發(fā)出中斷請求呢?發(fā)出中斷請求的來源叫做中斷源。單片機(jī)可提供五個中斷源。其中2個為外部中斷請求INT0和INT1,2個為片內(nèi)定時/計數(shù)器T0和T1的計滿溢出中斷,還有一個是片內(nèi)串行口中斷請求TI或者RI。在本試驗中,我們用到的是外部中斷INT1。
還是先看看電路吧。(注意在作中斷試驗之前,我們必須先把JMP4跳線插上,這樣按鍵動作才能發(fā)出中斷請求。)
我們在試驗一中曾經(jīng)給大家介紹過,單片機(jī)的P3口是雙功能口,第一種功能可以作通用的I/O口。而在本試驗中,我們要用到P3口的第二功能。大家看P3.2和P3.3兩個引腳,斜線后面標(biāo)示的就是P3口的第二功能,分別是INT0和INT1,也就是單片機(jī)的兩個外部中斷源。
我們發(fā)現(xiàn),當(dāng)任何一個按鍵按下的時候,P3.3引腳,即INT1上就會出現(xiàn)一個低電平,向單片機(jī)發(fā)出中斷申請。如果單片機(jī)開放了外部中斷,就響應(yīng)中斷請求,進(jìn)入中斷服務(wù)程序。
那么單片機(jī)是否開放中斷功能是由什么控制的呢?在這里就涉及到另外一個特殊功能寄存器IE啦。還記得單片機(jī)內(nèi)部256字節(jié)的數(shù)據(jù)RAM嗎?其中高128字節(jié)(80h~ffh)是特殊功能寄存器區(qū)。以前我們介紹過PSW就在這個區(qū)域,同樣IE也在這個區(qū)域,它的名字叫做“中斷允許寄存器”,專門負(fù)責(zé)程序是否響應(yīng)中斷的,它的各位功能說明如下:
EA:CPU中斷允許標(biāo)志。EA=0,CPU禁止各種中斷;EA=1,CPU開放中斷。但是,每個中斷源的中斷請求是否允許,還需要由各自的允許位決定。所以在本程序中,大家不要忘了首先把EA置1哦!
ES:串行口允許中斷。ES=1,允許串行口中斷;ES=0,禁止串行口中斷。所以,在這個程序中,這一位和我們沒有關(guān)系,不理它就是啦。
ET1:定時器/計數(shù)器T1的溢出中斷允許。ET1=1時,允許T1溢出中斷;ET1=0時,禁止T1溢出中斷。同樣,這一位和我們也沒有關(guān)系。
EX1:外部中斷1(即INT1)允許中斷。當(dāng)EX1=1時,允許INT1中斷;當(dāng)EX1=0時,禁止INT1中斷??梢?,這一位的值和我們這個試驗密切相關(guān),所以大家千萬不要忘了把這一位置1。
下面的ET0和EX0的功能與ET1和EX1類似,是分別控制定時器T0和外部中斷INT0的,這里就不再贅述啦。
在前面分析時,我們發(fā)現(xiàn),四個按鍵中任何一個按下,都會發(fā)出中斷請求。那么,如何判斷中斷請求是由那個按鍵發(fā)出的呢?這就是中斷服務(wù)程序的工作了。在中斷服務(wù)程序中,需要完成如下工作:鍵識別、去抖動、和鍵功能處理。
那么,鍵識別是如何完成的呢?它的思路是這樣的。
(1)、先把P1口的狀態(tài)讀入a寄存器,然后把高四位屏蔽掉
(2)、判斷是否k0按鍵按下,(即判斷a中的數(shù)是否00001101),如果是就調(diào)用延時程序去抖,否則,表示不是K0按下,退出中斷返回主程序
(3)、調(diào)用延時程序后,重復(fù)上面的(1)(2)步。如果確定k0按下,轉(zhuǎn)中斷服務(wù)程序,否則就是抖動,退出中斷返回主程序。
在這里還需要說明一點:在進(jìn)入中斷服務(wù)程序之后,我們首先應(yīng)該關(guān)閉中斷,因為如果不關(guān)閉中斷,就有可能會引起混亂。在中斷服務(wù)程序返回主程序之前,再把中斷打開。
4、實驗程序
org 0000h
ljmp start ;(1)為什么這里要放一條跳轉(zhuǎn)指令呢,我們在后面解釋把
org 0013h
ljmp ext1 ;(2)同上
org 0030h
start: clr p1.5 ;主程序開始
mov r7,#0ffh
setb ea ;cpu開放中斷
setb ex1 ;允許外部中斷1申請中斷
setb it1 ;(3)設(shè)置外部中斷1觸發(fā)方式為跳變觸發(fā),原因在后面詳細(xì)解釋
lcall play1 ;調(diào)用初始狀態(tài)顯示子程序
ajmp $ ;等待按鍵發(fā)出中斷申請
ext1: clr ea ;進(jìn)入中斷,先關(guān)閉中斷
lcall key_reader ;調(diào)用鍵識別子程序
pass: setb ea ;返回主程序之前先開中斷
reti ;(4)中斷返回指令,
key_reader: mov a,p1 ;讀入P1口的狀態(tài)
anl a,#0fh ;屏蔽高四位
cjne a,#0dh,pass;如果a的內(nèi)容不是00001101(表示不是k0按下),就退出中斷
lcall del10ms ;否則,表示k0按下,調(diào)用10ms延時去抖
mov a,p1 ;再次讀入p1口的內(nèi)容
anl a,#0fh ;屏蔽高四位
cjne a,#0dh,pass ;如果a的內(nèi)容不是00001101,就是抖動,退出中斷
lcall play2 ;否則,確定按鍵按下,轉(zhuǎn)數(shù)碼顯示程序
ret
play1: mov a,#48h ;讓最右面的數(shù)碼管顯示0的子程序
mov p0,a
mov p2,#01h;
ret
play2: inc r7 ;查表求段碼,然后送到P0口的子程序,大家很熟了
mov a,r7
mov dptr,#tab
movc a,@a+dptr
mov p0,a
mov p2,#01h
cjne a,#48h,next;如果沒有顯示到最后一個數(shù)字0,就繼續(xù)查表顯示
mov r7,#0ffh ;否則,重新從表頭開始顯示
next: ret
del10ms: mov r5,#10 ;延時10ms子程序
del1: mov r4,#02h
del2: mov r3,#0ffh
del3: djnz r3,del3
djnz r4,del2
djnz r5,del1
ret
tab: db 0ebh,52h,62h,0e1h,64h,44h,0eah,40h,60h,48h ;存放0~9的段碼表
end
相信通過上面的詳細(xì)注釋,大家基本上已經(jīng)看懂這個程序了。下面我就幾個小問題再給大家作一些解釋。
5、注釋
1、先看(1)語句,我們發(fā)現(xiàn)程序開始的時候,在地址為0000h的地方,放了一條跳轉(zhuǎn)指令。主程序是從程序存儲器中0030h的地方開始存放的,為什么要把前面的空間空出來呢?這是因為前面的空間我們是有用處的。
由于不同類型的中斷,具有不同的中斷入口地址。CPU在響應(yīng)中斷的時候,會根據(jù)中斷源的類別,轉(zhuǎn)到相應(yīng)的入口去執(zhí)行中斷服務(wù)程序。外部中斷1的入口地址是0013h(其余4個中斷的入口地址大家可以查閱相關(guān)資料),那么cpu在響應(yīng)了外部中斷1后,會自動的到這個地址來,從這個地址開始往下執(zhí)行程序。所以我們要把前面的一段空出來,以免覆蓋這個地址。
2、再看看(2)語句,它在中斷1的入口處放了一個跳轉(zhuǎn)指令,所以,cpu在響應(yīng)外部中斷后,會到這個入口處往下執(zhí)行程序。于是CPU就會從這里轉(zhuǎn)去中斷服務(wù)程序。大家可能會說,為什么要跳轉(zhuǎn),直接從這里開始存放中斷服務(wù)程序 不就可以了嘛。
由于我們很難預(yù)料中斷服務(wù)程序的長度,所以我們就拿不準(zhǔn)主程序應(yīng)該從什么單元開始存放。這樣就容易造成整個程序的結(jié)構(gòu)混亂。
所以還是采用上面的方法吧,看起來結(jié)構(gòu)清楚規(guī)范,容易理解。
3、(3)語句的意思是設(shè)置外部中斷1為跳變方式觸發(fā)。大家可能覺得,當(dāng)K0按下的時候,INT1上會出現(xiàn)一個低電平,為什么不能采用電平方式觸發(fā)呢?解釋如下:當(dāng)我們選外部中斷為電平方式觸發(fā)的時候,當(dāng)INT1輸入低電平的時候,cpu響應(yīng)中斷。在中斷返回之前,INT1必須回到高電平,否則就會第二次產(chǎn)生中斷。所以,如果我們按下按鍵的時間較長,就會產(chǎn)生多次的中斷,導(dǎo)致程序混亂。所以我們在這里要采用邊沿方式觸發(fā)。
順便說說it1,它是外部中斷觸發(fā)方式控制位,為1的時候選擇跳變方式觸發(fā),為0的時候選擇電平方式觸發(fā)。那么它在哪里呢?
it1是tcon寄存器其中的一位,tcon和我們知道的psw,ie一樣,也是一個特殊功能寄存器。位置當(dāng)然也在特殊功能寄存器區(qū)啦。
TCON是定時器/計數(shù)器(T0,T1)的控制寄存器,關(guān)于它的應(yīng)用我們以后通過例子詳細(xì)說明。它的各位的功能說明如下:
TF1:定時器/計數(shù)器(T1)的溢出中斷標(biāo)志,當(dāng)T1產(chǎn)生溢出試,由硬件置1,CPU響應(yīng)中斷后,由硬件置0;TF0類似。(以后通過試驗詳細(xì)說明)
TR1:置1時啟動定時/計數(shù)器,置0時停止定時/計數(shù)器;TR0類似。(以后通過試驗詳細(xì)說明)
IE1:外部中斷1請求標(biāo)志。當(dāng)它置一的時候,請求中斷。
IT1:外部中斷1觸發(fā)方式控制位。如果IT1是1,則外部中斷為跳變方式觸發(fā),否則,為電平方式觸發(fā)。選擇何種方式觸發(fā),視程序的具體情況來定。
IE0:外部中斷0請求標(biāo)志,含義同IE1。
IT0:外部中斷0觸發(fā)方式控制位,含義同IT1。
4、語句(4)是中斷返回指令,功能和子程序返回指令ret相類似,通常被安排在中斷服務(wù)程序的最后。CPU執(zhí)行完這條指令后,從原來被中斷處開始,重新執(zhí)行被中斷的程序。
現(xiàn)在大家對中斷的基本概念和簡單的編程處理方法有所了解了把,下面一個試驗“按鍵控制跑馬燈”,在這個試驗里面,我們要了解關(guān)于中斷現(xiàn)場保護(hù)的問題。
評論