📄 数字钟代码.asm
字号:
DATA_IN DATA 0020H
DATA_OUT DATA 0021H
WEISHU DATA 0022H
WEISHU2 DATA 0029H
SHI DATA 0023H
FEN DATA 0024H
MIAO DATA 0025H
YEAR DATA 0026H
MONTH DATA 0027H
DAY DATA 0028H
KEY BIT P3.3 ;7279的KEY按键输出
DAT BIT P1.1 ;7279的DATA串行数据引脚
CLK BIT P1.0 ;7279的CLK同步时钟引脚
CS BIT P2.6 ;7279的CS片选输入端
;*************************************
;************ 主程序 **************
;*************************************
ORG 0000H
LJMP START
ORG 000BH
LJMP INT
ORG 0013H
LJMP INT1
ORG 0100H
START: MOV SP,#2FH ; 定义堆栈
SETB CS
SETB KEY
CLR CLK
CLR DAT ;初始化I/O口
CALL DELAY25 ;延时25mS
MOV R3,#20
SETB EA
SETB ET0
SETB EX1
SETB PX1
MOV TMOD,#01H
MOV TH0,#03CH
MOV TL0,#0B0H
SETB TR0 ;中断初始化
MOV DATA_OUT,#0A4H
CALL SEND ;发复位(清除)指令
;-----------------------------------------
MOV MIAO,#55 ;存放秒数字
MOV FEN,#59 ;存放分数字
MOV SHI,#11 ;存放时数字
MOV DAY,#1fH
MOV MONTH,#0cH
MOV YEAR,#08H
MOV WEISHU,#03H
MOV WEISHU2,#03H
SETB P1.7 ;判断是否闪烁
SETB P1.5
SETB P1.6
MOV R6,#11111100B ;存放要闪烁的位数,要左移
MOV R4,#11111100B
;----------------------------------------
; 第三个和第六个数码管位显示点并闪烁
; 扫描显示时钟
;----------------------------------------
SHIZHONG:MOV DATA_OUT,#88H
CALL SEND
MOV DATA_OUT,#11011011B
CALL SEND
CFSM:MOV DATA_OUT,#95H
CALL SEND
MOV DATA_OUT,#80H
CALL SEND
;--------------------------------
MOV DATA_OUT,#92H
CALL SEND
MOV DATA_OUT,#80H
CALL SEND
;--------------------------------
MOV R5,#87H
MOV A,SHI ;显示时分秒
XS:MOV B,#10
DIV AB
MOV DATA_OUT,R5
CALL SEND
MOV DATA_OUT,A
CALL SEND
DEC R5
MOV DATA_OUT,R5
CALL SEND
DEC R5
MOV DATA_OUT,B
CALL SEND
CJNE R5,#85H,LOP1
MOV A,FEN
DEC R5
SJMP XS
LOP1:CJNE R5,#82H,LOP2
MOV A,MIAO
DEC R5
SJMP XS
LOP2:JNB P1.6,RIQI ;P1.0=0扫描显示日期
JB P1.7,SHIZHONG
SJMP CFSM
DDD0:SJMP SHIZHONG
;----------------------------
; 扫描显示日期
;----------------------------
RIQI:MOV DATA_OUT,#88H
CALL SEND
MOV DATA_OUT,#11011011B
CALL SEND
CFSM2:MOV DATA_OUT,#95H
CALL SEND
MOV DATA_OUT,#01H
CALL SEND
;--------------------------------
MOV DATA_OUT,#92H
CALL SEND
MOV DATA_OUT,#01H
CALL SEND
MOV R5,#87H
MOV A,YEAR ;显示年月日
XS2:MOV B,#10
DIV AB
MOV DATA_OUT,R5
CALL SEND
MOV DATA_OUT,A
CALL SEND
DEC R5
MOV DATA_OUT,R5
CALL SEND
DEC R5
MOV DATA_OUT,B
CALL SEND
CJNE R5,#85H,LOP21
MOV A,MONTH
DEC R5
SJMP XS2
LOP21:CJNE R5,#82H,LOP22
MOV A,DAY
DEC R5
SJMP XS2
LOP22:JB P1.6,DDD0;若P1.6=1,扫描时钟显示
JB P1.5,RIQI
SJMP CFSM2
;***********************************
;****** 定时T0中断服务程序 *****
;***********************************
INT:PUSH A
DJNZ R3,OUT
MOV R3,#20
INC MIAO
MOV A,MIAO
CJNE A,#60,OUT
MOV MIAO,#00H
INC FEN
MOV A,FEN
CJNE A,#60,OUT
MOV FEN,#00H
INC SHI
MOV A,SHI
CJNE A,#24,OUT
MOV SHI,#00H
;----------------------------------------
INC DAY
MOV A,YEAR ;判断是否为闰年
MOV B,#4
DIV AB
MOV A,B
CJNE A,#0,OUT11 ;是否被四整除?,不整除则跳转
MOV DPTR,#TABLE1
RRT: MOV A,MONTH
MOVC A,@A+DPTR
INC A
CJNE A,DAY,OUT
MOV DAY,#01H
INC MONTH
MOV A,MONTH
CJNE A,#13,OUT
MOV MONTH,#01H
INC YEAR
MOV A,YEAR
CJNE A,#100,OUT
MOV YEAR,#00H
JMP OUT
OUT11:MOV DPTR,#TABLE2
SJMP RRT
OUT:POP A
MOV TH0,#03CH
MOV TL0,#0B0H
RETI
;*************************************
;*********** 按键中断程序 *********
;*************************************
INT1:PUSH A
CALL DELAY25
JB P3.3,OUT2
MOV DATA_OUT,#15H ;读键值指令
CALL SEND
CALL RECEIVE
SETB CS
MOV A,DATA_IN ;键值放在A里面
;-------------------------------
; 在时钟界面下操作
;-------------------------------
;----------S0按下----------
S0: CJNE A,#00H,S1
JNB P1.6,S80C
JB P1.7,S00 ;P1.7=1 :不闪烁,要进入闪烁状态
CPL P1.7 ;P1.7=0 :已经闪烁,要关掉。
JMP OUT2
S00:CPL P1.7
MOV R0,WEISHU
CJNE R0,#00H,S01 ;时闪烁,R0=00H-- 分闪烁,R0=01H---秒闪烁,R0=02H
MOV WEISHU,#03H ;已经闪烁完,则重新再来
MOV R6,#11111100B
S01:MOV DATA_OUT,#88H ;要闪烁的位数
CALL SEND
MOV DATA_OUT,R6
CALL SEND
MOV R0,A
MOV A,R6
RL A
RL A
RL A
MOV R6,A
MOV A,R0
DEC WEISHU
SJMP OUT2
;---------S1按下 加1 ----------
S1:CJNE A,#01H,S2
JNB P1.6,S81C
JNB P1.7,S10 ;P1.7=0闪烁,才进行加1操作
SJMP OUT2 ;否则退出
S10:MOV R1,WEISHU
CJNE R1,#00H,S11
INC SHI
MOV R0,SHI
CJNE R0,#24,OUT2
MOV SHI,#00H
SJMP OUT2
S11:CJNE R1,#01H,S12
INC FEN
MOV R0,FEN
CJNE R0,#60,OUT2
MOV FEN,#00H
JMP OUT2
S12:INC MIAO
MOV R0,MIAO
CJNE R0,#60,OUT2
MOV MIAO,#00H
JMP OUT2
;---------跳出中断中转-------
S0C:SJMP S0
OUT2:SJMP OUT21
S80C:SJMP S80
;---------S2按下 减1 ----------
S2:CJNE A,#02H,S8
JNB P1.6,S82C
JNB P1.7,S20 ;P1.7=0有闪烁,才进入减1操作
SJMP OUT2 ;无闪烁才退出
S20:MOV R1,WEISHU
CJNE R1,#00H,S21
DEC SHI
MOV R0,SHI
CJNE R0,#0FFH,OUT2
MOV SHI,#23
SJMP OUT2
S21:CJNE R1,#01H,S22
DEC FEN
MOV R0,FEN
CJNE R0,#0FFH,OUT2
MOV FEN,#59
SJMP OUT2
S22:DEC MIAO
MOV R0,MIAO
CJNE R0,#0FFH,OUT2
MOV MIAO,#59
SJMP OUT2
;--------------------------------------
; 在日期界面下操作
;-------------------------------------
S1C:SJMP S1
S81C:SJMP S81
S82C:JMP S82
;---------S8按下 进入日期界面 ----------
S8: CJNE A,#08H,S80
CPL P1.6
SJMP OUT2
;---------S0按下,调整日期------------
S80: CJNE A,#00H,S81
JB P1.6,S0C
JB P1.5,S800
CPL P1.5
JMP OUT2
S800:CPL P1.5
MOV R0,WEISHU2
CJNE R0,#00H,S801
MOV WEISHU2,#03H
MOV R4,#11111100B
S801:MOV DATA_OUT,#88H
CALL SEND
MOV DATA_OUT,R4
CALL SEND
MOV R0,A
MOV A,R4
RL A
RL A
RL A
MOV R4,A
MOV A,R0
DEC WEISHU2
SJMP OUT2
OUT21:SJMP OUT22
S2C:SJMP S2
;---------日期S1按下 加1 ----------
S81:CJNE A,#01H,S82
JB P1.6,S1C
JNB P1.5,S810
SJMP OUT21
S810:MOV R1,WEISHU2
CJNE R1,#00H,S811
INC YEAR
MOV R0,YEAR
CJNE R0,#100,TT2
MOV YEAR,#00H
TT2:MOV A,YEAR ;判断是否为闰年
MOV B,#4
DIV AB
MOV A,B
CJNE A,#0,OUT82 ;是否被四整除?,不整除则跳转
MOV DPTR,#TABLE1
RRT8: MOV A,MONTH
MOVC A,@A+DPTR
INC A
CJNE A,DAY,TTQ
DEC A
MOV DAY,A
SJMP OUT21
TTQ:JNC OUT21
DEC A
MOV DAY,A
SJMP OUT21
OUT82:MOV DPTR,#TABLE2
SJMP RRT8
S811:CJNE R1,#01H,S812
INC MONTH
MOV R0,MONTH
CJNE R0,#13,TT21
MOV MONTH,#01H
TT21:JMP TT2
S812:INC DAY
MOV A,YEAR ;判断是否为闰年
MOV B,#4
DIV AB
MOV A,B
CJNE A,#0,OUT8222 ;是否被四整除?,不整除则跳转
MOV DPTR,#TABLE1
RRT822:MOV A,MONTH
MOVC A,@A+DPTR
INC A
CJNE A,DAY,OUT22
MOV DAY,#01H
SJMP OUT22
OUT8222:MOV DPTR,#TABLE2
SJMP RRT822
OUT22:SJMP OUT23
;---------日期S2按下 减1 ----------
S82:CJNE A,#02H,OUT22
JB P1.6,S2C
JNB P1.5,S820
SJMP OUT22
S820:MOV R1,WEISHU2
CJNE R1,#00H,S821
DEC YEAR
MOV R0,YEAR
CJNE R0,#0FFH,TT23
MOV YEAR,#99
TT23:MOV A,YEAR ;判断是否为闰年
MOV B,#4
DIV AB
MOV A,B
CJNE A,#0,OUT823 ;是否被四整除?,不整除则跳转
MOV DPTR,#TABLE1
RRT83:MOV A,MONTH
MOVC A,@A+DPTR
INC A
CJNE A,DAY,TT
DEC A
MOV DAY,A
SJMP OUT22
TT:JNC OUT22
DEC A
MOV DAY,A
SJMP OUT22
OUT823:MOV DPTR,#TABLE2
SJMP RRT83
S821:CJNE R1,#01H,S822
DEC MONTH
MOV R0,MONTH
CJNE R0,#00H,TT24
MOV MONTH,#12
TT24:SJMP TT23
SJMP OUT22
S822:DEC DAY
MOV R0,DAY
CJNE R0,#00H,OUT22
MOV A,YEAR ;判断是否为闰年
MOV B,#4
DIV AB
MOV A,B
CJNE A,#0,OUT822 ;是否被四整除?,不整除则跳转
MOV DPTR,#TABLE1
RRT82:MOV A,MONTH
MOVC A,@A+DPTR
MOV DAY,A
SJMP OUT22
OUT822:MOV DPTR,#TABLE2
SJMP RRT82
SJMP OUT22
OUT23:POP A
JNB P3.3,$
RETI
;*******************************************************
;********从HD7279接受一个字节,高位在前*****************
;*******************************************************
RECEIVE:MOV R7,#8
SETB DAT ;P1口为输入状态,要至1
CLR CS
D2:CALL DELAY100
SETB CLK
CALL DELAY100
MOV A,DATA_IN
RL A
MOV DATA_IN,A
MOV C,DAT
MOV DATA_IN.0,C
CLR CLK
DJNZ R7,D2
CLR DAT ;接收完毕
CALL DELAY100
RET
;*******************************************
;******发送1个字节到HD7279,高位在前********
;*******************************************
SEND:PUSH A
MOV R7,#8;设定位计数器
CLR CS
CALL DELAY100
D1:MOV C,DATA_OUT.7
MOV DAT,C
SETB CLK
MOV A,DATA_OUT
RL A
MOV DATA_OUT,A
CALL DELAY100
CLR CLK
DJNZ R7,D1
CLR DAT ;发送完毕
POP A
RET
;***************************
;*********延时子程序********
;***************************
DELAY25:MOV R1,#250
D0:MOV R2,#100
DJNZ R2,$
DJNZ R1,D0
RET
;---------------------
DELAY100:MOV R0,#50
DJNZ R0,$
RET
TABLE1:DB 00,31,29,31,30,31,30,31,31,30,31,30,31 ;闰年每月的天数
TABLE2:DB 00,31,28,31,30,31,30,31,31,30,31,30,31
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -