📄 2051的时钟程序问题2051clk.asm
字号:
LCALL ADD1 ;调用加1子程序
MOV A,R3 ;取调整单元数据
CLR C ;清进位标志
CJNE A,#60H,HHH ;调整单元数据与60比较
HHH: JC SET4 ;调整单元数据小于60转SET4循环
LCALL CLR0 ;调整单元数据大于或等于60时清0
CLR C ;清进位标志
AJMP SET4 ;跳转到SET4循环
CLOSEDIS: SETB ET0 ;省电(LED不显示)状态。开T0中断
SETB TR0 ;开启T0定时器(开时钟)
CLOSE: JB P3.7,CLOSE ;无按键按下,等待。
LCALL DISPLAY ;有键按下,调显示子程序延时削抖
JB P3.7,CLOSE ;是干扰返回CLOSE等待
WAITH: JNB P3.7,WAITH ;等待键释放
LJMP START1 ;返回主程序(LED数据显示亮)
SETHH: CLR 00H ;分闪烁标志清除(进入调小时状态)
SETHH1: JNB P3.7,SET5 ;等待键释放
SETB 01H ;小时调整标志置1
SET6: JB P3.7,SET7 ;等待按键按下
LCALL DL05S ;有键按下延时0.5秒
JNB P3.7,SETOUT ;按下时间大于0.5秒退出时间调整
MOV R0,#79H ;按下时间小于0.5秒加1小时操作
LCALL ADD1 ;调加1子程序
MOV A,R3 ;
CLR C ;
CJNE A,#24H,HOUU ;计时单元数据与24比较
HOUU: JC SET6 ;小于24转SET6循环
LCALL CLR0 ;大于或等于24时清0操作
AJMP SET6 ;跳转到SET6循环
SETOUT: JNB P3.7,SETOUT1 ;调时退出程序。等待键释放
LCALL DISPLAY ;延时削抖
JNB P3.7,SETOUT ;是抖动,返回SETOUT再等待
CLR 01H ;清调小时标志
CLR 00H ;清调分标志
CLR 02H ;清闪烁标志
CLR TR1 ;关闭定时器T1
CLR ET1 ;关定时器T1中断
SETB TR0 ;开启定时器T0
SETB ET0 ;开定时器T0中断(计时开始)
LJMP START1 ;跳回主程序
SET1: LCALL DISPLAY ;键释放等待时调用显示程序(调分)
AJMP SET2 ;防止键按下时无时钟显示
SET3: LCALL DISPLAY ;等待调分按键时时钟显示用
AJMP SET4
SET5: LCALL DISPLAY ;键释放等待时调用显示程序(调小时)
AJMP SETHH1 ;防止键按下时无时钟显示
SET7: LCALL DISPLAY ;等待调小时按键时时钟显示用
AJMP SET6
SETOUT1: LCALL DISPLAY ;退出时钟调整时键释放等待
AJMP SETOUT ;防止键按下时无时钟显示
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 显示程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 显示数据在70H-75H单元内,用六位LED共阳数码管显示,P1口输出段码数据,P3口作
; 扫描控制,每个LED数码管亮1MS时间再逐位循环。
DISPLAY: MOV R1,#70H ;指向显示数据首址
MOV R5,#0FEH ;扫描控制字初值
;这是后加的;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;这是设定21点后每隔10分钟闪一次屏(20秒),到22点结束.
PLAY: mov a,71h ;秒,十位
cjne a,#0h,ettt ;0
sjmp ettt0
ettt: cjne a,#1h,etooo ;1
ettt0: mov a,72h ;分,个位
cjne a,#0h,etooo ;0
mov a,73h ;分,十位
cjne a,#0h,etooo1 ;0
sjmp etoooo
etooo1: cjne a,#1h,etooo2 ;1
sjmp etoooo
etooo2: cjne a,#2h,etooo3 ;2
sjmp etoooo
etooo3: cjne a,#3h,etooo4 ;3
sjmp etoooo
etooo4: cjne a,#4h,etooo5 ;4
sjmp etoooo
etooo5: cjne a,#5h,etooo ;5
etoooo: mov a,74h ;时,个位
cjne a,#1h,etooo ;1
mov a,75h ;时,十位
cjne a,#2h,etooo ;2
;设定时间到,所有字符闪烁;;;;;;;;;;;;;;;;;;;;;;;;;
etoo0: cjne r4,#0ah,etoo ;
etoo: jnc etoo1 ;
mov c,tr1
jc etoo1 ;调整时间时不闪烁
mov a,#0ffh ;
sjmp etoo2 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;早上8点闪一次(10秒)
etooo: mov a,71h ;秒,十位
cjne a,#0,etoo1
mov a,72h ;分,个位
cjne a,#0,etoo1
mov a,73h ;分,十位
cjne a,#0,etoo1
mov a,74h ;时,个位
cjne a,#8,etoo1
sjmp etoo0 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
etoo1: MOV A,R5 ;扫描字放入A
etoo2: MOV P3,A ;从P3口输出
MOV A,@R1 ;取显示数据到A
MOV DPTR,#TAB ;取段码表地址
MOVC A,@A+DPTR ;查显示数据对应段码
jb p3.5,eout0 ;是否是小时的十位
cjne a,#0c0h,eout0 ;是否是“0”
cjne r6,#17,eout00 ;r6是旋转数据地址,是否结束
mov r6,#11 ;如结束,则重新赋值
eout00: mov a,r6 ;
movc a,@a+dptr ;取旋转显示数据
inc r7 ;延时,防止旋转过快
cjne r7,#04bh,eout0
mov r7,#0
inc r6 ;指向下一显示数据地址
eout0:
cjne r4,#0ah,eout ;这是后加的,是为了双跳灯显示
eout: jnc eout1 ;秒计数是否到0ah
sjmp eoutt
eout1: cpl acc.7 ;准备在P1.7输出
jnb p3.3,eoutt ;与扫描显示同步
cpl acc.7
eoutt: MOV p1,A ;段码放入P1口
LCALL DL1MS ;显示1MS
mov p1,#0ffh ;防止拖尾
INC R1 ;指向下一地址
MOV A,R5 ;扫描控制字放入A
JNB ACC.5,ENDOUT ;ACC.5=0时一次显示结束
RL A ;A中数据循环左移
MOV R5,A ;放回R5内
AJMP PLAY ;跳回PLAY循环
ENDOUT: SETB P3.5 ;一次显示结束,P3口复位
MOV P1,#0FFH ;P1口复位
RET ;子程序返回
TAB:
db 0C0H,0CFH,92H,086H,8DH,0A4H,0A0H,0CEH,80H,84H,0FFH
;"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮"
db 0feh,0dfh,0efh,0f7h,0fbh,0fdh
;0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH
;共阳段码表 "0""1""2" "3""4""5""6""7" "8""9""不亮"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 延时程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;1MS延时程序,LED显示程序用
DL1MS: MOV 2ah,#14H
DL1: MOV 2bh,#19H
DL2: DJNZ 2bh,DL2
DJNZ 2ah,DL1
RET
;20MS延时程序,采用调用显示子程序以改善LED的显示闪烁现象
DS20MS: ACALL DISPLAY
ACALL DISPLAY
ACALL DISPLAY
RET
;延时程序,用作按键时间的长短判断
DL1S: LCALL DL05S
LCALL DL05S
RET
DL05S: MOV R3,#20H ;8毫秒*32=0.196秒
DL05S1: LCALL DISPLAY
DJNZ R3,DL05S1
RET
END ;程序结束
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -