新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機學習之十三:流水燈花樣變換(中斷)

        單片機學習之十三:流水燈花樣變換(中斷)

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

        進入程序后,程序作雙向跑馬燈;按下k0鍵,程序作左向跑馬燈;按下k1按鍵程序作右向跑馬燈;按下k2鍵兩個亮點從兩邊向中間移動;按下k3鍵兩個亮點從中間向兩邊移動。

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

        二、實驗目的
        掌握在中斷程序中處理多個按鍵動作的響應方法

        三、實驗任務分析:
        (注意:在作這個試驗的時候,不要忘了把JMP0跳線置于1、2的位置,選擇二極管顯示單元。)
        在前面的兩個中斷方式響應按鍵動作的試驗中,我們只對一個按鍵動作做出響應,難度比較小。
        而在這個程序中,我們的中斷程序要對多個按鍵動作進行響應, 燈光變換的花樣有4種,用不同的按鍵切換。那么,這種問題又應該如何處理呢?
        我們可以這樣作:主程序中,我們作左右跑馬燈,相信大家已經很熟啦。
        在中斷服務程序中,我們首先讀取按鍵狀態,然后延時10ms,再次讀取按鍵狀態。把兩次獲得的按鍵狀態比較,如果不同,就表示是抖動,退出中斷;否則,就去判斷是哪個按鍵按下。如果是k0,就執行左跑馬燈;如果是k1,就執行右跑馬燈;如果是k2,就執行亮點向中間移動;如果是k3,就執行亮點向兩邊移動。
        這樣的思路總體是對的,但是有一點需要注意:我們在寫程序的時候,在中斷服務程序中,應該盡量的使得任務簡化,不要讓中斷服務程序作過多復雜的任務,而要盡量把這些復雜的任務放到主程序中間去完成。
        按照這樣的一個思路,我們的做法如下:
        在主程序中設5個標志,然后不斷的對這幾個標志進行查詢:如果是標志1,就執行雙向跑馬燈;如果是標志2,就執行左向跑馬燈;如果是標志3,就執行右向跑馬燈,依次類推。
        而在中斷服務程序中,我們只需要進行如下工作:去抖動,鍵識別,改變標志,就可以啦。
        該程序中,我們用寄存器r0中的內容作為標志,當它里面的內容是0ffh時,執行左右跑馬燈程序;為00h時,執行左跑馬燈;01h時執行右跑馬燈;02h時執行兩個亮點向中間移動;03h時執行兩個亮點象兩邊移動。
        現在來看看主程序和中斷服務程序的流程圖吧:

        下面就是按照這個思路編寫的程序,這個程序的結構略微復雜,大家要注意。

        四、實驗程序如下:
        org 0000h

        ajmp start

        org 0013h

        ajmp ext1

        org 0020h

        start: clr p1.5

        mov r0,#0ffh ;對r0賦初值,r0即為我們設的標志,

        setb ea ;開中斷

        setb ex1 ;允許外部中斷1申請中斷

        setb it1 ;設置外部中斷1跳變方式觸發

        mov sp,#70h ;設置堆棧

        loop0: cjne r0,#0ffh,loop1 ; 如果r0中的內容不是0ffh,轉去loop1

        ajmp main_light ;否則,執行左右跑馬燈

        loop1: cjne r0,#00h,loop2 ;如果r0中的內容不是00h,轉去loop2

        ajmp k0_light ;否則,執行左向跑馬燈

        loop2: cjne r0,#01h,loop3 ;如果r0中的內容不是01h,轉去loop3

        ajmp k1_light ;否則,執行右向跑馬燈

        loop3: cjne r0,#02h,loop4 ;如果r0中的內容不是02h,轉去loop4

        ajmp k2_light ;否則,執行雙亮點向中間移動

        loop4: cjne r0,#03h,loop5 ;如果r0中的內容不是03h,返回重新開始查詢

        ajmp k3_light ;否則,執行雙亮點向兩邊移動

        loop5: ajmp loop0 ;返回重新開始查詢

        ext1: clr ea ;關閉中斷

        push acc ;現場保護

        push psw

        mov a,p1 ;讀入按鍵狀態

        anl a,#0fh ;屏蔽高四位

        mov 30h,a ;把鍵盤狀態值保存在30h

        mov a,p1 ;再次讀入按鍵狀態

        anl a,#0fh ;屏蔽高四位

        cjne a,30h,pass ;兩次的按鍵值如果不相等,表示是抖動,退出中斷

        ajmp k0_check ;如果相等,轉去鍵識別程序

        ;以下是按鍵識別程序

        k0_check: cjne a,#0dh,k1_check ;如果不是k0按下,轉去判斷是否k1按下

        ajmp k0_manage ;否則,轉去k0的按鍵處理程序

        k1_check: cjne a,#0eh,k2_check ;如果不是k1按下,轉去判斷是否k2按下

        ajmp k1_manage ;否則,轉去k1的按鍵處理程序

        k2_check: cjne a,#0bh,k3_check ;如果不是k2按下,轉去判斷是否k3按下

        ajmp k2_manage ;否則,轉去k2的按鍵處理程序

        k3_check: cjne a,#07h,pass ;如果不是k3按下,退出中斷

        ajmp k3_manage ;否則,轉去k3的按鍵處理程序

        ;以下是各按鍵相應的處理程序,

        k0_manage: mov r0,#00h ;置標志2

        ajmp pass

        k1_manage: mov r0,#01h ;置標志3

        ajmp pass

        k2_manage: mov r0,#02h ;置標志4

        ajmp pass

        k3_manage: mov r0,#03h :置標志5

        ajmp pass

        pass: pop psw ;恢復現場

        pop acc

        setb ea ;開中斷

        reti ;中斷返回

        main_light: mov r7,#08h ;main_light是左右跑馬燈程序

        mov r6,#06h

        mov a,#0feh

        l_loop: mov r1,a ;用r1保存現在的亮點位置,便于變換燈光時從該位置開始

        mov p0,a

        lcall del100ms

        rl a

        djnz r7,l_loop

        mov a,#0bfh

        r_loop: mov r1,a

        mov p0,a

        lcall del100ms

        rr a

        djnz r6,r_loop

        ljmp loop0

        k0_light: mov a,r1 ;k0_light是左向跑馬燈程序

        mov p0,a

        lcall del100ms

        rl a

        mov r1,a

        ajmp loop0

        k1_light: mov a,r1 ;k1_light是右向跑馬燈程序

        mov p0,a

        lcall del100ms

        rr a

        mov r1,a

        ajmp loop0

        k2_light: mov p0,#7eh ;k2_light是雙亮點向中間程序

        lcall del100ms

        mov p0,#0bdh

        lcall del100ms

        mov p0,#0dbh

        lcall del100ms

        mov p0,#0e7h

        lcall del100ms

        ajmp loop0

        k3_light: mov p0,#0e7h ;k3_light是雙亮點向兩邊程序

        lcall del100ms

        mov p0,#0dbh

        lcall del100ms

        mov p0,#0bdh

        lcall del100ms

        mov p0,#7eh

        lcall del100ms

        ajmp loop0

        del10ms: mov r5,#20 ;10ms延時程序

        del1: mov r4,#0ffh

        del2: djnz r4,del2

        djnz r5,del1

        ret;

        del100ms: mov r3,#200 ;100ms延時程序

        del3: mov r2,#0ffh

        del4: djnz r2,del4

        djnz r3,del3

        ret

        end;



        關鍵詞: 單片機流水燈中

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 陕西省| 明溪县| 福州市| 南江县| 新宁县| 望城县| 通化县| 临朐县| 安仁县| 浙江省| 武汉市| 阆中市| 峨眉山市| 郧西县| 昌邑市| 厦门市| 河曲县| 桐城市| 赤峰市| 新晃| 博湖县| 鞍山市| 万荣县| 芒康县| 新乡市| 丰台区| 云浮市| 伊宁市| 资兴市| 东乌| 永修县| 临夏县| 广平县| 廉江市| 贵德县| 佛教| 井陉县| 宣城市| 余干县| 宜都市| 万州区|