📄 clock.asm
字号:
WATCH: CJNE A,#02H,ATIME ;显示秒表
MOV R0,#S_PER_SEC_BCD ;
SJMP TSAVE
ATIME:
MOV R0,#A_SEC_BCD
TSAVE: MOV A,@R0 ;取日的BCD码
ANL A,#0FH ;得到低四位
MOVC A,@A+DPTR ;取编码表中的相应编码
MOV R1,A ;存显示数值到(R1)
MOV A,@R0
SWAP A
ANL A,#0FH ;得到高四位
MOVC A,@A+DPTR ;取编码表中的相应编码
MOV R2,A ;存显示数值到(R2)
INC R0 ;地址增一
MOV A,@R0 ;取分/月的BCD码
ANL A,#0FH ;得到低四位
MOVC A,@A+DPTR ;取编码表中的相应编码
ANL A,#7FH ;加上小数点已区分分秒
MOV R3,A ;存显示数值到(R3)
MOV A,@R0
SWAP A
ANL A,#0FH ;得到高四位
MOVC A,@A+DPTR ;取编码表中的相应编码
MOV R4,A ;存显示数值到(R4)
INC R0
MOV A,@R0 ;取时/年的BCD码
ANL A,#0FH ;得到低四位
MOVC A,@A+DPTR ;取编码表中的相应编码
ANL A,#7FH ;加上小数点已区分时分
MOV R5,A ;存显示数值到(R5)
MOV A,@R0
SWAP A
ANL A,#0FH ;得到高四位
MOVC A,@A+DPTR ;取编码表中的相应编码
MOV R6,A ;存显示数值到(R6)
NOP
;——————————————————————————————————
;p1位选线
;p0段选线
;——————————————————————————————————
TDISP: MOV P1,#0FFH ;熄灭所有的LED
MOV P0,R1 ;数值输往DS6
MOV A,27H ;取闪烁标志
CJNE A,#03H,AA ;"03H"则DS5&DS6闪烁
SJMP AAA
AA: CJNE A,#06H,AAAA1 ;"06H"则DS5&DS6闪烁
SJMP AAA
AAAA1:
CJNE A,#09H,AAAA
AAA: MOV A,20H ;取T0计时循环次数
RRC A
JNC AAAAA ;最低位为1则开DS6
AAAA: MOV P1,#0FBH
AAAAA: LCALL DELAY ;调用延迟程序
MOV P1,#0FFH ;熄灭所有的LED
MOV P0,R2 ;数值输往DS5
MOV A,27H ;取闪烁标志
CJNE A,#03H,BB ;"03H"则DS5&DS6闪烁
SJMP BBB
BB: CJNE A,#06H,BBBB1 ;"06H"则DS5&DS6闪烁
SJMP BBB
BBBB1: CJNE A,#09H,BBBB
BBB: MOV A,20H ;取T0计时循环次数
RRC A
JNC BBBBB ;最低位为1则开DS5
BBBB: MOV P1,#0F7H
BBBBB: LCALL DELAY ;调用延时程序
MOV P1,#0FFH ;熄灭所有的LED
MOV P0,R3 ;数值输往DS4
MOV A,27H ;取闪烁标志
CJNE A,#02H,CC ;"02H"则DS3&DS4闪烁
SJMP CCC
CC: CJNE A,#05H,CCCC1 ;"05H"则DS3&DS4闪烁
SJMP CCC
CCCC1: CJNE A,#08H,CCCC
CCC: MOV A,20H ;取T0计时循环次数
RRC A
JNC CCCCC ;最低位为1则开DS4
CCCC: MOV P1,#0EFH ;
CCCCC: LCALL DELAY ;调用延时程序
MOV P1,#0FFH ;熄灭所有的LED
MOV P0,R4 ;数值输往DS3
MOV A,27H ;取闪烁标志
CJNE A,#02H,DD ;"02H"则DS3&DS4闪烁
SJMP DDD
DD: CJNE A,#05H,DDDD1 ;"05H"则DS3&DS4闪烁
SJMP DDD
DDDD1: CJNE A,#08H,DDDD
DDD: MOV A,20H ;取T0计时循环次数
RRC A
JNC DDDDD ;最低位为1则开DS3
DDDD: MOV P1,#0DFH ;
DDDDD: LCALL DELAY ;调用延时程序
MOV P1,#0FFH ;熄灭所有的LED
MOV P0,R5 ;数值输往DS2
MOV A,27H ;取闪烁标志
CJNE A,#01H,EE ;"01H"则DS1&DS2闪烁
SJMP EEE
EE: CJNE A,#04H,EEEE1 ;"04H"则DS1&DS2闪烁
SJMP EEE
EEEE1: CJNE A,#07H,EEEE
EEE: MOV A,20H ;取T0计时循环次数
RRC A
JNC EEEEE ;最低位为1则开DS2
EEEE: MOV P1,#0BFH
EEEEE: LCALL DELAY ;调用延时程序
MOV P1,#0FFH ;熄灭所有的LED
MOV P0,R6 ;数值输往DS1
MOV A,27H ;取闪烁标志
CJNE A,#01H,FF ;"01H"则DS1&DS2闪烁
SJMP FFF
FF: CJNE A,#04H,FFFF1 ;"04H"则DS1&DS2闪烁
SJMP FFF
FFFF1: CJNE A,#07H,FFFF
FFF: MOV A,20H ;取T0计时循环次数
RRC A
JNC FFFFF ;最低位为1则开DS1
FFFF: MOV P1,#7FH ;
FFFFF: LCALL DELAY ;调用延时程序
RET
;————————————————————————————————————
; sub: delay (6.148ms)Author:By YUJIAN.XU 延时程序
;————————————————————————————————————
DELAY: MOV 28H,#03H
D2: MOV 29H,#0FFH
D1: DJNZ 29H,D1
DJNZ 28H,D2
RET
;————————————————————————————————————
;sub: INT0 Author: By YUJIAN.XU 中断服务程序
;处理开关Key0(for shift/adjust即调整/时间,日期显示模式/秒表控制键)
;————————————————————————————————————
ADJUST0:
NOP ; 调整/时间,日期显示模式/秒表
PUSH PSW
PUSH ACC
LCALL DMS ;调用按键操作程序(包括LED显示)
JB P3.2,OUT ;检查端口INT0,高电平表示无key0按下
;K0按下
; MOV SLEEP_UP,#00H ;自动休眠器清零
MOV A,27H ;取闪烁标志
CJNE A,#00H,ADJYY ;"00H"则不闪烁
MOV S_PER_SEC_BCD,#00H ;秒表清零
MOV S_SEC_BCD,#00H
MOV MIN_BCD,#00H
MOV A,#00H ;秒表清0
MOV A,R7 ;取时间/日期显示转换标志
INC A
CJNE A,#04H,MODE
CLR A
MODE: MOV R7,A ;保存标志
LCALL DISP ;LED显示
OUT: LJMP AEND0
ADJYY: NOP ;"01 to 06"闪烁
CJNE A,#01H,ADJMM ;"01H"表示调整年
MOV A,26H ;取年的BCD码
CJNE A,#99H,ADJYY0 ;是否为99年,否则转年加一
MOV 26H,#00H ;保存第一年数值(00年)
LJMP ADJYYF
ADJYY0: ADD A,#01H ;年数值加一
DA A ;BCD调整
MOV 26H,A ;保存年的数值
ADJYYF: LJMP AEND0
ADJMM: CJNE A,#02H,ADJDD ;"02H"表示调整月
MOV A,25H ;取月的BCD码
CJNE A,#12H,ADJMM0 ;是否为12月,否则转月加一
MOV 25H,#01H ;存第一个月数值(1月)
LJMP ADJMMF
ADJMM0: ADD A,#01H ;月数值加一
DA A ;BCD码调整
MOV 25H,A ;存月的数值
ADJMMF: LJMP AEND0
ADJDD: CJNE A,#03H,AA1 ;"03H"表示调整日
LJMP BB1
AA1: LJMP ADJH
BB1: MOV A,25H ;取月的BCD码
CJNE A,#02H,NFEB ;判断是否为二月,是则转二月处理
FEB: NOP
ACALL DIVBCD ;调用平年闰年判断程序
MOV A,R3 ;程序参数传递
CJNE A,#00H,APING ;"00H"则表示闰年
ARUN: MOV A,24H ;取(闰年)日的BCD码
CJNE A,#29H,DDA ;是否为29号,否则转日加一
LJMP DD01
APING: MOV A,24H ;取(平年)日的BCD码
CJNE A,#28H,DDA ;是否为28号,否则转日加一
LJMP DD01
NFEB: NOP ;判断大小月
CJNE A,#04H,YUE4 ;4月?
LJMP ADD1
YUE4: CJNE A,#06H,YUE5 ;6月?
LJMP ADD1
YUE5: CJNE A,#09H,YUE6 ;9月?
LJMP ADD1
YUE6: CJNE A,#11H,YUE7 ;11月?
LJMP ADD1
YUE7: NOP ;大月处理
MOV A,24H ;取日的BCD码
CJNE A,#31H,DDA ;是否31号,否则转日加一
LJMP DD01
ADD1: NOP ;小月处理
MOV A,24H ;取日的BCD码
CJNE A,#30H,DDA ;是否30号,否则转日加一
DD01: MOV 24H,#01H ;保存第一天(1号)
LJMP ADJDDF
DDA: ADD A,#01H ;日加一
DA A ;BCD码调整
MOV 24H,A ;存日的数值
ADJDDF: LJMP AEND0
ADJH: CJNE A,#04H,ADJM ;"04H"表示调整时
MOV A,23H ;取时的BCD码
CJNE A,#23H,ADJH0 ;是否为23时,否则转时加一
MOV 23H,#00H ;保存第一小时数值(00时)
LJMP ADJHF
ADJH0: ADD A,#01H ;时加一
DA A ;BCD码调整
MOV 23H,A ;保存时的数值
ADJHF: LJMP AEND0
ADJM : CJNE A,#05H,ADJS ;"05H"表示调整分
MOV A,22H ;取分的BCD码
CJNE A,#59H,ADJM0 ;是否59分,否则转分加一
MOV 22H,#00H ;存第一分钟(00分)
LJMP ADJMF
ADJM0: ADD A,#01H ;分加一
DA A ;BCD码调整
MOV 22H,A ;存分的数值
ADJMF: LJMP AEND0
ADJS:
CJNE A,#06H,ADJAH
MOV A,21H ;取秒的BCD码
CJNE A,#59H,ADJS0 ;是否为59秒,否则转秒加一
MOV 21H,#00H ;存第一秒的数值(00秒)
LJMP ADJSF
ADJS0: ADD A,#01H ;秒加一
DA A ;BCD码调整
MOV 21H,A ;存秒的数值
ADJSF: NOP
;————————————————————————————————————
;闹钟调整
;————————————————————————————————————
ADJAH: CJNE A,#07H,ADJAM ;"07H"表示调整时
MOV A,A_HOUR_BCD ;取时的BCD码
CJNE A,#23H,ADJAH0 ;是否为23时,否则转时加一
MOV A_HOUR_BCD,#00H ;保存第一小时数值(00时)
LJMP ADJAHF
ADJAH0: ADD A,#01H ;时加一
DA A ;BCD码调整
MOV A_HOUR_BCD,A ;保存时的数值
ADJAHF: LJMP AEND0
ADJAM : CJNE A,#08H,ADJAS ;"08H"表示调整分
MOV A,A_MIN_BCD ;取分的BCD码
CJNE A,#59H,ADJAM0 ;是否59分,否则转分加一
MOV A_MIN_BCD,#00H ;存第一分钟(00分)
LJMP ADJAMF
ADJAM0: ADD A,#01H ;分加一
DA A ;BCD码调整
MOV A_MIN_BCD,A ;存分的数值
ADJAMF: LJMP AEND0
ADJAS: MOV A,A_SEC_BCD ;取秒的BCD码
CJNE A,#59H,ADJAS0 ;是否为59秒,否则转秒加一
MOV A_SEC_BCD,#00H ;存第一秒的数值(00秒)
LJMP ADJASF
ADJAS0: ADD A,#01H ;秒加一
DA A ;BCD码调整
MOV A_SEC_BCD,A ;存秒的数值
ADJASF: NOP
AEND0: NOP
WAIT2: JNB P3.2,WAIT2 ;按键等待
POP ACC
POP PSW ;恢复标志寄存器内容
RETI
;————————————————————————————————————
; sub: INT1 Author: By YUJIAN.XU 中断服务程序
;————————————————————————————————————
ADJUST1:NOP ;转换 flag(00 to 06) in 27H
PUSH PSW ;保护标志寄存器内容
PUSH ACC
LCALL DMS ;调用按键操作程序(包括LED显示)
JB P3.3,AEND1 ;检查端口INT1,高电平表示key1按下
;K1按下
; MOV SLEEP_UP,#00H ;自动休眠器清零
MOV A,R7 ;取时间/日期显示转换标志
CJNE A,#00H,EDIT0 ;"00H"则显示时间
MOV A,27H ;取闪烁标志
CJNE A,#00H,EDIT2 ;"00H"则在不闪烁状态
MOV 27H,#04H ;存闪烁标志,表示DS1&DS2闪烁
SJMP AEND1
EDIT2: CJNE A,#06H,EDIT1 ;"06H"表示DS5&DS6闪烁
MOV 27H,#00H ;恢复到不闪烁状态
SJMP AEND1
EDIT0: CJNE A,#01H,DIS_WATCH ; "R7=01" 表示显示日期
NOP
MOV A,27H ;取闪烁标志
CJNE A,#03H,EDIT1 ;"03H"表示DS5&DS6闪烁
MOV 27H,#00H ;恢复到不闪烁状态
SJMP AEND1
EDIT1: INC A ;闪烁标志加一
MOV 27H,A ;存闪烁标志
NOP
SJMP AEND1
DIS_WATCH:
CJNE A,#02H,DIS_BELL ; 秒表
MOV A,WATCH_FLAG
CJNE A,#00H,WATCH_STOP
XRL A,#0FFH
MOV WATCH_FLAG,A ; 取flag标志
SETB TR1 ; 启动T1定时器,开始计时
SJMP AEND1
WATCH_STOP:
CLR TR1 ; 停止计时
MOV A,WATCH_FLAG
XRL A,#0FFH
MOV WATCH_FLAG,A ; 取flag标志
SJMP AEND1
DIS_BELL:
CJNE A,#03H,AEND1
MOV A,27H
CJNE A,#00H,ALT0
MOV 27H,#07H
SJMP AEND1
ALT0:
CJNE A,#09H,EDIT1
MOV 27H,#00H
AEND1: NOP
WAIT1: JNB P3.3,WAIT1 ; 等待按键提起
POP ACC
POP PSW ;恢复标志寄存器内容
RETI
;————————————————————————————————————
; sub:按键操作及LED显示程序
;————————————————————————————————————
DMS: MOV 2AH,#09H ; or(#0BH)
DMSS: LCALL DISP ; with LED display
DJNZ 2AH,DMSS
RET
;————————————————————————————————————
; sub: BCD division 用于判断是否为闰年?
;————————————————————————————————————
DIVBCD: MOV R0,26H ;存被除数BCD码
MOV R1,#04H ;存除数BCD码
MOV R2,#00H ;存商数BCD码
MOV A,R1 ;除数求补码
CPL A ;
ADD A,#9BH ;
MOV R1,A ;存除数的补码
MOV A,R0 ;取被除数
ANL A,#0F0H ;屏蔽被除数低四位
SWAP A ;高四位转低四位
LP0: MOV R3,A ;存余数BCD码
ADD A,R1 ;加除数补码
DA A ;BCD码调整
JNC LP1 ;C=1,被除数大于除数,继续加
INC R2 ;商数加一
SJMP LP0
LP1: MOV A,R3 ;取余数
SWAP A ;高四位低四位对调
MOV R3,A ;存余数
MOV A,R2 ;取商数
SWAP A ;商数置高四位
MOV R2,A ;存商数
MOV A,R0 ;取被除数
ANL A,#0FH ;屏蔽被除数高四位
ORL A,R3
LP2: MOV R3,A ;存余数
ADD A,R1 ;加除数补码
DA A ;BCD码调整
JNC LP3 ;C=1,被除数大于除数,继续加
INC R2 ;商加一
SJMP LP2
LP3: NOP ; without rounding
RET
;————————————————————————————————————
;code table Author: By YUJIAN.XU 显示编码表
;————————————————————————————————————
TABLE: DB 0c0H ; for "0"
DB 0f9H ; for "1"
DB 0a4H ; for "2"
DB 0b0H ; for "3"
DB 99H ; for "4"
DB 92H ; for "5"
DB 82H ; for "6"
DB 0f8H ; for "7"
DB 80H ; for "8"
DB 90H ; for "9"
DB 88H ; for "A"
DB 83H ; for "B"
DB 0C6H ; for "C"
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -