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