📄 数字钟.asm
字号:
;数字钟
;P3.0、P3.1、P3.2接键盘;P1口接数码管的A-H;P2口接数码管的位码。
SECOND EQU 30H ;定义秒钟的内存地址为30H
MINITE EQU 31H ;定义分钟的内存地址为31H
HOUR EQU 32H ;定义小时的内存地址为32H
HOURK BIT P3.2 ;定义小时的加1按键为P3.2引脚
MINITEK BIT P3.1 ;定义分钟的加1按键为P3.1引脚
SECONDK BIT P3.0 ;定义秒钟的加1按键为P3.0引脚
DISPBUF EQU 40H ;DISPBUF=40H
DISPBIT EQU 48H ;位码值-
T2SCNTA EQU 49H ;定义T2SCNTA为计数单元,计数范围0-100
T2SCNTB EQU 4AH ;单元T2SCNTB为计数单元,计数范围0-5
TEMP EQU 4BH ;
ORG 0000H ;程序起始地址
LJMP START ;无条件跳转至START
ORG 000BH ;定时/计数器T0的矢量地址
LJMP INT_T0 ;无条件跳转至INT_T0,定时/计数器T0中断服务子程序
START:MOV SECOND,#00H ;秒钟初始化为0
MOV MINITE,#00H ;分钟初始化为0
MOV HOUR,#12 ;小时初始化为12
MOV DISPBIT,#00H ;DISPBIT初始化为0
MOV T2SCNTA,#00H ;T2SCNTA初始化为0
MOV T2SCNTB,#00H ;T2SCNTB初始化为0
MOV TEMP,#07H ;第一个数码管(左边)的位码
LCALL DISP ;调用DISP子程序
MOV TMOD,#01H ;定时/计数器T0的工作方式为方式1,16为计数器
MOV TH0,#(65536-2000)/256 ;计数器初值为0F830H,2ms
MOV TL0,#(65536-2000) MOD 256
SETB TR0 ;启动定时/计数器T0
SETB ET0 ;定时/计数器T0开溢出中断
SETB EA ;CPU开总中断
WT:JB SECONDK,NK1 ;SECONDK=1时,跳转至NK1
LCALL DELY10MS ;SECONDK=0时,调用10毫秒按键仿抖动延时子程序
JB SECONDK,NK1 ;SECONDK=1时,跳转至NK1
INC SECOND ;SECOND加1
MOV A,SECOND ;SECOND的值送A
CJNE A,#60,NS60 ;A的值不为60,跳转至NS60
MOV SECOND,#00H ;A的值为60,则SECOND初始化为0
NS60:LCALL DISP ;调用DISP
JNB SECONDK,$ ;SECONDK=0时,原地踏步
;SECONDK=1时,执行NK1
NK1:JB MINITEK,NK2 ;MINITEK=1时,跳转至NK2
LCALL DELY10MS ;MINITEK=0时,调用10毫秒按键仿抖动延时子程序
JB MINITEK,NK2 ;MINITEK=1时,跳转至NK2
INC MINITE ;MINITE加1
MOV A,MINITE ;MINITE的值送A
CJNE A,#60,NM60 ;A的值不为60时,跳至NM60
MOV MINITE,#00H ;A的值为60时,MINITE初始化为0
NM60:LCALL DISP ;调用DISP
JNB MINITEK,$ ;MINITE=0时,原地踏步
;MINITE=1时,执行NK2
NK2:JB HOURK,NK3 ;HOURK=1时,跳转至NK3
LCALL DELY10MS ;HOURK=0时,调用10毫秒按键仿抖动延时子程序
JB HOURK,NK3 ;HOURK=1时,跳转至NK3
INC HOUR ;HOUR加1
MOV A,HOUR ;HOUR的值送A
CJNE A,#24,NH24 ;A的值不为24时,跳转至NH24
MOV HOUR,#00H ;A的值为24时,HOUR初始化为0
NH24:LCALL DISP ;调用DISP
JNB HOURK,$ ;HOURK=0时,原地踏步
;HOURK=1时,执行NK3
NK3:LJMP WT ;无条件跳转至WT
;10毫秒按键仿抖动延时子程序
DELY10MS:MOV R6,#10
D1:MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
;各个位的数值分离子程序,均为段码值所对应的十进制数。
DISP:MOV A,#DISPBUF ;DISPBUF的值给A=40H
ADD A,#8 ;A加8后,给A=48H
DEC A ;A减1,即A=47H
MOV R1,A ;A的值给R1,即R1=47H
MOV A,HOUR ;HOUR的值给A
MOV B,#10 ;10给B
DIV AB ;A除以B
MOV @R1,A ;商的值在A中,A的值给R1的值所对应的地址(47H)空间
DEC R1 ;R1减1,即R1=46H
MOV A,B ;余数值在B中,B的值给A
MOV @R1,A ;A的值给R1的值所对应的地址(46H)空间
DEC R1 ;R1减1
MOV A,#10 ;10给A
MOV @R1,A ;A的值给R1的值所对应的地址(45H)空间
DEC R1 ;R1减1
MOV A,MINITE ;MINITE的值给A
MOV B,#10 ;10给B
DIV AB ;A除以B
MOV @R1,A ;商在A中,A的值给R1的值所对应的地址(44H)空间
DEC R1 ;R1减1
MOV A,B ;余数在B中,B的值给A
MOV @R1,A ;A的值给R1的值所对应的地址(43H)空间
DEC R1 ;R1减1
MOV A,#10 ;10给B
MOV @R1,A ;A的值给R1的值所对应的地址(42H)空间
DEC R1 ;R1减1
MOV A,SECOND ;SECOND的值给A
MOV B,#10 ;10给B
DIV AB ;A除以B
MOV @R1,A ;商在A中,A的值给R1的值所对应的地址(41H)空间
DEC R1 ;R1减1
MOV A,B ;余数在B中,B的值给A
MOV @R1,A ;A的值给R1的值所对应的地址(40H)空间
DEC R1 ;R1减1
RET
;定时/计数器T0中断服务子程序
INT_T0:MOV TH0,#(65536-2000)/256 ;重新初始化计数器为0F830H,2ms
MOV TL0,#(65536-2000) MOD 256
MOV A,#DISPBUF ;DISPBUF的值送A=40H
ADD A,DISPBIT ;A的值加DISPBIT的值给A
MOV R0,A ;A的值送R0
MOV A,@R0 ;把R0的值所对应的地址中的内容给A
MOV DPTR,#TABLE ;TABLE的首地址给DPTR
MOVC A,@A+DPTR ;查表,程序存储器
MOV P0,A ;A的值给P0口
MOV A,DISPBIT ;DISPBIT的值给A
MOV DPTR,#TAB ;TAB的首地址给DPTR
MOVC A,@A+DPTR ;查表,程序存储器
MOV P2,A ;A的值给P2口
INC DISPBIT ;DISPBIT加1
MOV A,DISPBIT ;DISPBIT的值给A
CJNE A,#08H,KNA ;A不为8,则跳转至KNA
MOV DISPBIT,#00H ;A=8,则DISPBIT初始化为0
KNA:INC T2SCNTA ;T2SCNTA加1
MOV A,T2SCNTA ;T2SCNTA的值给A
CJNE A,#100,DONE ;A不为100,则跳转至DONE
MOV T2SCNTA,#00H ;A=100时,T2SCNA初始化为0
INC T2SCNTB ;T2SCNTB加1
MOV A,T2SCNTB ;T2SCNTB的值给A
CJNE A,#05H,DONE ;A不为5时,跳转至DONE
MOV T2SCNTB,#00H ;A=5时,T2SCNTB初始化为0
INC SECOND ;SECOND加1
MOV A,SECOND ;SECOND的值给A
CJNE A,#60,NEXT ;A的值不为60,跳转至NEXT
MOV SECOND,#00H ;A=60时,SECOND初始化为0
INC MINITE ;MINITE加1
MOV A,MINITE ;MINITE的值给A
CJNE A,#60,NEXT ;A的值不为60时,跳转至NEXT
MOV MINITE,#00H ;A=60时,MINITE初始化为0
INC HOUR ;HOUR加1
MOV A,HOUR ;HOUR的值给A
CJNE A,#24,NEXT ;A的值不为24时,跳转至NEXT
MOV HOUR,#00H ;A=24时,HOUR初始化为0
NEXT:LCALL DISP ;无条件跳转至DISP
DONE:RETI ;中断返回
;
TABLE:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H ;0-9以及-的段码值
TAB:DB 07H,06H,05H,04H,03H,02H,01H,00H ;各个数码管的选中码即位码
END ;程序结束
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -