ljmp main ; 顯示到最后一個(gè)數(shù)字則重新開始
tab: db 0ebh, 52h, 62h, 0e1h, 64h, 44h, 0eah, 40h, 60h, 48h ; 段碼表
del10ms: ; 10ms延時(shí)子程序(12M)
mov r6, #20 ; 2機(jī)器周期
temp: mov r5, #248 ; 2機(jī)器周期
djnz r5, $ ; 2機(jī)器周期 2+2×248=498
djnz r6, temp ; 2機(jī)器周期 2×20=40
ret ; 2+20×498+40=10002 即10ms
end
★將該程序下載到板上驗(yàn)證發(fā)現(xiàn)很不穩(wěn)定,按一次鍵時(shí)顯示可能會(huì)變幾次,如果按住鍵不放,將會(huì)顯示“8”,且不停在閃爍,用Porteus仿真了一下也是這個(gè)問題。這是由于顯示了一個(gè)數(shù)字之后,單片機(jī)會(huì)返回重新查詢P1.0的狀態(tài),如果按下的時(shí)間很長(zhǎng),就會(huì)導(dǎo)致單片機(jī)又檢測(cè)到低電平,所以就繼續(xù)顯示下一個(gè)數(shù)字,常按住的話就會(huì)循環(huán)此過程,所以看到的閃爍的“8”實(shí)際上是快速動(dòng)態(tài)顯示“0”到“9”時(shí)人眼的視覺暫留產(chǎn)生的。那如何使按下一次按鍵,無論時(shí)間長(zhǎng)短,只作一次按鍵處理呢?可以在顯示完一個(gè)數(shù)字后即檢測(cè)P1.0是否回到高電平(鍵放開),若是,表示按鍵一次,繼續(xù)執(zhí)行顯示下一個(gè)數(shù); 若不是則原地等待直到P1.0返回高電平。按此思路在程序中將一個(gè)段碼送入P0口顯示之后,加一判斷語(yǔ)句(紅色):
org 0000h
start: mov p0, #48h ; 段碼-顯示0
mov p2, #01h ; 位碼-選通第一位數(shù)碼管
main: mov r7, #0ffh ; 查表時(shí)偏移量,用來實(shí)現(xiàn)由0到9循環(huán)顯示
key: jb p1.0, key ; 如果P1.0為高電平,則繼續(xù)執(zhí)行此句查詢。
call del10ms ; 否則調(diào)用延時(shí)程序?qū)崿F(xiàn)軟件去抖
jb p1.0, key ; 再次查詢P1.0,如果是高電平,表示是抖動(dòng),繼續(xù)查詢
dis: ; 確定按鍵按下,開始執(zhí)行顯示程序
inc r7 ; 偏移量自加(第一次值為0)
mov a, r7
mov dptr, #tab ; 取表首址
movc a, @a+dptr ; 用查表指令獲取要顯示的數(shù)字
mov p0, a ; 得到該字段碼送入P0口顯示
wait2: jnb p1.0, wait2 ; 等待按鍵松開
cjne a, #48h, key ; 未顯示到最后一個(gè)數(shù), 繼續(xù)查詢按鍵狀態(tài)
ljmp main ; 顯示到最后一個(gè)數(shù)字則重新開始
tab: db 0ebh, 52h, 62h, 0e1h, 64h, 44h, 0eah, 40h, 60h, 48h ; 段碼表
del10ms: ; 10ms延時(shí)子程序(12M)
mov r6, #20 ; 2機(jī)器周期
temp: mov r5, #248 ; 2機(jī)器周期
djnz r5, $ ; 2機(jī)器周期 2+2×248=498
djnz r6, temp ; 2機(jī)器周期 2×20=40
ret ; 2+20×498+40=10002 即10ms
end
★再下載到板上驗(yàn)證,可得到預(yù)測(cè)結(jié)果,用Porteus仿真如下(注:由于此Blog空間圖片上傳要求在100K以內(nèi),所以只模擬了0到5的循環(huán),而實(shí)際上是從0到9循環(huán)的,那個(gè)文件做出來要144K,無法上傳。在此僅作為模擬演示):





