设计分享|基于51单片机的数字时钟(汇编)

2022-07-27 18:49:25 浏览数 (1)

具体功能:

上电后滚动显示年、月、日、时、分,最后进入秒计时,通过四个按键可对时间进行设置操作。

设计介绍

单片机介绍

51单片是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C51为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。具有以下标准功能:8k字节Flash,512字节RAM,32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口。另外 STC89X51 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35Mhz,6T/12T可选。

设计思路

文献研究法:搜集整理相关单片机智能手环系统相关研究资料,认真阅读文献,为研究做准备;

调查研究法:通过调查、分析、具体试用等方法,发现单片机智能手环系统的现状、存在问题和解决办法;

比较分析法:比较不同单片机智能手环系统的具体原理,以及同一类传感器性能的区别,分析单片机智能手环系统的研究现状与发展前景;

软硬件设计法:通过软硬件设计实现具体硬件实物,最后测试各项功能是否满足要求。

设计内容

01

仿真图

本设计利用protues8.7软件实现仿真设计,具体如图。

Protues也是在单片机仿真设计中常用的设计软件之一,通过设计出硬件电路图,及写入驱动程序,就能在不实现硬件的情况进行电路调试。另外,protues还能实现PCB的设计,在仿真中也可以与KEIL实现联调,便于程序的调试,且支持多种平台,使用简单便捷。

02

程序

本设计由汇编语言编写,主代码具体如下:

代码语言:javascript复制
DISBEG    EQU  30H          ;显示单元首地址
CALB        EQU  P1.7         ;报警喇叭
TIMCON     EQU  2FH        ;存放报时次数
ORG    0000H                     ;程序开始
LJMP        MAIN
ORG     0003H           ;关外中断0
RETI
ORG    000BH            ;定时器T0中断程序入口
LJMP        INTT0            ;跳至INTTO执行
ORG     0013H            ;关中断1
RETI
ORG        001BH                ;定时器T1中断程序入口
LJMP        INTT1          ;跳至INTT1执行
ORG     0023H            ;关串行中断
RETI
TAB:   DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,88H,0BFH
;共阳段码表          "0""1""2" "3""4""5""6""7" "8""9""不亮""A""-"
I_TAB:  DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0C6H,0BFH,88H
; 显示数  "0    1    2    3    4   5   6   7   8    9  不亮  C   -    A  "
; 内存数  "0    1    2    3    4   5   6   7   8    9  0AH  0BH 0CH  0DH "
;STAB表,启动时显示2008年10月14日、A06-3-67(学号)用
STAB:   DB 0AH,0AH,0AH,0AH,0AH,0AH,07H,06H,0CH,03H,0CH,06H,00H,0DH,0AH,0AH
DB 04H,01H,0CH,00H,01H,0CH,08H,00H,00H,02H,0AH,0AH,0AH,0AH,0AH,0AH
DLY1M:   MOV    R6,#14H        ;1毫秒延时
DL_LOOP:    MOV     R7,#19H
DL_LOOP1:   DJNZ     R7,DL_LOOP1
DJNZ     R6,DL_LOOP
RET
DLY20M:  CLR     CALB         ;20毫秒延时
LCALL     D_II_PLAY
LCALL    D_II_PLAY
LCALL    D_II_PLAY
SETB     CALB
RET
DL_LOOPS:  LCALL     DL05S
LCALL     DL05S
RET
DL05S:     MOV       R3,#20H           ;8毫秒*32=0.196秒
DL05S1:     LCALL     D_II_PLAY
DJNZ      R3,DL05S1
RET
;程序开始                 ;;
;整点报时用
CTIME:     MOV      A,#10H
MOV       B,79H
MUL      AB
ADD      A,78H
MOV      TIMCON,A
CLOOP:      LCALL    DLY20M
LCALL    DL_LOOPS
LCALL    DL_LOOPS
LCALL      DL_LOOPS
DJNZ     TIMCON,CLOOP
CLR      08H            ;清整点报时标志
AJMP    MLOOP1
;主程序开始
MAIN:      LCALL ST                 ;上电显示年月日及班级学号
MOV       R0,#00H        ;清00H-7FH内存单元
MOV       R7,#80H        ;
MLOOP:     MOV       @R0,#00H        ;
INC       R0              ;
DJNZ      R7,MLOOP      ;
MOV       20H,#00H       ;清20H(标志用)
MOV       7AH,#0AH       ;放入"熄灭符"数据
MOV     TMOD,#11H      ;设T0、T1为16位定时器
MOV       TL0,#0B0H     ;50MS定时初值(T0计时用)
MOV       TH0,#3CH       ;50MS定时初值
MOV       TL1,#0B0H     ;50MS定时初值(T1闪烁定时用)
MOV       TH1,#3CH      ;50MS定时初值
SETB      EA               ;总中断开放
SETB      ET0              ;允许T0中断
SETB      TR0              ;开启T0定时器
MOV       R4,#14H          ;1秒定时用计数值(50MS×20)
MOV       DISBEG,#70H     ;显示单元为70-75H
;以下主程序循环
MLOOP1:   LCALL     D_II_PLAY       ;调用显示子程序
JNB     P1.0,T_SETSC    ;P1.0口为0时转时间调整程序
JNB       P1.1,DLY5       ;秒表功能,P1.1按键调时时作减1加能
JNB       P1.2,FUNBT     ;秒表STOP,PUSE,CLR
JNB       P1.3,TSET       ;定时闹铃设定
JB       08H,  CTIME
AJMP      MLOOP1       ;P1.0口为1时跳回MLOOP1
FUNBT:    LJMP      DLY6
;以下闹铃时间设定程序,按P1.3进入设定
TSET:     LCALL     DLY20M
JB        P1.3,MLOOP1    ;
TS_LOOP:    JNB       P1.3,TS_LOOP    ;等待键释放
JB       05H,CLRBELL    ;闹铃已开的话,关闹铃
MOV      DISBEG,#50H    ;进入闹铃设定程序,显示50-55H闹钟定时单元
MOV       50H,#0CH       ;"-"   闹铃设定时显示格式00:00: -
MOV       51H,#0AH        ;"黑"
MINCHG:   SETB      EA
LCALL     D_II_PLAY
JNB      P1.2,DLY1        ;分加1
JNB      P1.0,DLY3        ;分减1
JNB      P1.3,DLY       ;进入时调整
AJMP    MINCHG
CLRBELL:    CLR      05H            ;关闹铃标志
CLR      CALB
AJMP      MLOOP1
DLY:        LCALL     DLY20M        ;消抖
JB      P1.3, MINCHG
LJMP      DLY8           ;进入时调整
T_SETSC:     LJMP     R_SETTIM       ;转到时间调整程序R_SETTIM
DLY1:        LCALL     DLY20M        ;消抖
JB      P1.2, MINCHG
DLY2:      LCALL     D_II_PLAY      ;等键 释放
JNB       P1.2, DLY2
CLR       EA
MOV       R0,#53H        ;
LCALL     ADD_1        ;闹铃设定分加1
MOV     A,R3          ;分数据放入A
CLR       C               ;清进位标志
CJNE      A,#60H,ADD_M  ;
ADD_M:     JC       MINCHG         ;小于60分时返回
ACALL    CLR_H          ;大于或等于60分时分计时单元清0
AJMP      MINCHG
DLY3 :     LCALL     DLY20M        ;消抖
JB      P1.0, MINCHG
DLY4:      LCALL     D_II_PLAY        ;等键 释放
JNB       P1.0, DLY4
CLR       EA
MOV      R0,#53H        ;
LCALL     SUB_M         ;闹铃设定分减1
LJMP    MINCHG
;以下秒表功能/时钟转换程序
;按下P1.1 可进行功能转换
DLY5:     LCALL     DLY20M
JB        P1.1,T_MLOOP1
JNB       P1.1,$
CPL       03H
JNB       03H,DIS_SET
MOV       DISBEG,#60H    ;显示秒表数据单元
MOV       60H,#00H
MOV      61H,#00H
MOV       62H,#00H
MOV       63H,#00H
MOV       64H,#00H
MOV       65H,#00H
MOV       TL1,#0F0H     ;10MS定时初值()
MOV       TH1,#0D8H      ;10MS定时初值
SETB      TR1
SETB      ET1
T_MLOOP1:  LJMP      MLOOP1
DIS_SET:  MOV       DISBEG,#70H    ;显示时钟数据单元
CLR       ET1
CLR       TR1
T_MLOOP11:  LJMP      MLOOP1
;以下秒表暂停清零功能程序
;按下P1.2暂停或清0,按下P1.1退出秒表回到时钟计时
DLY6:     LCALL     DLY20M
JB        P1.2,T_MLOOP11
T_EST11:     JNB       P1.2,T_EST11
CLR       ET1
CLR       TR1
T_EST22:     JNB      P1.1,DLY5
JB       P1.2,T_EST21
LCALL     DLY20M
JB        P1.2,T_EST22
T_EST55:     JNB       P1.2,T_EST51
MOV       60H,#00H
MOV       61H,#00H
MOV       62H,#00H
MOV       63H,#00H
MOV       64H,#00H
MOV       65H,#00H
T_EST33:   JNB      P1.1,DLY5
JB       P1.2,T_EST31
LCALL     DLY20M
JB        P1.2,T_EST33
T_EST44:     JNB       P1.2,T_EST41
SETB      ET1
SETB      TR1
AJMP      MLOOP1
;以下键等待释放时显示不会熄灭用
T_EST411:    LCALL     D_II_PLAY
AJMP      T_EST11
T_EST21:     LCALL     D_II_PLAY
AJMP      T_EST22
T_EST31:   LCALL     D_II_PLAY
AJMP      T_EST33
T_EST41:    LCALL     D_II_PLAY
AJMP      T_EST44
T_EST51:    LCALL     D_II_PLAY
AJMP      T_EST55
; 1秒计时程序
;T0中断服务程序
INTT0:     PUSH      ACC           ;累加器入栈保护
PUSH      PSW           ;状态字入栈保护
CLR       ET0          ;关T0中断允许
CLR       TR0             ;关闭定时器T0
MOV       A,#0B7H         ;中断响应时间同步修正
ADD       A,TL0           ;低8位初值修正
MOV       TL0,A           ;重装初值(低8位修正值)
MOV       A,#3CH          ;高8位初值修正
ADDC      A,TH0          
MOV       TH0,A           ;重装初值(高8位修正值)
SETB      TR0             ;开启定时器T0
DJNZ      R4, I_INT0        ;20次中断未到中断退出
A_DDS:    MOV    R4,#14H          ;20次中断到(1秒)重赋初值

CPL       07H           ;闹铃时间隔呜叫用
MOV     R0,#71H        ;指向秒计时单元(71H-72H)
ACALL    ADD_1          ;调用加1程序(加1秒操作)
MOV     A,R3                ;秒数据放入A(R3为2位十进制数组合)
CLR       C                   ;清进位标志
CJNE      A,#60H,A_DDM     
A_DDM:    JC      I_INT0               ;小于60秒时中断退出
ACALL    CLR_H             ;大于或等于60秒时对秒计时单元清0
MOV    R0,#77H             ;指向分计时单元(76H-77H)
ACALL    ADD_1             ;分计时单元加1分钟
MOV     A,R3                ;分数据放入A
CLR       C                   ;清进位标志
CJNE      A,#60H,A_DDH      ;
A_DDH:   JC       I_INT0               ;小于60分时中断退出
ACALL     CLR_H            ;大于或等于60分时分计时单元清0
LCALL     DLY20M            ;正点报时
SETB     08H
MOV    R0,#79H             ;指向小时计时单元(78H-79H)
ACALL     ADD_1             ;小时计时单元加1小时
MOV       A,R3                ;时数据放入A
CLR       C                   ;清进位标志
CJNE      A,#24H,RSTART       ;
RSTART:   JC        I_INT0               ;小于24小时中断退出
ACALL    CLR_H              ;大于或等于24小时小时计时单元清0
I_INT0:     MOV       72H,76H             ;中断退出时将分、时计时单元数据移
MOV       73H,77H             ;入对应显示单元
MOV       74H,78H             ;
MOV       75H,79H             ;
LCALL    BELL
POP     PSW                 ;恢复状态字(出栈)
POP       ACC                 ;恢复累加器
SETB      ET0                 ;开放T0中断
RETI                        ;中断返回
;闪动调时程序秒表功能程序
;T1中断服务程序,用作时间调整时调整单元闪烁指示或秒表计时
INTT1:       PUSH      ACC              ;中断现场保护
PUSH      PSW               
JB         03H, R_ADDS       ;=1时秒表
MOV     TL1,   #0B0H      ;装定时器T1定时初值
MOV       TH1,   #3CH       
DJNZ      R2,I_INT1         ;0.3秒未到退出中断(50MS中断6次)
MOV       R2,#06H           ;重装0.3秒定时用初值
CPL       02H               ;0.3秒定时到对闪烁标志取反
JB         02H,FLASH0        ;02H位为1时显示单元"熄灭"
MOV       72H,76H           ;02H位为0时正常显示
MOV       73H,77H           
MOV       74H,78H          
MOV       75H,79H          
I_INT1:      POP      PSW               ;恢复现场
POP       ACC               
RETI                        ;中断退出
FLASH0:    JB        01H,FLASH1        ;01H位为1时,转小时熄灭控制
MOV      72H,7AH           ;01H位为0时,"熄灭符"数据放入分
MOV     73H,7AH          ;显示单元(72H-73H),将不显示分数据
MOV      74H,78H           
MOV      75H,79H           
AJMP     I_INT1            ;转中断退出
FLASH1:     MOV       72H,76H           ;01H位为1时,"熄灭符"数据放入小时MOV      73H,77H           ;显示单元(74H-75H),小时将不显示
MOV      74H,7AH       
MOV       75H,7AH     
AJMP     I_INT1            ;转中断退出
R_ADDS :    CLR      TR1
MOV       A,#0F7H           ;中断响应时间同步修正,重装初值(10ms)
ADD       A,TL1             ;低8位初值修正
MOV       TL1,A             ;重装初值(低8位修正值)
MOV       A,#0D8H            ;高8位初值修正
ADDC      A,TH1         
MOV       TH1,A             ;重装初值(高8位修正值)
SETB      TR1               ;开启定时器T0
MOV     R0,#61H             ;指向秒计时单元(71H-72H)
ACALL     ADD_1              ;调用加1程序(加1秒操作)
CLR       C                  
MOV       A,R3               
JZ        R_ADDM             ;加1后为00,C=0
AJMP      I_INT01              ;加1后不为00,C=1
R_ADDM:    ACALL     CLR_H             ;大于或等于60秒时对秒计时单元清0
MOV    R0,#63H             ;指向分计时单元(76H-77H)
ACALL     ADD_1              ;分计时单元加1分钟
MOV     A,R3               ;分数据放入A
CLR       C                   ;清进位标志
CJNE      A,#60H,R_ADDH     
R_ADDH:   JC       I_INT01             ;小于60分时中断退出
LCALL     CLR_H             ;大于或等于60分时分计时单元清0
MOV    R0,#65H             ;指向小时计时单元(78H-79H)
ACALL     ADD_1              ;小时计时单元加1小时

I_INT01:    POP     PSW                 ;恢复状态字(出栈)
POP       ACC                 ;恢复累加器
RETI                        ;中断返回            ;
; 加1子 程 序
ADD_1:     MOV    A,@R0           ;取当前计时单元数据到A
DEC    R0              ;指向前一地址
SWAP      A               ;A中数据高四位与低四位交换
ORL     A,@R0           ;前一地址中数据放入A中低四位
ADD    A,#01H          ;A加1操作
DA        A               ;十进制调整
MOV       R3,A            ;移入R3寄存器
ANL     A,#0FH          ;高四位变0
MOV     @R0,A           ;放回前一地址单元
MOV    A,R3            ;取回R3中暂存数据
INC       R0              ;指向当前地址单元
SWAP    A               ;A中数据高四位与低四位交换
ANL     A,#0FH          ;高四位变0
MOV    @R0,A           ;数据放入当削地址单元中
RET                        ;子程序返回
;分减1子 程 序              ;;
SUB_M:    MOV    A,@R0           ;取当前计时单元数据到A
DEC    R0              ;指向前一地址
SWAP      A               ;A中数据高四位与低四位交换
ORL     A,@R0           ;前一地址中数据放入A中低四位
JZ        SUB_M1
DEC    A               ;A减1操作
SUB_M11:   MOV      3,A              ;移入R3寄存器
ANL     A,#0FH          ;高四位变0
CLR       C               ;清进位标志
SUBB      A,#0AH
SUB_M111:   JC      SUB_M110
MOV     @R0,#09H        ;大于等于0AH,为9
SUB_M10:    MOV    A,R3            ;取回R3中暂存数据
INC       R0              ;指向当前地址单元
SWAP    A               ;A中数据高四位与低四位交换
ANL     A,#0FH          ;高四位变0
MOV    @R0,A           ;数据放入当削地址单元中
RET                       ;子程序返回
;
SUB_M1:   MOV      A,#59H
AJMP      SUB_M11
SUB_M110:  MOV     A,R3            ;移入R3寄存器
ANL     A,#0FH          ;高四位变0
MOV       @R0,A
AJMP      SUB_M10
;时减1子 程 序 
SUB_H:    MOV    A,@R0           ;取当前计时单元数据到A
DEC    R0              ;指向前一地址
SWAP      A               ;A中数据高四位与低四位交换
ORL     A,@R0           ;前一地址中数据放入A中低四位
JZ        SUB_H1         ;00减1为23(小时)
DEC    A                ;A减1操作
SUB_H11:  MOV       R3,A            ;移入R3寄存器
ANL     A,#0FH          ;高四位变0
CLR       C               ;清进位标志
SUBB      A,#0AH          ;时个位大于9为9
SUB_H111:   JC      SUB_H110       
MOV     @R0,#09H        ;大于等于0AH,为9
SUB_H10:  MOV    A,R3            ;取回R3中暂存数据
INC       R0              ;指向当前地址单元
SWAP    A               ;A中数据高四位与低四位交换
ANL     A,#0FH          ;高四位变0
MOV    @R0,A           ;时十位数数据放入
RET                       ;子程序返回
SUB_H1:    MOV       A,#23H
AJMP      SUB_H11
SUB_H110:  MOV       A,R3            ;时个位小于0A不处理
ANL     A,#0FH          ;高四位变0
MOV       @R0,A           ;个位移入
AJMP      SUB_H10
;清零程序 
;对计时单元复零用
CLR_H:     CLR     A               ;清累加器
MOV     @R0,A          ;清当前地址单元
DEC     R0              ;指向前一地址
MOV     @R0,A           ;前一地址单元清0
RET                          ;子程序返回
;时钟时间调整程序
;当调时按键按下时进入此程序
R_SETTIM:  CLR      ET0                ;关定时器T0中断
CLR     TR0                ;关闭定时器T0
LCALL    DL_LOOPS        ;调用1秒延时程序
LCALL     DLY20M           ;消抖
JB      P1.0,SLEEP        ;键按下时间小于1秒,关闭显示(省电)
MOV      R2,#06H           ;进入调时状态,赋闪烁定时初值
MOV       70H,#00H           ;调时时秒单元为00 秒
MOV      71H,#00H
SETB     ET1                ;允许T1中断
SETB     TR1                ;开启定时器T1
SET_2:     JNB     P1.0,SET_1         ;P1.0口为0(键未释放),等待
SETB      00H                ;键释放,分调整闪烁标志置1
SET_4:     JB      P1.0,SET_3          ;等待键按下
LCALL     DL05S              ;有键按下,延时0.5秒
LCALL     DLY20M           ;消抖
JNB        P1.0,R_SETHH       ;按下时间大于0.5秒转调小时状态
MOV     R0,#77H           ;按下时间小于0.5秒加1分钟操作
LCALL     ADD_1             ;调用加1子程序
MOV     A,R3               ;取调整单元数据
CLR     C                  ;清进位标志
CJNE     A,#60H,SET_LOOP    ;调整单元数据与60比较
SET_LOOP:   JC       SET_4              ;调整单元数据小于60转SET_4循环
LCALL     CLR_H             ;调整单元数据大于或等于60时清0
CLR     C                  ;清进位标志
AJMP      SET_4             ;跳转到SET_4循环
SLEEP:     SETB     ET0               ;省电(LED不显示)状态。开T0中断
SETB     TR0               ;开启T0定时器(开时钟)
SET_LOOP1:  JB       P1.0,SET_LOOP1      ;无按键按下,等待。
LCALL     DLY20M           ;消抖
JB        P1.0,SET_LOOP1     ;是干扰返回SET_LOOP1等待
SET_LOOP2:  JNB       P1.0,SET_LOOP2     ;等待键释放
LJMP      MLOOP1           ;返回主程序(LED数据显示亮)
R_SETHH:    CLR      00H               ;分闪烁标志清除(进入调小时状态)
SETB      01H                ;小时调整标志置1
SET_LOOP3:  JNB     P1.0,SET_5          ;等待键释放
SET_6:      JB      P1.0,SET_7          ;等待按键按下
LCALL    DL05S             ;有键按下延时0.5秒
LCALL     DLY20M            ;消抖
JNB      P1.0,STOP        ;按下时间大于0.5秒退出时间调整
MOV    R0,#79H           ;按下时间小于0.5秒加1小时操作
LCALL    ADD_1              ;调加1子程序
MOV    A,R3              
CLR     C               
CJNE     A,#24H,C_YHH        ;计时单元数据与24比较
C_YHH:      JC       SET_6               ;小于24转SET_6循环
LCALL     CLR_H               ;大于或等于24时清0操作
AJMP     SET_6               ;跳转到SET_6循环
STOP:     JNB       P1.0,STOP1         ;调时退出程序。等待键释放
LCALL     DLY20M           ;消抖
JNB       P1.0,STOP          ;是抖动,返回STOP再等待
CLR       01H                ;清调小时标志
CLR       00H                ;清调分标志
CLR       02H                ;清闪烁标志
CLR       TR1                ;关闭定时器T1
CLR       ET1                ;关定时器T1中断
SETB      TR0               ;开启定时器T0
SETB      ET0                ;开定时器T0中断(计时开始)
LJMP     MLOOP1             ;跳回主程序
SET_1:    LCALL    D_II_PLAY            ;键释放等待时调用显示程序(调分)
AJMP     SET_2               ;防止键按下时无时钟显示
SET_3:    LCALL    D_II_PLAY            ;等待调分按键时时钟显示用
JNB      P1.1, DLY7         ;减1分操作
AJMP     SET_4               ;调分等待
SET_5:    LCALL    D_II_PLAY            ;键释放等待时调用显示程序(调小时)
AJMP     SET_LOOP3         ;防止键按下时无时钟显示
SET_7:    LCALL    D_II_PLAY            ;等待调小时按键时时钟显示用
JNB       P1.1, DLY7B         ;小时减1操作
AJMP     SET_6                ;调时等待
STOP1:    LCALL    D_II_PLAY            ;退出时钟调整时键释放等待
AJMP     STOP              ;防止键按下时无时钟显示
;DLY7,分减1程序?
DLY7:      LCALL     DLY20M           ;消抖
JB       P1.1,SET_41         ;干扰,返回调分等待
DLY7_M:   JNB     P1.1,DLY7_M       ;等待键放开
MOV     R0,#77H            
LCALL     SUB_M             ;分减1程序
LJMP      SET_4               ;返回调分等待
;
SET_41:     LJMP     SET_4             ;
;DLY7B,时减1程序                                            ;
DLY7B:    LCALL     DLY20M            ;消抖
JB       P1.1,SET_61         ; 干扰,返回调时等待
DLY7_H:   JNB      P1.1,DLY7_H        ; 等待键放开
MOV     R0,#79H         
LCALL    SUB_H              ; 时减1程序
LJMP     SET_6               ; 返回调时等待
SET_61:    LJMP      SET_6
;显示程序                  ;;
;显示数据在70H-75H单元内,用六位LED共阳数码管显示,P0口输出段码数据,P2口作
;扫描控制,每个LED数码管亮1MS时间再逐位循环。
D_II_PLAY:   MOV    R1,DISBEG         ;指向显示数据首址
MOV    R5,#0FEH          ;扫描控制字初值
PLAY:     MOV     A,R5              ;扫描字放入A
MOV    P2,A              ;从P2口输出
MOV     A,@R1             ;取显示数据到A
MOV     DPTR,#TAB         ;取段码表地址
MOVC    A,@A DPTR       ;查显示数据对应段码
MOV     P0,A              ;段码放入P1口
MOV      A,R5           
JB        ACC.2,D_LOOP     ;小数点处理
CLR       P0.7          ;
D_LOOP:     JB       ACC.4,D_LOOP1     ;小数点处理
CLR        P0.7          ;
D_LOOP1:    LCALL     DLY1M             ;显示1MS
INC     R1                ;指向下一地址
MOV     A,R5              ;扫描控制字放入A
JNB     ACC.5,CLOSE      ;ACC.5=0时一次显示结束
RL       A                 ;A中数据循环左移
MOV     R5,A              ;放回R5内
MOV     P0,#0FFH
AJMP     PLAY              ;跳回PLAY循环
CLOSE:     MOV      P2,#0FFH            ;一次显示结束,P2口复位
MOV     P0,#0FFH           ;P0口复位
RET                          ;子程序返回
; SD_II_PLAY ,上电显示子程序
;不带小数点显示,有"A""-"显示功能
SD_II_PLAY: MOV      R1,DISBEG
MOV     R5,#0FEH          ;扫描控制字初值
I_PLAY:    MOV     A,R5              ;扫描字放入A
MOV     P2,A              ;从P2口输出
MOV     A,@R1             ;取显示数据到A
MOV     DPTR,#I_TAB       ;取段码表地址
MOVC    A,@A DPTR       ;查显示数据对应段码
MOV     P0,A              ;段码放入P1口
MOV      A,R5          
LCALL     DLY1M             ;显示1MS
INC     R1              ;指向下一地址
MOV     A,R5            ;扫描控制字放入A
JNB     ACC.5,FLSH    ;ACC.5=0时一次显示结束
RL       A                 ;A中数据循环左移
MOV     R5,A             ;放回R5内
AJMP     I_PLAY            ;跳回PLAY循环
FLSH:    MOV      P2,#0FFH            ;一次显示结束,P2口复位
MOV     P0,#0FFH           ;P0口复位
RET                          ;子程序返回
;ST,上电时显示年月班级用,采用移动显示,先右移,接着左移.
ST:        MOV       R0,#40H          ;将显示内容移入40H-5FH单元
MOV       R2,#20H      
MOV      R3,#00H     
CLR       A          
MOV       DPTR,#STAB    
S_LOOP:     MOVC       A,@A DPTR      
MOV       @R0,A         
MOV      A,R3         
INC       A            
MOV      R3,A        
INC          R0           
DJNZ         R2,S_LOOP         ;移入完毕
MOV        DISBEG,#40H      ;以下程序从左往右移
SS_LOOP:   MOV       R2,#50             ;控制移动速度
SS_LOOP1:  LCALL    SD_II_PLAY    
DJNZ         R2,SS_LOOP1      
INC          DISBEG
MOV        A,DISBEG
CJNE         A,#5AH, SS_LOOP   
MOV        DISBEG,#5AH      ;以下程序从右往左移
MOV        R3,#1BH           ;显示27个单元
SS_LOOP2:  MOV       R2,#32H            ;控制移动速度
SS_LOOP12: LCALL        SD_II_PLAY       ;
DJNZ         R2,SS_LOOP12     ;
DEC       DISBEG
DJNZ         R3,SS_LOOP2      ;
RET
;以下是闹铃时间设定程序中的时调整程序
DLY8:     LCALL     D_II_PLAY          ;等待键释放
JNB       P1.3, DLY8
MOV      50H,#0AH          ;时调整时显示为00:00:- .
MOV      51H,#0CH
R_BTIM:    SETB      EA
LCALL     D_II_PLAY
JNB       P1.2,DLY12        ;时加1键
JNB       P1.0,DLY14        ;时减1
JNB       P1.3,DLY9          ;闹铃设定退出键
JNB       P1.1,DLY10         ;闹铃设定有效或无效按键
AJMP      R_BTIM
DLY9:        LCALL     DLY20M           ;消抖
JB       P1.3, R_BTIM
DLY8M:      LCALL     D_II_PLAY           ;键释放等待
JNB      P1.3, DLY8M
MOV      DISBEG,#70H
LJMP     MLOOP1
DLY10:     LCALL     DLY20M           ;消抖        ;
JB       P1.1, R_BTIM
DLY11:    LCALL     D_II_PLAY           ;键释放等待
JNB       P1.1, DLY11
CPL      05H
JNB      05H,R_BTIM11
MOV      50H,#00H          ;05H=1,闹铃开,显示为 00:00:0。
AJMP      R_BTIM
R_BTIM11:   MOV      50H,#0aH          ;闹铃不开,显示为00:00:- .
AJMP      R_BTIM
DLY12:       LCALL     DLY20M            ;消抖        ;
JB       P1.2, R_BTIM
DLY13:      LCALL    D_II_PLAY           ;键释放等待
JNB       P1.2, DLY13
CLR       EA
MOV       R0,#55H
LCALL     ADD_1
MOV      A,R3            ;

CLR       C                 ;
CJNE      A,#24H,A_DDH33N   ;
A_DDH33N:   JC       R_BTIM          ;小于24点返回
ACALL     CLR_H              ;大于等于24点清零
AJMP      R_BTIM
DLY14  :    LCALL     DLY20M             ;消抖        ;
JB       P1.0, R_BTIM
DLY15:      LCALL     D_II_PLAY           ;键释放等待
JNB       P1.0, DLY15
CLR       EA
MOV       R0,#55H
LCALL     SUB_H
LJMP      R_BTIM
;以下是闹铃判断子程序
BELL:     JNB       05H,BBELL         ;05H=1,闹钟开,要比较数据
MOV      A,79H           ;从时十位、个位、分十位、分个位顺序比较
CJNE       A,55H,BBELL
MOV      A,78H
CLR        C
BELL_1:      CJNE       A,54H,BBELL
MOV      A,77H
CLR       C
CJNE       A,53H,BBELL
MOV      A,76H
CLR        C
BELL_2:     CJNE       A,52H,BBELL
JNB       07H,BBELL          ;07H在1秒到时会取反
CLR        CALB             ;时分相同时呜叫(1秒间隔叫)
RET
BBELL:     SETB      CALB              ;闹铃不开
RET
END

0 人点赞