📄 clock.asm
字号:
;*************************************
;按k1进入设置,按k4设置分,按k3设置时,再按一次k1退出设置
;按k2进入定时,再按一次退出定时
;**************************************
org 0000h
ajmp main
org 000bh
ajmp int0
;------------------------------------
main:
mov dptr , #code_tab;数码管码表地址
mov sp , #60h;栈地址
mov r0 , #79h;时间寄存区
mov r7 , #06h;
initial1:mov @r0 , #00h
inc r0
djnz r7 , initial1 ;寄存区清0
mov r0 , #59h;定时时间寄存区
mov r7 , #06h;
initial2:mov @r0 , #00h
inc r0
djnz r7 , initial2 ;定时时间寄存区清0
mov 5bh , #1;定时初始为1分
mov tmod , #01h;T0工作方式1
mov th0 , #3ch;
mov tl0 , #0afh;初值装定(FFFFH-3CAFH=50000us=50ms)
mov ie, #82h;允许T0中断
mov ip, #00h ;开T0中断,优先级为0
mov tcon , #10h;启动T0
mov 31h , #0;鸣响标志
mov 30h , #14h;计数寄存区(20*50ms)
loop:acall display;显示
acall match;匹配定时
acall display
mov a , p1;读P1口
anl a , #00000010b;查询K2,进行定时设置,
jnz next_1;第2位为0时执行下句,否则跳转
acall delay_;延迟10ms,以便消抖
acall display
mov a , p1
anl a , #00000010b
jnz next_1;K2消抖
setb p1.7
mov 31h , #00h
here_1:acall display_1;显示定时时间
mov a , p1
anl a , #00001000b;查询K4,加分钟
jnz here_h_1
acall delay_
acall display_1
mov a , p1
anl a , #00001000b
jnz here_h_1 ;K4消抖
m_add1_1:mov r0 , #5ch
acall daad1
mov a , r2
xrl a , #60h ;满60min?
jnz here_1
acall clr0
mov r0 , #5eh
acall daad1
mov a , r2
xrl a , #24h
jnz here_1
acall clr0
ajmp here_1
here_h_1:acall display_1
mov a , p1
anl a , #00000100b;查询K3,时钟加1
jnz exit_1
acall delay_
acall display_1
mov a , p1
anl a , #00000100b
jnz exit_1 ;K3消抖
h_add1_1:mov r0 , #5eh
acall daad1
mov a , r2
xrl a , #24h
jnz here_h_1
acall clr0
ajmp here_h_1
exit_1:acall display_1
mov a , p1
anl a , #00000010b;查询K2,退出
jnz here_1
acall delay_
acall display_1
mov a , p1
anl a , #00000010b
jnz here_1 ;K2消抖
exit1_1:acall display_1
mov a , p1
anl a , #00000010b
jz exit1_1 ;弹起退出
next_1:mov a , p1
anl a , #00000001b;查询K1,进入设置
jnz next
acall delay_
acall display
mov a , p1
anl a , #00000001b
jnz next;K1消抖
here:acall display
mov a , p1
anl a , #00001000b;查询K4,加分钟
jnz here_h
acall delay_
acall display
mov a , p1
anl a , #00001000b
jnz here_h ;K4消抖
m_add1:mov r0 , #7ch
acall daad1
mov a , r2
xrl a , #60h;满60分?
jnz here
acall clr0 ;
mov r0 , #7eh
acall daad1
mov a , r2
xrl a , #24h
jnz here
acall clr0
ajmp here
here_h:acall display
mov a , p1
anl a , #00000100b
jnz exit
acall delay_
acall display
mov a , p1
anl a , #00000100b
jnz exit ;K3消抖
h_add1:mov r0 , #7eh
acall daad1
mov a , r2
xrl a , #24h
jnz here_h
acall clr0
ajmp here_h
exit:acall display
mov a , p1
anl a , #00000001b
jnz here
acall delay_
acall display
mov a , p1
anl a , #00000001b
jnz here ;K1消抖
exit1:acall display
mov a , p1
anl a , #00000001b
jz exit1 ;弹起退出
next:
ajmp loop
;------------------------------------
delay_:;延迟10ms
mov r6 , #0c3h
del1:mov r7 , #50h
del2:djnz r7 , del2
djnz r6 , del1
ret
;------------------------------------
match:
mov r1 , #5eh
mov r0 , #7eh
mov r5 , #06
ini:mov a , @r1
xrl a , @r0;比较时分秒各位,同A为0,不同A为1
jz ext0
dec r1
dec r0
djnz r5 , ini ;
mov 31h , #0
ajmp ext
ext0:mov 31h , #1;匹配成功,置鸣响标志
ext: ret
;------------------------------------
display_1: ;显示定时时间,由5EH到59H的RAM
mov r4 , a
mov r1 , #5eh
mov r3 , #11011111b
mov r5 , #06
ini0:mov a , @r1
movc a , @a+dptr;取对应码字
mov p0 , a;输出到LED
mov a , r3
mov p2 , a;选择数码管
rr a
mov r3 , a
dec r1
mov r6 , #011h
del_3:mov r7 , #51h
del_4:djnz r7 , del_4
djnz r6 , del_3;延迟显示1ms,动态显示
djnz r5 , ini0;
mov a , r4
ret
;------------------------------------
display: ;显示时间,有7EH到79H的RAM
mov r4 , a
mov r1 , #7eh
mov r3 , #11011111b
mov r5 , #06
ini1:mov a , @r1
movc a , @a+dptr;取对应码字
mov p0 , a;输出到LED
mov a , r3
mov p2 , a;选择数码管
rr a
mov r3 , a
dec r1
mov r6 , #011h
del_5:mov r7 , #50h
del_6:djnz r7 , del_6
djnz r6 , del_5;延迟显示1ms,动态显示
djnz r5 , ini1;
mov a , r4
ret
;------------------------------------
int0: ;时钟中断处理
push psw
push acc;保存现场
setb psw.3;使用寄存器组1
mov th0 , #3ch
mov tl0 , #0afh;重载50ms
mov a , 30h;
dec a
mov r3 , a
jnz ret0;满一秒(R3计满20次)
mov r3 , #14h;重载计数20(20*50ms)
mov r0 , #7ah;秒
acall daad1 ;加1
mov a , r2
xrl a , #60h;秒满60s?
jnz ret0
mov a , 31h
jnz peep;由鸣响标志鸣响蜂鸣器
setb p1.7;鸣响后一分停止鸣响
ajmp pass
peep:clr p1.7;开启蜂鸣器
mov 31h , #00h;鸣响后清除鸣响标志
pass:acall clr0;秒清0
mov r0 , #7ch;分
acall daad1
mov a , r2
xrl a , #60h;分满60min?
jnz ret0
acall clr0 ;分清0
mov r0 , #7eh;时
acall daad1
mov a , r2
xrl a , #24h;时满24
jnz ret0
acall clr0 ;时清0
ret0:mov 30h , r3
pop acc
pop psw;恢复现场
reti
;------------------------------------
daad1:;时/分/秒寄存区加1
mov a , @r0;取十位到A低位
dec r0;地址减1
swap a;A高低位交换,十位数到高位
orl a , @r0;取个位到A低位
add a , #1
da a;数据调整,保证为BCD码
mov r2 , a;保存A结果
anl a , #0fh;a高位置0
mov @r0 , a;a低位存回个位
mov a , r2;结果写回A
inc r0;地址加1
anl a , #0f0h;a低位置0
swap a;a高低位交换,十位数到低位
mov @r0 , a;a低位存回十位
ret
;------------------------------------
clr0:
clr a
mov @r0 , a
dec r0
mov @r0 , a
ret
;------------------------------------
code_tab: ;字形表
db 0c0h,0f9h,0a4h,0b0h,099h
db 10010010b,10000010b,11011000b,10000000b
db 10010000b
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -