?? d9999.asm
字號:
;可預制的倒計時鐘,2位顯示 p34個位調整p35十位調整 p32啟動!
;***************************************************************************
;* sxj1974@163.com (51c51 test web) www.8951.com *
;* Create by :石學軍 www.51c51.com 更多例程請登陸網站 *
;***************************************************************************
keyok bit 00h ;是否有鍵按下的標志
startrun bit 01h ;是否開始運行
value equ 21h ;秒計時值
setval equ 22h ;設置的數值
counter equ 23h ;用于顯示的計數器
count equ 24h ;秒計數器
keyval equ 25h ;按鍵寄存器
dispbuf equ 5eh ;顯示緩沖區
first bit p2.5 ;第一個數碼管控制
second bit p2.6 ;第二個數碼管控制
tmrvar equ 60110 ;定時器的初值65536-5000
hidden equ 0ffh ;顯示器的消隱
org 0000h
jmp start
org 1*8+3 ;time0中斷入口
jmp int_t0 ;到定時器t0中斷服務程序的入口
start:
mov sp,#5fh ;設置堆棧
mov p1,#0ffh ;所有led熄滅
mov setval,#59 ;初值59
mov value,setval ;開始不運行,按鍵后運行
clr startrun
clr keyok ;清除有鍵按下的標志
mov tmod,#01h
mov th0,#HIGH(TMRVAR) ;取tirvar的高8位
MOV TL0,#LOW(TMRVAR) ;取tirvar的低8位
SETB ET0 ;開t0中斷
SETB TR0 ;定時器開始運行
SETB EA ;開總中斷
LOOP:CALL KEY ;調用鍵盤程序
JB KEYOK,KEYPROC ;如果有鍵盤按下則轉鍵盤處理
NEXT:MOV A,VALUE ;獲得秒的數值
MOV B,#10
DIV AB ;二進制轉10進制10位個位分別送顯示緩沖
NEXT1:MOV DISPBUF,A ;
MOV DISPBUF+1,B ;個位送顯示緩沖
JMP LOOP
KEYPROC:MOV A,KEYVAL ;取得鍵值
JZ KEYRUN ;如果為0轉keyrun
DEC A
JZ KEYSTOP ;如果鍵值1 轉stop
DEC A
JZ KEYLEFT ;如果鍵值2轉left
JMP KEYRIGHT ; 如果為3轉right
KEYRUN:
SETB STARTRUN ; 將開始運行的標志送1
JMP LOOP
KEYSTOP:
CLR STARTRUN ;開始運行位送0
JMP LOOP
KEYLEFT: ;鍵盤處理,10位加1并在0-5循環
CLR STARTRUN ;先停止秒
MOV A,SETVAL ;取設置位
ADD A,#10 ;加10
CJNE A,#60,LEFT0 ;到60了么?
MOV A,#0 ;是則清零
JMP LEFT2 ;轉left2
LEFT0:JNC LEFT1 ;比60大么, 是則轉left1
JMP LEFT2 ; 轉left2
LEFT1:SUBB A,#60 ;減60
LEFT2:MOV SETVAL,A ;處理后的a送回setval
MOV VALUE,SETVAL ;送顯示
JMP LOOP
KEYRIGHT: ;鍵盤處理,10位加1并在0-5循環
CLR STARTRUN ;先停止秒
INC DISPBUF+1 ;顯示器的低位加1
MOV A,DISPBUF+1 ; 送到a
CJNE A,#10,REFT0 ;與10比較不等于則轉移
MOV DISPBUF+1,#0 ;等于10則送0
REFT0:MOV A,DISPBUF ; 取出顯示緩沖的高位
MOV B,#10
MUL AB ;乘10
ADD A,DISPBUF+1 ;加低位
MOV SETVAL,A ;送到setval暫存
MOV VALUE,SETVAL ;送顯示
JMP LOOP
KEY: ORL P3,#00111100B ;鍵盤口先送1
CLR KEYOK ;清key標志
MOV A,P3 ;取p3的值
ORL A,#11000011B ;把無關的4位置位
CPL A ;取反a
JZ KEY_RET ;沒有按則所有位都是1 取反則為0
CALL DELAY
MOV A,P3 ;再讀p3的值
ORL A,#11000011B
CPL A
JZ KEY_RET
SETB KEYOK ;確實有按下
JNB ACC.2,KEY_1 ; s1沒有按轉key1
MOV KEYVAL,#0 ;如按下則值為0
JMP KEY_RET
KEY_1:JNB ACC.3,KEY_2 ;s1沒有按轉key2
MOV KEYVAL,#1 ;如按下則值為1
JMP KEY_RET
KEY_2:JNB ACC.4,KEY_3
MOV KEYVAL,#2
JMP KEY_RET
KEY_3:MOV KEYVAL,#3
KEY_RET:
MOV A,P3
ORL A,#11000011B
CPL A
JNZ KEY_RET ;等按鍵釋放
RET
DELAY: mov r5,#2 ;延時20MS
d1:mov r6,#2
D2:djnz r6,d2
djnz r5,d1
ret
INT_T0: ;定時器t0的中斷響應
PUSH ACC
PUSH PSW ;壓堆棧
MOV TH0,#HIGH(TMRVAR)
MOV TL0,#LOW(TMRVAR)
INC COUNT ;軟件計數器加1
MOV A,COUNT ;
CJNE A,#200,INT_N2
MOV COUNT,#0 ;到了200清除
INT_N1:JNB STARTRUN,INT_N2 ;停止運轉,轉
DEC VALUE ;計數器減1
MOV A,VALUE
JNZ INT_N2 ; 不為0則轉
MOV VALUE,SETVAL ; 否則再置初值
INT_N2:
SETB FIRST
SETB SECOND ;關顯示
MOV A,#DISPBUF ; 顯示緩沖的首地址
ADD A,COUNTER
MOV R0,A
MOV A,@R0 ;根據計數器的值取相應緩沖的值
MOV DPTR ,#DISPTAB ;字型表的首地址
MOVC A,@A+DPTR
MOV P0,A ; 送顯示
MOV A,COUNTER ;取計數器的值
JZ DISPFIRST ; 如果為0則顯示第一位
CLR SECOND ; 否則顯示第二位
AJMP DISPNEXT
DISPFIRST:
CLR FIRST ;顯示第一位
DISPNEXT:
INC COUNTER ;計數器加1
MOV A,COUNTER
DEC A
DEC A ;如果為2則回0
JZ RSTCOUNT
AJMP DISPEXIT
RSTCOUNT:
MOV COUNTER,#0 ;計數器的值只能為0或者1
DISPEXIT:
POP PSW
POP ACC
RETI
DISPTAB:DB 28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60H
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -