新闻  |   论坛  |   博客  |   在线研讨会
可预制的倒计时钟
tvb2058 | 2007-09-12 11:19:26    阅读:2162   发布文章

 

;可预制的倒计时钟,p35个位,p34十位,p32确定
;***************************************************************************
;***************************************************************************

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 ;定时器开始运行
; CLR SEC
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 ;如果为0keyrun
DEC A
JZ KEYSTOP ;
如果键值1 stop
DEC A

JZ KEYLEFT ;
如果键值2left
JMP KEYRIGHT ;
如果为3right
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

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
szyth  2008-05-05 19:45:34 

沙发!

推荐文章
最近访客