📄 a_clock.asm
字号:
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP KEYSET
ORG 001BH
AJMP SERVE1
;*****************************************************************************************
MAIN: MOV TMOD,#10H ;设T1工作于模式1
MOV 20H,#10 ;装入中断次数
CLR A
MOV 30H,A
MOV 31H,A
MOV 32H,A
MOV 33H,A ;对时分秒单元清0
MOV 34H,A
MOV 35H,A
MOV 36H,A
MOV 37H,A
MOV 38H,A ;功能键0~3的操作值存储单元34~38H
MOV 39H,A ;设置时闪烁定时器
MOV 40H,A
MOV 41H,A
MOV 42H,A
MOV 43H,A ;调时子程序暂存单元40~43H
MOV 44H,A
MOV 45H,A
MOV 46H,A
MOV 47H,A ;调时期子程序暂存单元44~47H
MOV 48H,A
MOV 49H,A
MOV 50H,A
MOV 51H,A
MOV 52H,A
MOV 53H,A
MOV 54H,A
MOV 55H,A ;秒表子程序时间存储单元52~55H
MOV 56H,A
MOV 57H,A
MOV 58H,A
MOV 59H,A ;闹钟设置暂存单元56~59H
MOV 65H,A ;key3键功能中间值存储器
MOV 66H,A
MOV 70H,A
MOV 71H,A
MOV 72H,A
MOV 73H,A ;闹钟设置存储单元70H~73H
MOV 74H,A
MOV 75H,A
MOV 76H,A
MOV 77H,A ;日期存储单元74~77H
SETB ET1 ;允许T1中断
SETB EX0 ;允许外部中断1
SETB IT0 ;设外部中断1为边沿触发方式
MOV IP,#0CH
SETB EA ;允许CPU中断
MOV TH1,#0FCH
MOV TL1,#2AH
SETB TR1 ;开T1中断
CYC: MOV A,34H
CJNE A,#01H,NEXT1
MOV 66H,#00H
LCALL ADJUST
MOV P1,#0F7H
SJMP CYC
NEXT1: CJNE A,#02H,NEXT2
MOV 66H,#00H
LCALL DATE
MOV P1,#0F7H
SJMP CYC
NEXT2: CJNE A,#03H,NEXT3
MOV 66H,#00H
LCALL ALARMCLOCK
MOV P1,#0F7H
SJMP CYC
NEXT3: CJNE A,#04H,NEXT4
LCALL STOPWATCH
SJMP CYC
NEXT4: MOV P1,#0F7H
LCALL RING ;判断是否到了闹钟时间,是则报警
MOV P1,#0F7H
LCALL DISPLAY0
SJMP CYC
;*****************************************************************************************
ADJUST: ;时间校准子程序,40~43H做暂存器,将当前时间值存入并显示
LCALL DISPLAY1
MOV A,65H
CJNE A,#00H,AD_1 ;判断是否进行时间校准设置,否则保持显示校准前时间
MOV A,38H ;
CJNE A,#00H,AD_ET1 ;38H单元为1时表示没有进行功能设置,继续显示装入值
MOV 40H,30H
MOV 41H,31H
MOV 42H,32H
MOV 43H,33H ;将当前时间值装入
INC 38H
AJMP AD_EXIT
AD_1: CJNE A,#01H,AD_2 ;选择小时的十位数进行校准
MOV R0,#40H ;R0做存储单元中转器
AD_13: MOV A,36H
CJNE A,#01H,AD_3 ;加1键按下时,进行加1运算
MOV A,@R0
ADD A,66H
MOV B,#10
DIV AB ;将十位数个位数分开
CJNE R0,#40H,AD_14 ;判断是小时的调整,否则转向分钟判断
CJNE A,#3,AD_4 ;是则小时十位数为二进制
MOV A,#00H
MOV @R0,B ;保存个位数的值
AD_ET1: AJMP AD_EXIT
AD_14: CJNE R0,#41H,AD_15 ;判断是否分钟的校准,否则转向秒钟判断
AD_17: CJNE A,#6,AD_4 ;十位数为六进制
MOV A,#00H
MOV @R0,B ;保存个位数的值
AJMP AD_EXIT
AD_15: CJNE R0,#42H,AD_16 ;判断是否秒的校准,是则秒十位数为六进制,否则转向0.01秒判断
SJMP AD_17
AD_16: CJNE R0,#43H,AD_ET1 ;判断是否0.01秒的校准,否则退出
CJNE A,#10,AD_4 ;是则十位数为十进制
MOV A,#00H
MOV @R0,B ;保存个位数值
AJMP AD_EXIT
AD_4: MOV A,@R0
ADD A,66H
MOV @R0,A ;保存十位数校准值
AJMP AD_EXIT
AD_3: CJNE A,#02H,AD_ET1 ;是减1键按下时
MOV A,@R0
MOV B,#10
DIV AB ;将十位数个位数分开
CJNE A,#00H,AD_6 ;为负数时则返回为相应进制最高数
MOV A,B
CJNE R0,#40H,AD_23 ;时为二进制
ADD A,#20
AJMP AD_24
AD_23: CJNE R0,#41H,AD_25 ;分为六十进制
ADD A,#50
AJMP AD_24
AD_25: CJNE R0,#42H,AD_26 ;秒为六十进制
ADD A,#50
AJMP AD_24
AD_26: CJNE R0,#43H,AD_24 ;0.01秒为一百进制
ADD A,#90
AD_24: MOV @R0,A ;保存设置值
AJMP AD_EXIT
AD_6: MOV A,@R0
CLR C
SUBB A,66H
MOV @R0,A ;保存设置值
SJMP AD_EXIT
AD_2: CJNE A,#02H,AD_7 ;个位数调整
MOV R0,#40H
AD_19: MOV A,36H
CJNE A,#01H,AD_8 ;加1键有按,没有转判断是不减1
MOV A,@R0
MOV B,#10
DIV AB ;十位数个位数分开
MOV A,B
ADD A,66H ;个位数加1
CJNE A,#10,AD_9 ;个位数为十进制
MOV A,@R0
CLR C
SUBB A,B
MOV @R0,A ;保存十位数值
SJMP AD_EXIT
AD_9: INC @R0 ;个位数加1
SJMP AD_EXIT
AD_8: CJNE A,#02H,AD_EXIT ;减1键按下,没有退出
MOV A,@R0
MOV B,#10
DIV AB ;十位数个位数分开
MOV A,B
CJNE A,#00H,AD_11 ;减到为负时转回相应进制的最高数,没有则进行减1
MOV A,@R0
ADD A,#09H
MOV @R0,A ;保存设置值
SJMP AD_EXIT
AD_11: MOV A,@R0
CLR C
SUBB A,66H ;减1
MOV @R0,A ;保存设置值
SJMP AD_EXIT
AD_7: CJNE A,#03H,AD_12 ;分,十位数调整
MOV R0,#41H
AJMP AD_13
AD_12: CJNE A,#04H,AD_18 ;分,个位数调整
MOV R0,#41H
AJMP AD_19
AD_18: CJNE A,#05H,AD_20 ;秒,十位数调整
MOV R0,#42H
AJMP AD_13
AD_20: CJNE A,#06H,AD_21 ;秒,个位数调整
MOV R0,#42H
AJMP AD_19
AD_21: CJNE A,#07H,AD_22 ;0.01秒,十位数调整
MOV R0,#43H
AJMP AD_13
AD_22: CJNE A,#08H,AD_EXIT ;0.01秒,个位数调整
MOV R0,#43H
AJMP AD_19
AD_EXIT:MOV 30H,40H
MOV 31H,41H
MOV 32H,42H
MOV 33H,43H ;保存设置结果
MOV 36H,#00H
RET
;*****************************************************************************************
DATE: ;日期校准子程序,44~47H
LCALL DISPLAY2
MOV A,65H
CJNE A,#00H,DA_1 ;判断是否进行日期校准设置,否则保持显示校准前日期
MOV A,38H
CJNE A,#00H,DA_ET1
MOV 44H,74H
MOV 45H,75H
MOV 46H,76H
MOV 47H,77H
INC 38H
AJMP DA_EXIT
DA_1: CJNE A,#01H,DA_2 ;选择年份的千位数进行校准
MOV R0,#44H ;R0做时间值暂存器
DA_13: MOV A,36H
CJNE A,#01H,DA_3 ;加1键按下时,进行加1运算
MOV A,@R0
ADD A,66H
MOV B,#10
DIV AB
CJNE R0,#44H,DA_14 ;判断是年份千百位的调整,是则年份千位数为十进制
DA_17: CJNE A,#10,DA_4
MOV A,#00H
MOV @R0,B
DA_ET1: AJMP DA_EXIT
DA_14: CJNE R0,#45H,DA_15 ;判断是否年份的校准,是则年份百位数为十进制
AJMP DA_17
DA_15: CJNE R0,#46H,DA_16 ;判断是否月的校准,是则月十位数为二进制
CJNE A,#02H,DA_4
MOV A,#00H
MOV @R0,B
AJMP DA_EXIT
DA_16: CJNE R0,#47H,DA_ET1 ;判断是否日的校准,是则十位数为四进制
CJNE A,#4,DA_4
MOV A,#00H
MOV @R0,B
AJMP DA_EXIT
DA_4: MOV A,@R0
ADD A,66H
MOV @R0,A ;保存校准值
AJMP DA_EXIT
DA_3: CJNE A,#02H,DA_ET1 ;是减1键按下时
MOV A,@R0
MOV B,#10
DIV AB
CJNE A,#00H,DA_6 ;为负数时则返回为相应进制最高数
MOV A,B
CJNE R0,#44H,DA_23 ;年份千高位十进制
ADD A,#90
AJMP DA_26
DA_23: CJNE R0,#45H,DA_24 ;年份十位数十进制
ADD A,#90
AJMP DA_26
DA_24: CJNE R0,#46H,DA_25 ;月份十位数二进制
ADD A,#10
AJMP DA_26
DA_25: CJNE R0,#47H,DA_EXIT ;日十位数四进制
ADD A,#30
DA_26: MOV @R0,A
AJMP DA_EXIT
DA_6: MOV A,@R0
CLR C
SUBB A,66H
MOV @R0,A
AJMP DA_EXIT
DA_2: CJNE A,#02H,DA_7 ;年,百位数调整
MOV R0,#44H
DA_19: MOV A,36H
CJNE A,#01H,DA_8
MOV A,@R0
MOV B,#10
DIV AB
MOV A,B
ADD A,66H
CJNE A,#10,DA_9
MOV A,@R0
CLR C
SUBB A,B
MOV @R0,A
AJMP DA_EXIT
DA_9: INC @R0
SJMP DA_EXIT
DA_8: CJNE A,#02H,DA_EXIT
MOV A,@R0
MOV B,#10
DIV AB
MOV A,B
CJNE A,#00H,DA_11
MOV A,@R0
ADD A,#09H
MOV @R0,A
AJMP DA_EXIT
DA_11: MOV A,@R0
CLR C
SUBB A,66H
MOV @R0,A
AJMP DA_EXIT
DA_7: CJNE A,#03H,DA_12 ;年,十位数调整
MOV R0,#45H
AJMP DA_13
DA_12: CJNE A,#04H,DA_18 ;年,个位数调整
MOV R0,#45H
AJMP DA_19
DA_18: CJNE A,#05H,DA_20 ;月,十位数调整
MOV R0,#46H
AJMP DA_13
DA_20: CJNE A,#06H,DA_21 ;月,个位数调整
MOV R0,#46H
AJMP DA_19
DA_21: CJNE A,#07H,DA_22 ;日,十位数调整
MOV R0,#47H
AJMP DA_13
DA_22: CJNE A,#08H,DA_EXIT ;日,个位数调整
MOV R0,#47H
AJMP DA_19
DA_EXIT:MOV 74H,44H
MOV 75H,45H
MOV 76H,46H
MOV 77H,47H ;保存设置结果
MOV 36H,#00H
RET
;*****************************************************************************************
;****************************************************************************
ALARMCLOCK: ;闹钟设置子程序
LCALL DISPLAY3
MOV A,65H
CJNE A,#00H,AL_1 ;判断是否进行闹钟设置
MOV A,38H
CJNE A,#00H,AL_ET1
MOV 56H,70H
MOV 57H,71H
MOV 58H,72H
MOV 59H,73H
INC 38H
AJMP AL_EXIT
AL_1: CJNE A,#01H,AL_2 ;选择小时的十位数进行校准
MOV R0,#56H
AL_13: MOV A,36H
CJNE A,#01H,AL_3 ;加1键
MOV A,@R0
ADD A,66H
MOV B,#10
DIV AB
CJNE R0,#56H,AL_14 ;判断是小时的调整
CJNE A,#3,AL_4
MOV A,#00H
MOV @R0,B
AL_ET1: AJMP AL_EXIT
AL_14: CJNE R0,#57H,AL_15 ;判断分
AL_17: CJNE A,#6,AL_4
MOV A,#00H
MOV @R0,B
AJMP AL_EXIT
AL_15: CJNE R0,#58H,AL_16 ;判断秒
AJMP AL_17
AL_16: CJNE R0,#59H,AL_ET1
CJNE A,#10,AL_4
MOV A,#00H
MOV @R0,B
AJMP AL_EXIT
AL_4: MOV A,@R0
ADD A,66H
MOV @R0,A ;保存校准值
AJMP AL_EXIT
AL_3: CJNE A,#02H,AL_ET1 ;减1键
MOV A,@R0
MOV B,#10
DIV AB
CJNE A,#00H,AL_6
MOV A,B
CJNE R0,#56H,AL_23
ADD A,#20
AJMP AL_24
AL_23: CJNE R0,#57H,AL_25
ADD A,#50
AJMP AL_24
AL_25: CJNE R0,#58H,AL_26
ADD A,#50
AJMP AL_24
AL_26: CJNE R0,#59H,AL_24
ADD A,#90
AL_24: MOV @R0,A
AJMP AL_EXIT
AL_6: MOV A,@R0
CLR C
SUBB A,66H
MOV @R0,A
AJMP AL_EXIT
AL_2: CJNE A,#02H,AL_7 ;时,个位数调整
MOV R0,#56H
AL_19: MOV A,36H
CJNE A,#01H,AL_8
MOV A,@R0
MOV B,#10
DIV AB
MOV A,B
ADD A,66H
CJNE A,#10,AL_9
MOV A,@R0
CLR C
SUBB A,B
MOV @R0,A
AJMP AL_EXIT
AL_9: INC @R0
AJMP AL_EXIT
AL_8: CJNE A,#02H,AL_EXIT
MOV A,@R0
MOV B,#10
DIV AB
MOV A,B
CJNE A,#00H,AL_11
MOV A,@R0
ADD A,#09H
MOV @R0,A
AJMP AL_EXIT
AL_11: MOV A,@R0
CLR C
SUBB A,66H
MOV @R0,A
AJMP AL_EXIT
AL_7: CJNE A,#03H,AL_12 ;分,十位数设置
MOV R0,#57H
AJMP AL_13
AL_12: CJNE A,#04H,AL_18 ;分,个位数设置
MOV R0,#57H
AJMP AL_19
AL_18: CJNE A,#05H,AL_20 ;秒,十位数设置
MOV R0,#58H
AJMP AL_13
AL_20: CJNE A,#06H,AL_21 ;秒,个位数设置
MOV R0,#58H
AJMP AL_19
AL_21: CJNE A,#07H,AL_22 ;0.01秒,十位数设置
MOV R0,#59H
AJMP AL_13
AL_22: CJNE A,#08H,AL_EXIT
MOV R0,#59H
AJMP AL_19
AL_EXIT:MOV 70H,56H
MOV 71H,57H
MOV 72H,58H
MOV 73H,59H
MOV 36H,#00H
RET
;*******************************************************************************
STOPWATCH: ;秒表子程序,52H~55H为秒表暂存单元,35H单元为控制信号单元
LCALL DISPLAY4
MOV A,35H
CJNE A,#00H,ST_1
SJMP ST_EXIT
ST_1: CJNE A,#01H,ST_2 ;开始计时,key1键做开始、停止控制
MOV R3,#00H
ST_4: MOV A,34H
CJNE A,#04H,ST_3
LCALL DISPLAY4
MOV A,35H
CJNE A,#02H,ST_4 ;检测是否停止,是则退出计时,否则继续
ST_2: CJNE A,#03H,ST_EXIT ;复位key2键做复位控制
ST_3: MOV 52H,#00H
MOV 53H,#00H
MOV 54H,#00H
MOV 55H,#00H
MOV 35H,#00H
ST_EXIT:RET
TIME: ;秒表时钟源
INC 55H
MOV A,55H
CJNE A,#100,TI_EXIT
MOV 55H,#00H
INC 54H
MOV A,54H
CJNE A,#60,TI_EXIT
MOV 54H,#00H
INC 53H
MOV A,53H
CJNE A,#60,TI_EXIT
MOV 53H,#00H
INC 52H
MOV A,52H
CJNE A,#24,TI_EXIT
MOV 52H,#00H
TI_EXIT:RET
;**********************************************************************************
RING: ;闹钟判断及铃声产生70H~73H
MOV A,30H
CJNE A,70H,RI_EXIT
MOV A,31H
CJNE A,71H,RI_EXIT
MOV A,32H
CJNE A,72H,RI_EXIT
MOV 50H,#01H
RI_EXIT:
RET
;***********************************************************************************
KEYSET: ;键盘中断检测处理程序,34H~38H,60H,65H,66H
PUSH PSW
PUSH ACC
PUSH DPH
PUSH DPL
JNB P1.4,DELAY
JNB P1.5,DELAY
JNB P1.6,DELAY
JNB P1.7,DELAY
AJMP KEYEND
DELAY: LCALL D10MS
JNB P1.4,COL0 ;判断是否有键按下
JNB P1.5,COL1
JNB P1.6,COL2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -