單片機(jī)學(xué)習(xí)之十三:流水燈花樣變換(中斷)
進(jìn)入程序后,程序作雙向跑馬燈;按下k0鍵,程序作左向跑馬燈;按下k1按鍵程序作右向跑馬燈;按下k2鍵兩個(gè)亮點(diǎn)從兩邊向中間移動(dòng);按下k3鍵兩個(gè)亮點(diǎn)從中間向兩邊移動(dòng)。
本文引用地址:http://m.butianyuan.cn/article/201611/315888.htm二、實(shí)驗(yàn)?zāi)康?br />掌握在中斷程序中處理多個(gè)按鍵動(dòng)作的響應(yīng)方法
三、實(shí)驗(yàn)任務(wù)分析:
(注意:在作這個(gè)試驗(yàn)的時(shí)候,不要忘了把JMP0跳線(xiàn)置于1、2的位置,選擇二極管顯示單元。)
在前面的兩個(gè)中斷方式響應(yīng)按鍵動(dòng)作的試驗(yàn)中,我們只對(duì)一個(gè)按鍵動(dòng)作做出響應(yīng),難度比較小。
而在這個(gè)程序中,我們的中斷程序要對(duì)多個(gè)按鍵動(dòng)作進(jìn)行響應(yīng), 燈光變換的花樣有4種,用不同的按鍵切換。那么,這種問(wèn)題又應(yīng)該如何處理呢?
我們可以這樣作:主程序中,我們作左右跑馬燈,相信大家已經(jīng)很熟啦。
在中斷服務(wù)程序中,我們首先讀取按鍵狀態(tài),然后延時(shí)10ms,再次讀取按鍵狀態(tài)。把兩次獲得的按鍵狀態(tài)比較,如果不同,就表示是抖動(dòng),退出中斷;否則,就去判斷是哪個(gè)按鍵按下。如果是k0,就執(zhí)行左跑馬燈;如果是k1,就執(zhí)行右跑馬燈;如果是k2,就執(zhí)行亮點(diǎn)向中間移動(dòng);如果是k3,就執(zhí)行亮點(diǎn)向兩邊移動(dòng)。
這樣的思路總體是對(duì)的,但是有一點(diǎn)需要注意:我們?cè)趯?xiě)程序的時(shí)候,在中斷服務(wù)程序中,應(yīng)該盡量的使得任務(wù)簡(jiǎn)化,不要讓中斷服務(wù)程序作過(guò)多復(fù)雜的任務(wù),而要盡量把這些復(fù)雜的任務(wù)放到主程序中間去完成。
按照這樣的一個(gè)思路,我們的做法如下:
在主程序中設(shè)5個(gè)標(biāo)志,然后不斷的對(duì)這幾個(gè)標(biāo)志進(jìn)行查詢(xún):如果是標(biāo)志1,就執(zhí)行雙向跑馬燈;如果是標(biāo)志2,就執(zhí)行左向跑馬燈;如果是標(biāo)志3,就執(zhí)行右向跑馬燈,依次類(lèi)推。
而在中斷服務(wù)程序中,我們只需要進(jìn)行如下工作:去抖動(dòng),鍵識(shí)別,改變標(biāo)志,就可以啦。
該程序中,我們用寄存器r0中的內(nèi)容作為標(biāo)志,當(dāng)它里面的內(nèi)容是0ffh時(shí),執(zhí)行左右跑馬燈程序;為00h時(shí),執(zhí)行左跑馬燈;01h時(shí)執(zhí)行右跑馬燈;02h時(shí)執(zhí)行兩個(gè)亮點(diǎn)向中間移動(dòng);03h時(shí)執(zhí)行兩個(gè)亮點(diǎn)象兩邊移動(dòng)。
現(xiàn)在來(lái)看看主程序和中斷服務(wù)程序的流程圖吧:
下面就是按照這個(gè)思路編寫(xiě)的程序,這個(gè)程序的結(jié)構(gòu)略微復(fù)雜,大家要注意。
四、實(shí)驗(yàn)程序如下:
org 0000h
ajmp start
org 0013h
ajmp ext1
org 0020h
start: clr p1.5
mov r0,#0ffh ;對(duì)r0賦初值,r0即為我們?cè)O(shè)的標(biāo)志,
setb ea ;開(kāi)中斷
setb ex1 ;允許外部中斷1申請(qǐng)中斷
setb it1 ;設(shè)置外部中斷1跳變方式觸發(fā)
mov sp,#70h ;設(shè)置堆棧
loop0: cjne r0,#0ffh,loop1 ; 如果r0中的內(nèi)容不是0ffh,轉(zhuǎn)去loop1
ajmp main_light ;否則,執(zhí)行左右跑馬燈
loop1: cjne r0,#00h,loop2 ;如果r0中的內(nèi)容不是00h,轉(zhuǎn)去loop2
ajmp k0_light ;否則,執(zhí)行左向跑馬燈
loop2: cjne r0,#01h,loop3 ;如果r0中的內(nèi)容不是01h,轉(zhuǎn)去loop3
ajmp k1_light ;否則,執(zhí)行右向跑馬燈
loop3: cjne r0,#02h,loop4 ;如果r0中的內(nèi)容不是02h,轉(zhuǎn)去loop4
ajmp k2_light ;否則,執(zhí)行雙亮點(diǎn)向中間移動(dòng)
loop4: cjne r0,#03h,loop5 ;如果r0中的內(nèi)容不是03h,返回重新開(kāi)始查詢(xún)
ajmp k3_light ;否則,執(zhí)行雙亮點(diǎn)向兩邊移動(dòng)
loop5: ajmp loop0 ;返回重新開(kāi)始查詢(xún)
ext1: clr ea ;關(guān)閉中斷
push acc ;現(xiàn)場(chǎng)保護(hù)
push psw
mov a,p1 ;讀入按鍵狀態(tài)
anl a,#0fh ;屏蔽高四位
mov 30h,a ;把鍵盤(pán)狀態(tài)值保存在30h
mov a,p1 ;再次讀入按鍵狀態(tài)
anl a,#0fh ;屏蔽高四位
cjne a,30h,pass ;兩次的按鍵值如果不相等,表示是抖動(dòng),退出中斷
ajmp k0_check ;如果相等,轉(zhuǎn)去鍵識(shí)別程序
;以下是按鍵識(shí)別程序
k0_check: cjne a,#0dh,k1_check ;如果不是k0按下,轉(zhuǎn)去判斷是否k1按下
ajmp k0_manage ;否則,轉(zhuǎn)去k0的按鍵處理程序
k1_check: cjne a,#0eh,k2_check ;如果不是k1按下,轉(zhuǎn)去判斷是否k2按下
ajmp k1_manage ;否則,轉(zhuǎn)去k1的按鍵處理程序
k2_check: cjne a,#0bh,k3_check ;如果不是k2按下,轉(zhuǎn)去判斷是否k3按下
ajmp k2_manage ;否則,轉(zhuǎn)去k2的按鍵處理程序
k3_check: cjne a,#07h,pass ;如果不是k3按下,退出中斷
ajmp k3_manage ;否則,轉(zhuǎn)去k3的按鍵處理程序
;以下是各按鍵相應(yīng)的處理程序,
k0_manage: mov r0,#00h ;置標(biāo)志2
ajmp pass
k1_manage: mov r0,#01h ;置標(biāo)志3
ajmp pass
k2_manage: mov r0,#02h ;置標(biāo)志4
ajmp pass
k3_manage: mov r0,#03h :置標(biāo)志5
ajmp pass
pass: pop psw ;恢復(fù)現(xiàn)場(chǎng)
pop acc
setb ea ;開(kāi)中斷
reti ;中斷返回
main_light: mov r7,#08h ;main_light是左右跑馬燈程序
mov r6,#06h
mov a,#0feh
l_loop: mov r1,a ;用r1保存現(xiàn)在的亮點(diǎn)位置,便于變換燈光時(shí)從該位置開(kāi)始
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是雙亮點(diǎn)向中間程序
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是雙亮點(diǎn)向兩邊程序
lcall del100ms
mov p0,#0dbh
lcall del100ms
mov p0,#0bdh
lcall del100ms
mov p0,#7eh
lcall del100ms
ajmp loop0
del10ms: mov r5,#20 ;10ms延時(shí)程序
del1: mov r4,#0ffh
del2: djnz r4,del2
djnz r5,del1
ret;
del100ms: mov r3,#200 ;100ms延時(shí)程序
del3: mov r2,#0ffh
del4: djnz r2,del4
djnz r3,del3
ret
end;
評(píng)論