📄 time1.asm
字号:
;***********************************
;博圆单片机培训[博圆单片机初学之路]
;2005年10月10日
;Email: bypxmcu@126.com
;本程序采用的是六位数[最好采用八位码数,在时钟分钟秒钟之间用短横线隔开,如23时45分02秒,写为23-45-02]
;使用P1.7[选择键]、P1.6[时钟增1]、P1.5[分钟增1]、P1.4[秒钟增1]
;*******************************************
SEC DATA 51H ;定义秒钟计数器使用51H内存区
MIN DATA 53H ;定义分钟计数器使用53H内存区
HOU DATA 55H ;定义时钟计数器使用55H内存区
;*********************************************
ORG 0000H
AJMP MAIN ;跳过中断地址
ORG 000BH
LJMP TIME ;调用计时中断子程序
ORG 0100H
MAIN: MOV SP,#60H ;初始化堆栈
;给定时器0赋初值
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 ;初始化时钟计数器
;***********************************************
;主程序区的主循环体
;数字显示程序主体
;入口参数:SEC[秒],MIN[分],HOU[时]
;时间传送参数SEC[秒],MIN[分],HOU[时]
;*************************************************
DSUP: ;扫描并显示秒钟的个位
MOV DPTR,#TAB1 ;获得第一字形码表的启始地址[主要是个数字]
MOV A,SEC ;从字形码表取出秒钟的个位显示字模
MOVC A,@A+DPTR ;查表
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11111110B;关闭其它位,点亮秒钟个位
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短
;扫描并显示秒钟的十位
MOV DPTR,#TAB2 ;获得第二字形码表的启始地址[主要是个数字]
MOV A,SEC ;从字形码表取出秒钟的十位显示字模
MOVC A,@A+DPTR ;查表
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11111101B;关闭其它位,点亮秒钟十位
LCALL YSH2S
;显示'——'
MOV A,#0BFH
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11111011B;关闭其它位,点亮秒钟十位
LCALL YSH2S
;扫描并显示分钟的个位
MOV DPTR,#TAB1
MOV A,MIN ;从字形码表取出个位分钟显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11110111B;关闭其它位,点亮分钟个位
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短
;扫描并显示分钟的十位
MOV DPTR,#TAB2
MOV A,MIN ;从字形码表取出十位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11101111B
LCALL YSH2S
;显示'——'
MOV A,#0BFH
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11011111B;关闭其它位,点亮秒钟十位
LCALL YSH2S
;扫描并显示时钟的个位
MOV DPTR,#TAB1
MOV A,HOU ;从字形码表取出个位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#10111111B
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短
;扫描并显示时钟的十位
MOV DPTR,#TAB2
MOV A,HOU ;从字形码表取出十位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#01111111B
LCALL YSH2S
JNB P1.7,KEY17
JNB P1.6,KEY16
JNB P1.5,KEY15
JNB P1.4,KEY14
AJMP DSUP ;转到主程序区的主循环体开始处
;******************************************************
;使用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
;*******************************************************
;使用P1.7[选择键]、P1.6[时钟增1]、P1.5[分钟增1]
;按下连在P1.5引脚上的按键调整分钟
;********************************************************
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口线用于显示数字
MOV P2,#11111110B;关闭其它位,点亮秒钟个位
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短
;扫描并显示秒钟的十位
MOV DPTR,#TAB2 ;获得第二字形码表的启始地址[主要是个数字]
MOV A,SEC ;从字形码表取出秒钟的十位显示字模
MOVC A,@A+DPTR ;查表
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11111101B;关闭其它位,点亮秒钟十位
LCALL YSH2S
;显示'——'
MOV A,#0BFH
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11111011B;关闭其它位,点亮秒钟十位
LCALL YSH2S
;扫描并显示分钟的个位
MOV DPTR,#TAB1
MOV A,MIN ;从字形码表取出个位分钟显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11110111B;关闭其它位,点亮分钟个位
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短
;扫描并显示分钟的十位
MOV DPTR,#TAB2
MOV A,MIN ;从字形码表取出十位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11101111B
LCALL YSH2S
;显示'——'
MOV A,#0BFH
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#11011111B
LCALL YSH2S
;扫描并显示时钟的个位
MOV DPTR,#TAB1
MOV A,HOU ;从字形码表取出个位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#10111111B
LCALL YSH2S ;短时间延时 这个时间的长短是关键如果显示有抖动的感觉请时间继续短
;扫描并显示时钟的十位
MOV DPTR,#TAB2
MOV A,HOU ;从字形码表取出十位显示字模
MOVC A,@A+DPTR
MOV P0,A ;将个位段码值送给P0口线用于显示数字
MOV P2,#01111111B
LCALL YSH2S
DJNZ R7,DISP
MOV R7,#0AH
RET
;**********************************************************
;以下为中断服务子程序 [s为秒单位]
;采定时器0计时每50ms中断一次,中断20次为1s,即 50X20=1000ms[1秒]
;有关定时器初值的计算请查阅理论部分
;;*********************************************************
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 ;中断返回
;****************************************************
;为了简化程序中复杂的计算法,本人在实际设计中构思了一个复杂点的字形码表,这对于现
;在的mcu[单片机来说不是困难的事],却在程序中简去复杂的计算过程。
;采用个位和十位分开建表,个位为TAB1,十位为TAB2。
;****************************************************
TAB1: ;个位60个字模码表
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H ; 0~9
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H ; 10~19
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H ; 20~29
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H ; 30~39
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H ; 40~49
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H ; 50~59
; 0 1 2 3 4 5 6 7 8 9
TAB2: ;十位10个字模码表
DB 0C0H,0C0H,0C0H,0C0H,0C0H,0C0H,0C0H,0C0H,0C0H,0C0H ;十位 0
DB 0F9H,0F9H,0F9H,0F9H,0F9H,0F9H,0F9H,0F9H,0F9H,0F9H ;十位 1
DB 0A4H,0A4H,0A4H,0A4H,0A4H,0A4H,0A4H,0A4H,0A4H,0A4H ;十位 2
DB 0B0H,0B0H,0B0H,0B0H,0B0H,0B0H,0B0H,0B0H,0B0H,0B0H ;十位 3
DB 099H,099H,099H,099H,099H,099H,099H,099H,099H,099H ;十位 4
DB 092H,092H,092H,092H,092H,092H,092H,092H,092H,092H ;十位 5
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -