新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機學習之十一:中斷方式按鍵

        單片機學習之十一:中斷方式按鍵

        作者: 時間:2016-11-18 來源:網絡 收藏
        1、實驗現象

        本文引用地址:http://www.104case.com/article/201611/315886.htm

        最右面的數碼管初始顯示0,每次按下外部按鍵K0執行加一,計數到九時重新回零。

        2、實驗目的

        掌握中斷方式響應按鍵的原理
        掌握中斷服務程序的具體編寫:如何進行鍵的識別,如何去抖動

        3、實驗任務分析

        上一個試驗我們了解了查詢方式按鍵的原理。當單片機工作于查詢方式的時候,要不間斷的對外部按鍵進行查詢,其間單片機不能干其他的任何工作。如果單片機的工作量較大,這種方式就很難適應。

        為了進一步提高單片機的工作效率,可以采用中斷方式。
        中斷方式的按鍵響應過程如下:單片機處理自己的工作,如果有按鍵按下,向單片機發出中斷請求,單片機就會停下現在正在處理的工作,轉去執行中斷程序,執行之后回來繼續剛才的工作;如果沒有按鍵按下,單片機就作自己的工作,不理睬外部鍵盤。

        怎樣向單片機發出中斷請求呢?發出中斷請求的來源叫做中斷源。單片機可提供五個中斷源。其中2個為外部中斷請求INT0和INT1,2個為片內定時/計數器T0和T1的計滿溢出中斷,還有一個是片內串行口中斷請求TI或者RI。在本試驗中,我們用到的是外部中斷INT1。

        還是先看看電路吧。(注意在作中斷試驗之前,我們必須先把JMP4跳線插上,這樣按鍵動作才能發出中斷請求。)

        我們在試驗一中曾經給大家介紹過,單片機的P3口是雙功能口,第一種功能可以作通用的I/O口。而在本試驗中,我們要用到P3口的第二功能。大家看P3.2和P3.3兩個引腳,斜線后面標示的就是P3口的第二功能,分別是INT0和INT1,也就是單片機的兩個外部中斷源。

        我們發現,當任何一個按鍵按下的時候,P3.3引腳,即INT1上就會出現一個低電平,向單片機發出中斷申請。如果單片機開放了外部中斷,就響應中斷請求,進入中斷服務程序。
        那么單片機是否開放中斷功能是由什么控制的呢?在這里就涉及到另外一個特殊功能寄存器IE啦。還記得單片機內部256字節的數據RAM嗎?其中高128字節(80h~ffh)是特殊功能寄存器區。以前我們介紹過PSW就在這個區域,同樣IE也在這個區域,它的名字叫做“中斷允許寄存器”,專門負責程序是否響應中斷的,它的各位功能說明如下:
        EA:CPU中斷允許標志。EA=0,CPU禁止各種中斷;EA=1,CPU開放中斷。但是,每個中斷源的中斷請求是否允許,還需要由各自的允許位決定。所以在本程序中,大家不要忘了首先把EA置1哦!

        ES:串行口允許中斷。ES=1,允許串行口中斷;ES=0,禁止串行口中斷。所以,在這個程序中,這一位和我們沒有關系,不理它就是啦。

        ET1:定時器/計數器T1的溢出中斷允許。ET1=1時,允許T1溢出中斷;ET1=0時,禁止T1溢出中斷。同樣,這一位和我們也沒有關系。

        EX1:外部中斷1(即INT1)允許中斷。當EX1=1時,允許INT1中斷;當EX1=0時,禁止INT1中斷。可見,這一位的值和我們這個試驗密切相關,所以大家千萬不要忘了把這一位置1。

        下面的ET0和EX0的功能與ET1和EX1類似,是分別控制定時器T0和外部中斷INT0的,這里就不再贅述啦。

        在前面分析時,我們發現,四個按鍵中任何一個按下,都會發出中斷請求。那么,如何判斷中斷請求是由那個按鍵發出的呢?這就是中斷服務程序的工作了。在中斷服務程序中,需要完成如下工作:鍵識別、去抖動、和鍵功能處理。
        那么,鍵識別是如何完成的呢?它的思路是這樣的。
        (1)、先把P1口的狀態讀入a寄存器,然后把高四位屏蔽掉
        (2)、判斷是否k0按鍵按下,(即判斷a中的數是否00001101),如果是就調用延時程序去抖,否則,表示不是K0按下,退出中斷返回主程序
        (3)、調用延時程序后,重復上面的(1)(2)步。如果確定k0按下,轉中斷服務程序,否則就是抖動,退出中斷返回主程序。

        在這里還需要說明一點:在進入中斷服務程序之后,我們首先應該關閉中斷,因為如果不關閉中斷,就有可能會引起混亂。在中斷服務程序返回主程序之前,再把中斷打開。
        4、實驗程序
        org 0000h
        ljmp start ;(1)為什么這里要放一條跳轉指令呢,我們在后面解釋把

        org 0013h
        ljmp ext1 ;(2)同上

        org 0030h
        start: clr p1.5 ;主程序開始
        mov r7,#0ffh
        setb ea ;cpu開放中斷
        setb ex1 ;允許外部中斷1申請中斷
        setb it1 ;(3)設置外部中斷1觸發方式為跳變觸發,原因在后面詳細解釋
        lcall play1 ;調用初始狀態顯示子程序
        ajmp $ ;等待按鍵發出中斷申請

        ext1: clr ea ;進入中斷,先關閉中斷
        lcall key_reader ;調用鍵識別子程序
        pass: setb ea ;返回主程序之前先開中斷
        reti ;(4)中斷返回指令,

        key_reader: mov a,p1 ;讀入P1口的狀態
        anl a,#0fh ;屏蔽高四位
        cjne a,#0dh,pass;如果a的內容不是00001101(表示不是k0按下),就退出中斷
        lcall del10ms ;否則,表示k0按下,調用10ms延時去抖
        mov a,p1 ;再次讀入p1口的內容
        anl a,#0fh ;屏蔽高四位
        cjne a,#0dh,pass ;如果a的內容不是00001101,就是抖動,退出中斷
        lcall play2 ;否則,確定按鍵按下,轉數碼顯示程序
        ret

        play1: mov a,#48h ;讓最右面的數碼管顯示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;如果沒有顯示到最后一個數字0,就繼續查表顯示
        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

        相信通過上面的詳細注釋,大家基本上已經看懂這個程序了。下面我就幾個小問題再給大家作一些解釋。

        5、注釋

        1、先看(1)語句,我們發現程序開始的時候,在地址為0000h的地方,放了一條跳轉指令。主程序是從程序存儲器中0030h的地方開始存放的,為什么要把前面的空間空出來呢?這是因為前面的空間我們是有用處的。

        由于不同類型的中斷,具有不同的中斷入口地址。CPU在響應中斷的時候,會根據中斷源的類別,轉到相應的入口去執行中斷服務程序。外部中斷1的入口地址是0013h(其余4個中斷的入口地址大家可以查閱相關資料),那么cpu在響應了外部中斷1后,會自動的到這個地址來,從這個地址開始往下執行程序。所以我們要把前面的一段空出來,以免覆蓋這個地址。

        2、再看看(2)語句,它在中斷1的入口處放了一個跳轉指令,所以,cpu在響應外部中斷后,會到這個入口處往下執行程序。于是CPU就會從這里轉去中斷服務程序。大家可能會說,為什么要跳轉,直接從這里開始存放中斷服務程序 不就可以了嘛。

        由于我們很難預料中斷服務程序的長度,所以我們就拿不準主程序應該從什么單元開始存放。這樣就容易造成整個程序的結構混亂。
        所以還是采用上面的方法吧,看起來結構清楚規范,容易理解。

        3、(3)語句的意思是設置外部中斷1為跳變方式觸發。大家可能覺得,當K0按下的時候,INT1上會出現一個低電平,為什么不能采用電平方式觸發呢?解釋如下:當我們選外部中斷為電平方式觸發的時候,當INT1輸入低電平的時候,cpu響應中斷。在中斷返回之前,INT1必須回到高電平,否則就會第二次產生中斷。所以,如果我們按下按鍵的時間較長,就會產生多次的中斷,導致程序混亂。所以我們在這里要采用邊沿方式觸發。

        順便說說it1,它是外部中斷觸發方式控制位,為1的時候選擇跳變方式觸發,為0的時候選擇電平方式觸發。那么它在哪里呢?

        it1是tcon寄存器其中的一位,tcon和我們知道的psw,ie一樣,也是一個特殊功能寄存器。位置當然也在特殊功能寄存器區啦。

        TCON是定時器/計數器(T0,T1)的控制寄存器,關于它的應用我們以后通過例子詳細說明。它的各位的功能說明如下:

        TF1:定時器/計數器(T1)的溢出中斷標志,當T1產生溢出試,由硬件置1,CPU響應中斷后,由硬件置0;TF0類似。(以后通過試驗詳細說明)

        TR1:置1時啟動定時/計數器,置0時停止定時/計數器;TR0類似。(以后通過試驗詳細說明)

        IE1:外部中斷1請求標志。當它置一的時候,請求中斷。

        IT1:外部中斷1觸發方式控制位。如果IT1是1,則外部中斷為跳變方式觸發,否則,為電平方式觸發。選擇何種方式觸發,視程序的具體情況來定。

        IE0:外部中斷0請求標志,含義同IE1。

        IT0:外部中斷0觸發方式控制位,含義同IT1。

        4、語句(4)是中斷返回指令,功能和子程序返回指令ret相類似,通常被安排在中斷服務程序的最后。CPU執行完這條指令后,從原來被中斷處開始,重新執行被中斷的程序。

        現在大家對中斷的基本概念和簡單的編程處理方法有所了解了把,下面一個試驗“按鍵控制跑馬燈”,在這個試驗里面,我們要了解關于中斷現場保護的問題。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 建昌县| 宁化县| 九龙坡区| 神池县| 定远县| 尉犁县| 弥渡县| 车致| 汤阴县| 斗六市| 高雄市| 肇东市| 宿松县| 云和县| 定陶县| 吉林市| 汤原县| 天祝| 达州市| 嵊泗县| 志丹县| 社旗县| 清水县| 琼海市| 旌德县| 司法| 郸城县| 清徐县| 松潘县| 库伦旗| 镇康县| 凤城市| 察隅县| 闻喜县| 伊川县| 炎陵县| 子长县| 福泉市| 梁平县| 沐川县| 自治县|