📄 clock.txt
字号:
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP AJ0 ;外部中断0
ORG 000BH
LJMP TUP ;定时/计数器T0中断
ORG 0013H
LJMP AJ1 ;外部中断1
ORG 0030H
MAIN: NOP ;主程序
MOV SP,#60H ;设置堆栈指针
MOV 21H,#00H ;秒BCD码存储单元
MOV 22H,#00H ;分BCD码存储单元
MOV 23H,#00H ;小时BCD码存储单元
MOV 24H,#00H ;日BCD码存储单元
MOV 25H,#00H ;月BCD码存储单元
MOV 26H,#00H ;年BCD码存储单元
MOV 27H,#00H ;闪烁标志
MOV R7,#00H ;时间/日期转换标志
MOV TL0,#0B0H ;装T0的时间常数
MOV TH0,#3CH ;T0一次中断时间为0.05秒
MOV 20H,#14H ;T0循环计时次数20次
MOV TMOD,#01H ;T0初始化:方式1,计数位16位
SETB ET0 ;开T0中断
SETB EX0 ;开外部中断0(INT0)
SETB EX1 ;开外部中断1(INT1)
SETB EA ;CPU开中断
SETB PT0 ;设置T0中断为高优先级
SETB TR0 ;T0开始计时
SJMP $ ;等待中断
; // sub: T0中断程序 //
TUP: MOV TL0,#0B0H ;重装T0的时间常数
MOV TH0,#3CH
DJNZ 20H,INTER1 ;循环20次(是否达到1秒)?
SJMP INTER2
INTER1: LJMP LAST
INTER2: MOV A,21H ;取秒的BCD码
CJNE A,#59H,INTER3 ;是否达到59秒,否则转秒加一
SJMP INTER4
INTER3: LJMP SADD
INTER4: MOV 21H,#00H ;存第一秒数值
MOV A,22H ;取分的BCD码
CJNE A,#59H,INTER5 ;是否达到59分,否则转分加一
SJMP INTER6
INTER5: LJMP MADD
INTER6: MOV 22H,#00H ;存第一分数值
MOV A,23H ;取小时的BCD码
CJNE A,#23H,HADD ;是否达到23时,否则转小时加一
MOV 23H,#00H ;存第一小时数值
MOV A,25H ;取月的BCD码
CJNE A,#02H,NOTFEB ;是否2月,否则转大小月判断
ISFEB: NOP
ACALL DIVBCD ;调用平年闰年判断程序
MOV A,R3 ;程序参数传递(R3)->(A)
CJNE A,#00H,PING ;“00H”说明是闰年
RUN: MOV A,24H ;取(二月)日的BCD码
CJNE A,#29H,DDADD ;是否为29号,否则转日加一
MOV 24H,#01H ;存第一天数值(1号)
MOV 25H,#03H ;月份改为3月
SJMP CONT
PING: MOV A,24H ;取(二月)日的BCD码
CJNE A,#28H,DDADD ;是否为28号,否则转日加一
MOV 24H,#01H ;存第一天数值(1号)
MOV 25H,#03H ;月份改为3月
SJMP CONT
NOTFEB:NOP ;二月之外的其他月份处理
CJNE A,#04H,YUE1 ;是否为4月?
AJMP T12
YUE1: CJNE A,#06H,YUE2 ;是否为6月?
AJMP T12
YUE2: CJNE A,#09H,YUE3 ;是否为9月?
AJMP T12
YUE3: CJNE A,#11H,T11 ;是否为11月?
AJMP T12
T11: MOV A,24H ;取(大月)日的BCD码
CJNE A,#31H,DDADD ;是否为31号,否则转日加一
AJMP T30
T12: MOV A,24H ;取(小月)日的BCD码
CJNE A,#30H,DDADD ;是否为30号,否则转日加一
T30: MOV 24H,#01H ;存第一天数值(1号)
MOV A,25H ;取月的BCD码
CJNE A,#12H,MMADD ;是否为12月,否则转月加一
MOV 25H,#01H ;存第一月数值(1月)
MOV A,26H ;取年的BCD码
CJNE A,#99H,YYADD ;是否为99年,否则转年加一
MOV 26H,#00H ;存第一年数值(00年)
SJMP CONT
YYADD: MOV A,26H ;取年的BCD码
ADD A,#01H ;年数值加一
DA A ;BCD码调整
MOV 26H,A ;存年的数值
SJMP CONT
MMADD:MOV A,25H ;取月的BCD码
ADD A,#01H ;月数值加一
DA A ;BCD码调整
MOV 25H,A ;存月的数值
SJMP CONT
DDADD: MOV A,24H ;取日的BCD码
ADD A,#01H ;日数值加一
DA A ;BCD码调整
MOV 24H,A ;存日的数值
SJMP CONT
HADD: MOV A,23H ;取时的BCD码
ADD A,#01H ;时数值加一
DA A ;BCD码调整
MOV 23H,A ;存时的数值
SJMP CONT
MADD: MOV A,22H ;取分的BCD码
ADD A,#01H ;分数值加一
DA A ;BCD调整
MOV 22H,A ;存分的数值
SJMP CONT
SADD: MOV A,21H ;取秒的BCD码
ADD A,#01H ;秒加一
DA A ;BCD码调整
MOV 21H,A ;存秒的数值
CONT: MOV 20H,#14H ;重置T0计时循环次数20次
LAST: RETI
; // sub: LED显示程序 //
DISP: MOV DPTR,#TABLE ;取显示编码表头地址
MOV A,R7 ;取时间/日期转换显示标志
CJNE A,#00H,DATE ;“00H”为显示时间
TIME: MOV R0,#21H ;取秒地址
SJMP TSAVE
DATE: MOV R0,#24H ;“FFH”为显示日期,取日地址
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 ;取编码表中的相应编码
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 ;取编码表中的相应编码
MOV R5,A ;存显示数值到(R5)
MOV A,@R0
SWAP A
ANL A,#0FH ;得到高四位
MOVC A,@A+DPTR ;取编码表中的相应编码
MOV R6,A ;存显示数值到(R6)
NOP TDISP: MOV P2,#0FFH ;熄灭所有的LED MOV P0,R1 ;数值输往DS6 MOV A,27H ;取闪烁标志 CJNE A,#03H,AA ;“03H”则DS5&DS6闪烁 SJMP AAA AA: CJNE A,#06H,AAAA ;“06H”则DS5&DS6闪烁 AAA: MOV A,20H ;取T0计时循环次数
RRC A
JNC AAAAA ;最低位为1则开DS6
AAAA: MOV P2,#0FEH
AAAAA: LCALL DELAY ;调用延迟程序
MOV P2,#0FFH ;熄灭所有的LED
MOV P0,R2 ;数值输往DS5
MOV A,27H ;取闪烁标志
CJNE A,#03H,BB ;“03H”则DS5&DS6闪烁
SJMP BBB
BB: CJNE A,#06H,BBBB ;“06H”则DS5&DS6闪烁
BBB: MOV A,20H ;取T0计时循环次数
RRC A
JNC BBBBB ;最低位为1则开DS5
BBBB: MOV P2,#0FDH
BBBBB: LCALL DELAY ;调用延时程序
MOV P2,#0FFH ;熄灭所有的LED
MOV P0,R3 ;数值输往DS4
MOV A,27H ;取闪烁标志
CJNE A,#02H,CC ;“02H”则DS3&DS4闪烁
SJMP CCC
CC: CJNE A,#05H,CCCC ;“05H”则DS3&DS4闪烁
CCC: MOV A,20H ;取T0计时循环次数
RRC A
JNC CCCCC ;最低位为1则开DS4
CCCC: MOV P2,#0FBH ;
CCCCC: LCALL DELAY ;调用延时程序
MOV P2,#0FFH ;熄灭所有的LED
MOV P0,R4 ;数值输往DS3
MOV A,27H ;取闪烁标志
CJNE A,#02H,DD ;“02H”则DS3&DS4闪烁
SJMP DDD
DD: CJNE A,#05H,DDDD ;“05H”则DS3&DS4闪烁
DDD: MOV A,20H ;取T0计时循环次数
RRC A
JNC DDDDD ;最低位为1则开DS3
DDDD: MOV P2,#0F7H ;
DDDDD: LCALL DELAY ;调用延时程序
MOV P2,#0FFH ;熄灭所有的LED
MOV P0,R5 ;数值输往DS2
MOV A,27H ;取闪烁标志
CJNE A,#01H,EE ;“01H”则DS1&DS2闪烁
SJMP EEE
EE: CJNE A,#04H,EEEE ;“04H”则DS1&DS2闪烁
EEE: MOV A,20H ;取T0计时循环次数
RRC A
JNC EEEEE ;最低位为1则开DS2
EEEE: MOV P2,#0EFH ;
EEEEE: LCALL DELAY ;调用延时程序
MOV P2,#0FFH ;熄灭所有的LED
MOV P0,R6 ;数值输往DS1
MOV A,27H ;取闪烁标志
CJNE A,#01H,FF ;“01H”则DS1&DS2闪烁
SJMP FFF
FF: CJNE A,#04H,FFFF ;“04H”则DS1&DS2闪烁
FFF : MOV A,20H ;取T0计时循环次数
RRC A
JNC FFFFF ;最低位为1则开DS1
FFFF: MOV P2,#0DFH ;
FFFFF: LCALL DELAY ;调用延时程序
RET
; // sub:延时程序 //
DELAY: MOV 28H,#03H
D2: MOV 29H,#0FFH
D1: DJNZ 29H,D1
DJNZ 28H,D2
RET
; // sub: INT0中断服务程序 //
AJ0 :NOP ; 切换/调整时间/日期
PUSH PSW
LCALL DMS ;调用按键操作程序(包括LED显示)
JNB P3.3,OUT ;检查端口INT1,高电平表示key0按下
NOP
MOV A,27H ;取闪烁标志
CJNE A,#00H,ADJYY ;“00H”则不闪烁
MOV A,R7 ;取时间/日期显示转换标志
XRL A,#0FFH ;修改标志
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 BCD ;调用平年闰年判断程序
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: 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
AEND0: NOP
POP PSW ;恢复标志寄存器内容
RETI
; // sub: INT1中断服务程序 //
AJ1: NOP
PUSH PSW ;保护标志寄存器内容
LCALL DMS ;调用按键操作程序(包括LED显示)
JNB P3.2,AEND1 ;检查端口INT0,高电平表示key1按下
NOP
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: NOP ;“R7=FFH”表示显示日期
MOV A,27H ;取闪烁标志
CJNE A,#03H,EDIT1 ;“03H”表示DS5&DS6闪烁
MOV 27H,#00H ;恢复到不闪烁状态
SJMP AEND1
EDIT1: INC A ;闪烁标志加一
MOV 27H,A ;存闪烁标志
NOP
AEND1: NOP
POP PSW ;恢复标志寄存器内容
RETI
; // sub:按键操作及LED显示程序 //
DMS: MOV 2AH,#09H ; or(#0BH)
DMSS: LCALL DISP ; with LED display
DJNZ 2AH,DMSS
RET
; // sub: BCD除法/
BCD: 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
RET
; // code table 显示编码表//
TABLE: DB 40H ; for “0”
DB 79H ; for “1”
DB 24H ; for “2”
DB 30H ; for “3”
DB 19H ; for “4”
DB 12H ; for “5”
DB 02H ; for “6”
DB 78H ; for “7”
DB 00H ; for “8”
DB 10H ; for “9”
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -