51单片机八位共阴极数码管时钟(汇编)

SEC DATA 51H ;定义秒钟计数器使用51H内存区
MIN DATA 53H
HOU DATA 55H
MINAL DATA 57H
HOUAL DATA 59H
LATCH1 BIT P2.2
LATCH2 BIT P2.3
ORG 0000H
AJMP MAIN
ORG 000BH
LJMP TIME
ORG 0100H
MAIN: MOV SP,#60H
MOV TMOD,#001H ;使用16位无分频模式[方式1 M1=0 M0=1]
MOV TH0,#04CH ;初始化定时器0的溢出间隔时间为50ms
MOV TL0,#000H ;TH为位 TL为低位
SETB EA ;启用全局中断
SETB ET0 ;启用定时器0中断
SETB TR0 ;启用定时器0
MOV R0,#014H ;初始化定时计数为20[014H]次,014H为十六进制码,请查阅[附录12]
MOV R1,#00H
MOV R6,#0AH ;
MOV R7,#0AH
MOV SEC,#00H ;初始化秒钟计数器
MOV MIN,#00H
MOV HOU,#00H ;

DSUP:

MOV DPTR,#TAB1 ;获得第一字形码表的启始地址[主要是个数字]
MOV A,SEC ;从字形码表取出秒钟的个位显示字模
MOVC A,@A+DPTR ;查表
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#01111111B;关闭其它位,点亮秒钟个位
SETB LATCH2
CLR LATCH2
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短

;扫描并显示秒钟的十位

MOV DPTR,#TAB2 ;获得第二字形码表的启始地址[主要是个数字]
MOV A,SEC ;从字形码表取出秒钟的十位显示字模
MOVC A,@A+DPTR ;查表
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#10111111B;关闭其它位,点亮秒钟十位
SETB LATCH2
CLR LATCH2
LCALL YSH2S

;显示'——'

MOV A,#40H

MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11011111B;关闭其它位,点亮秒钟十位
SETB LATCH2
CLR LATCH2
LCALL YSH2S
;扫描并显示分钟的个位
MOV DPTR,#TAB1
MOV A,MIN ;从字形码表取出个位分钟显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11101111B;关闭其它位,点亮分钟个位
SETB LATCH2
CLR LATCH2
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短

;扫描并显示分钟的十位

MOV DPTR,#TAB2
MOV A,MIN ;从字形码表取出十位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1

CLR LATCH1
MOV P0,#11110111B
SETB LATCH2
CLR LATCH2
LCALL YSH2S

;显示'——'

MOV A,#40H

MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11111011B;关闭其它位,点亮秒钟十位
SETB LATCH2
CLR LATCH2
LCALL YSH2S

;扫描并显示时钟的个位

MOV DPTR,#TAB1
MOV A,HOU ;从字形码表取出个位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11111101B
SETB LATCH2
CLR LATCH2
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短

;扫描并显示时钟的十位

MOV DPTR,#TAB2
MOV A,HOU ;从字形码表取出十位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11111110B
SETB LATCH2
CLR LATCH2
LCALL YSH2S

JNB P1.7,KEY17
JNB P1.6,KEY16
JNB P1.5,KEY15
JNB P1.4,KEY14

;闹钟程序
CJNE HOU,HOUAL,BACK
CJNE MIN,MINAL,BACK
LJMP ALARM

BACK: AJMP DSUP ;转到主程序区的主循环体开始处


;闹钟程序
ALARM: JNB ET0,KEY17_
CLR ET0 ;停止定时器0中断
CLR EA ;关闭全局中断
MOV R6,#0BH ;给用来控制KEY16,KEY15赋初值,允许KEY16,KEY15两按下产生动作
LJMP DSUP
RET

;******************************************************

;使用P1.7[选择键]、P1.6[时钟增1]、P1.5[分钟增1]

;按下连在P1.7引脚上的按键进入时钟和分钟调整

;******************************************************

KEY17: JNB ET0,KEY17_
CLR ET0 ;停止定时器0中断
CLR EA ;关闭全局中断
MOV R6,#0BH ;给用来控制KEY16,KEY15赋初值,允许KEY16,KEY15两按下产生动作
LJMP DSUP
RET



KEY17_:MOV R6,#0AH ;禁用KEY16,KEY15两键工作
SETB ET0 ;启用定时器0
SETB EA ;开启全局中断
LJMP DSUP
RET

;*****************************************************

;使用P1.7[选择键]、P1.6[时钟增1]、P1.5[分钟增1]

;按下连在P1.6引脚上的按键调整时钟

;*****************************************************

KEY16:

CJNE R6,#0BH,KEY16_
INC HOU ;时钟加1
ACALL DISP ;调用显示程序
MOV R1,HOU
CJNE R1,#018H,KEY16_
MOV HOU,#00H

KEY16_: LJMP DSUP
RET

KEY15:

CJNE R6,#0BH,KEY15_

INC MIN
ACALL DISP
MOV R1,MIN
CJNE R1,#03CH,KEY15_
MOV MIN,#00H
KEY15_:LJMP DSUP
RET

;*******************************************************

;使用P1.7[选择键]、P1.6[时钟增1]、P1.5[分钟增1]、P1.4[秒钟增1]

;按下连在P1.4引脚上的按键调整分钟

;********************************************************
KEY14:
CJNE R6,#0BH,KEY14_
INC SEC
ACALL DISP
MOV R1,SEC
CJNE R1,#03CH,KEY14_
MOV SEC,#00H
KEY14_:LJMP DSUP
RET

;*************************************************************

;延时子程序

;用于控制显示器的扫描速度

;**************************************************************

YSH2S: MOV R3,#01H
LOOP2: MOV R4,#014H ;修改这里的参数可以改显示扫描速的快和慢
LOOP21: MOV R5,#05AH
XHD3: DJNZ R5,XHD3
DJNZ R4,LOOP21
DJNZ R3,LOOP2
RET
;*************************************************************

;计时子程序

;入口参数:SEC[秒],MIN[分],HOU[时]

;出口参数:SEC[秒],MIN[分],HOU[时]

;以上三个参传递给字符显示程序

;***************************************************************

TIME4: ;计时[每秒计时一次]

CPL P1.0 ;指示灯一秒显一次[熄一秒亮一秒]
INC SEC ;秒钟增1
MOV R1,SEC
CJNE R1,#03CH,TIME5 ;R1与立即数60秒比较,满60秒了吗?如果没到跳到TIME5处执行
MOV SEC,#00H ;满60秒给秒钟变量清0
INC MIN ;分钟加1
MOV R1,MIN
CJNE R1,#03CH,TIME5 ;满60分了吗?如果没满跳到TIME5处执行
MOV MIN,#00H ;满60分给分钟变量清0
INC HOU ;时钟加1
MOV R1,HOU
CJNE R1,#18H,TIME5 ;满24小时了吗?如果没满跳到TIME5处执行
MOV HOU,#00H ;满24小时给时钟变清0
;在此如你做的是日期你可以加入日变量、月变量和年变量
TIME5:RET

;**********************************************************

;调时时调用的显示子程序

;入口参数:SEC[秒],MIN[分],HOU[时]

;*********************************************************

DISP:

MOV DPTR,#TAB1 ;获得第一字形码表的启始地址[主要是个数字]
MOV A,SEC ;从字形码表取出秒钟的个位显示字模
MOVC A,@A+DPTR ;查表
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#01111111B;关闭其它位,点亮秒钟个位
SETB LATCH2
CLR LATCH2
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短
;扫描并显示秒钟的十位
MOV DPT

R,#TAB2 ;获得第二字形码表的启始地址[主要是个数字]
MOV A,SEC ;从字形码表取出秒钟的十位显示字模
MOVC A,@A+DPTR ;查表
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#10111111B;关闭其它位,点亮秒钟十位
SETB LATCH2
CLR LATCH2
LCALL YSH2S
JMP NEXT1
DISPJMP2: LJMP DISP
NEXT1:
;显示'——'
MOV A,#40H
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11011111B;关闭其它位,点亮秒钟十位
SETB LATCH2
CLR LATCH2
LCALL YSH2S
;扫描并显示分钟的个位
MOV DPTR,#TAB1
MOV A,MIN ;从字形码表取出个位分钟显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11101111B;关闭其它位,点亮分钟个位
SETB LATCH2
CLR LATCH2
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短
;扫描并显示分钟的十位
MOV DPTR,#TAB2
MOV A,MIN ;从字形码表取出十位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11110111B
SETB LATCH2
CLR LATCH2
LCALL YSH2S
JMP NEXT2

DISPJMP1: LJMP DISPJMP2
NEXT2:
;显示'——

MOV A,#40H
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11111011B
SETB LATCH2
CLR LATCH2
LCALL YSH2S
;扫描并显示时钟的个位
MOV DPTR,#TAB1
MOV A,HOU ;从字形码表取出个位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11111101B
SETB LATCH2
CLR LATCH2
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短
;扫描并显示时钟的十位
MOV DPTR,#TAB2
MOV A,HOU ;从字形码表取出十位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
SETB LATCH1
CLR LATCH1
MOV P0,#11111110B
SETB LATCH2
CLR LATCH2
LCALL YSH2S
DJNZ R7,DISPJMP1
MOV R7,#0AH
RET
TIME: CLR ET0 ;关闭定时器0中断
CLR TR0 ;关闭定时器0
MOV TH0,#04CH ;初始化定时器0的溢出间隔时间[50ms]

MOV TL0,#00H ;TH为位 TL为低位
DJNZ R0,TIME2 ;20次计数到了吗?没到跳到程序[TIME2]处执行
LCALL TIME4 ;20次计数已到调用计时子程序计时一次[一秒]
MOV R0,#014H ;给R0赋20[014H]次的初值,以便下一秒钟的计数



TIME2:SETB TR0 ;开启定时器0

SETB ET0 ;允许定时器0中断

RETI ;中断返回

TAB1: ;个位60个字模码表

DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ; 0~9

DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ; 10~19

DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ; 20~29

DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ; 30~39

DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ; 40~49

DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ; 50~59

; 0 1 2 3 4 5 6 7 8 9

TAB2: ;十位10个字模码表

DB 3FH,3FH,3FH,3FH,3FH,3FH,3FH,3FH,3FH,3FH ;十位 0

DB 06H,06H,06H,06H,06H,06H,06H,06H,06H,06H ;十位 1

DB 5BH,5BH,5BH,5BH,5BH,5BH,5BH,5BH,5BH,5BH ;十位 2

DB 4FH,4FH,4FH,4FH,4FH,4FH,4FH,4FH,4FH,4FH ;十位 3

DB 66H,66H,66H,66H,66H,66H,66H,66H,66H,66H ;十位 4

DB 6DH,6DH,6DH,6DH,6DH,6DH,6DH,6DH,6DH,6DH ;十位 5
END

相关文档
最新文档