⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock.asm

📁 还是电子闹钟方面的
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; 电子日历时钟.asm
; (Electronic Calendar and Clock)
; Reference for Grade 2005, s.c.u.t.
; Author: YUJIAN.XU
; Revision: version 2.0 2007/12/01
; Update  : 2007/12/10
; Limitations:None
; 开关Key0(for shift/adjust即调整/时间,日期显示模式/秒表控制键)connected to INT0
; 开关Key1(for un-flash/flash即功能选择键) connected to INT1
; 开关Key2:休眠唤醒键      connected to P2.6
; 开关Key3:闹钟开关键      connected to P2.7
; 开关Key4: 系统复位键,所有数值清零,初始值从07年12月01日12:00:00开始显示

;变量定义
;SLEEP_UP    EQU   38H          ;休眠计时器
TICK_CNT	EQU	20H		;T0溢出计数器
FLASH_FLAG	EQU	27H	    ;00h不选择修改,01h-03h分别为"DATE"的年,月,日闪烁,
;04h-06h分别为"time"的时,分,秒闪烁,07h-09h分别为"bell"的时,分,mode闪烁

;时间
SECOND_BCD	EQU	21H
MINUTE_BCD	EQU	22H
HOUR_BCD	EQU	23H


;闹钟
A_SEC_BCD   EQU 34H
A_MIN_BCD   EQU 35H
A_HOUR_BCD  EQU 36H


;日期
DAY_BCD		EQU	24H
MONTH_BCD	EQU	25H
YEAR_BCD	EQU	26H

;秒表
WATCH_FLAG	EQU	30H
S_PER_SEC_BCD	EQU	31H	;秒表百分之一秒
S_SEC_BCD       EQU	32H
MIN_BCD	        EQU	33H


;LED系统功能状态标记
CLOCK_LED EQU P2.0
ALARM_LED EQU P2.1
WATCH_LED EQU P2.2
DATA_LED  EQU P2.3
TIME_LED  EQU P2.4

;中断向量表
		ORG 0000H
		LJMP MAIN
		ORG 0003H
		LJMP ADJUST0			;外部中断0
		ORG 000BH
		LJMP TIMEUP			    ;定时/计数器T0中断
		ORG 0013H
		LJMP ADJUST1			;外部中断1
	      ORG 001BH
	      LJMP  T1_INT			;定时/计数器T1中断

		ORG 0030H
MAIN:	NOP					    ;主程序
		MOV SP,#60H             ;设置堆栈指针
                             	;初始化变量
	   MOV P2,#0FFH
;显示的时间:
	MOV	SECOND_BCD, #00H		; 秒BOD码
	MOV	MINUTE_BCD, #00H		;  分BCD码
	MOV	HOUR_BCD,   #12H		; 时BOD码
;显示的日期:
	MOV	DAY_BCD,  #01H		; 天BCD码
	MOV	MONTH_BCD,#12H		; 月BCD码
	MOV	YEAR_BCD, #07H		; 年BCD码
;秒表
	MOV	S_PER_SEC_BCD,#00H	; 百分秒
	MOV	S_SEC_BCD,    #00H	; 秒
	MOV	MIN_BCD,   #00H	; ;秒表清零
	MOV	WATCH_FLAG,   #00H	; 秒表开始/停止标志
;闹钟
        MOV A_SEC_BCD,#00H
        MOV A_MIN_BCD,#00H
        MOV A_HOUR_BCD,#00H

	MOV FLASH_FLAG,#00H		;闪烁标志
	MOV R7,#00H			    ;时间/日期转换标志

	MOV TL0,#0B0H		    ;装T0的时间常数
	MOV TH0,#3CH			;T0一次中断时间为0.05秒
      MOV	TL1,#0F0H		    ;装T1的时间常数
	MOV	TH1,#0D8H
     ; MOV SLEEP_UP,#00H
	MOV	TICK_CNT,#14H		;T0循环计时次数20次(F=12Mhz)
	MOV TMOD,#11H		    ;T0初始化:方式1,计数位16位
	CLR  IT0
	CLR  IT1
	SETB ET0				;开T0中断
    SETB ET1                ;开T1中断
	SETB EX0				;开外部中断0(INT0)
	SETB EX1				;开外部中断1(INT1)
	SETB EA				    ;CPU开中断
	SETB PT0				;设置T0中断为高优先级
	SETB TR0				;T0开始计时
	CLR  TR1                ;T1未计时
;LOOP1:
     ; MOV  A,SLEEP_UP
     ; CJNE A,#91H,LOOP2        ;一分半钟到自动进入休眠状态
     ; CLR EX0                 ;关外部中断
     ; CLR EX1
     ; MOV P1,#0FFH
     ; JB ALARM_LED,SLEEP3
;LOP: LCALL ALARM
     ; MOV P1,#0FFH
    ;  JB P2.6,LOP        ;P2.6按键按下激活
    ;  LCALL  DMS
    ;  JNB P2.6,LOP        ;等待按键提起
    ;  MOV P1,#0FFH
     ; SJMP EXIT0
;SLEEP3:
    ;  JB P2.6,SLEEP3          ;P2.6按键按下激活
;WEAK_UP:
    ;  LCALL  DMS
    ;  JNB P2.6,WEAK_UP        ;等待按键提起
;EXIT0:
    ;  MOV SLEEP_UP,#00H
     ; SETB EX0
     ; SETB EX1
LOOP1:
      JNB P2.7,SET_ARM            ;低电平表示K3键按下,开闹钟功能
	JNB P2.6,SLEEP
      JB ALARM_LED,LOOP2
	LCALL ALARM
LOOP2:
    LCALL CHECK_STADE
    LCALL CHECK_INT
    LCALL DISP

    SJMP LOOP1
;————————————————————————————————————

;等待中断

;————————————————————————————————————

;开闹钟
SET_ARM:
   LCALL DMS                   ;消抖动,并显示
   JNB P2.7,SET_ARM            ;等待按键提起
   ;MOV SLEEP_UP,#00H              ;自动休眠器清零
   CLR ALARM_LED            ; 开闹钟
   SJMP LOOP1

;手动进入休眠状态
SLEEP:
   LCALL DMS
   JNB P2.6,SLEEP               ;等待按键提起
   ;MOV SLEEP_UP,#00H              ;自动休眠器清零
   ;MOV P1,#0FFH
   CLR EX0                     ;关外部中断
   CLR EX1                  ;进入休眠状态,即LED不显示,外部中断按键不响应
   JB ALARM_LED,SLEEP0        ;查是否开闹钟?
LOOP3:
   LCALL ALARM           ;查闹钟时间到?
   MOV P1,#0FFH
   JB P2.6,LOOP3
SLEEP3:
   LCALL DMS             ;消抖动,并显示
   JNB P2.6,SLEEP3           ;等待按键提起
  ; MOV SLEEP_UP,#00H              ;自动休眠器清零
   SETB EX0
   SETB EX1                ;开外部中断
   LJMP LOOP1
SLEEP0:
   JB P2.6,SLEEP0               ;再次按 K2键,则退出休眠状态
SLEEP1:
    LCALL DMS             ;消抖动,并显示
   JNB P2.6,SLEEP1           ;等待按键提起
  ; MOV SLEEP_UP,#00H              ;自动休眠器清零
   SETB EX0                   ;开外部中断
   SETB EX1
   LJMP LOOP1

;系统功能状态功能查询
CHECK_STADE:             ;R7='00'显示时间状态LED亮
  PUSH ACC
  MOV A,R7
  CJNE A,#00H,CHECK1
  CLR TIME_LED
  SETB DATA_LED
  SETB WATCH_LED
  SETB P2.0
   SJMP CHECK_OUT
CHECK1:
  CJNE A,#01H,CHECK2       ;R7='01'显示日期状态LED亮
   SETB TIME_LED
   CLR DATA_LED
  SETB WATCH_LED
  SETB P2.0
   SJMP CHECK_OUT
CHECK2:
   CJNE A,#02H,CHECK3          ;R7='02'显示秒表状态LED亮
   SETB TIME_LED
  SETB DATA_LED
  CLR WATCH_LED
  SETB P2.0
   SJMP CHECK_OUT
CHECK3:                  ;R7='03'显示闹钟设定时间状态LED亮
  SETB TIME_LED
  SETB DATA_LED
  SETB WATCH_LED
  CLR P2.0
CHECK_OUT:
  POP ACC
 RET

;闹钟查询
ALARM:
   PUSH ACC
   MOV A,23H
   CJNE A,36H,DONT
   MOV A,22H
   CJNE A,35H,DONT
   MOV A,21H
   CJNE A,34H,DONT
ALARM1:
   LCALL DISP
   CPL P2.5       ;开/关蜂鸣器
   LCALL DMS        ;延时响应
   JB P2.7,ANEXT    ;P2.7按下关闹铃
AL0:
    LCALL DMS
    JNB P2.7,AL0
    MOV P1,#0FFH
    LCALL DISP
    SETB P2.1       ;关闹钟标记位
    SETB P2.5
    SETB P2.6
    SJMP DONT
ANEXT:   SJMP ALARM1
DONT:
   POP ACC
   RET

;整点报时
CHECK_INT:
   MOV A,22H
   CJNE A,#00H,C_OUT
   MOV A,21H
   CJNE A,#00H,C_OUT
   CPL P2.5
   LCALL DMS
   SETB P2.5
C_OUT:NOP
   RET

;——————————————————————————————————

; 定时器1中断;用于秒表

;——————————————————————————————————

T1_INT:	MOV	TL1,#0F0H		        ;重载T1,0.01s
	    MOV	TH1,#0D8H		        ;
	    MOV A,S_PER_SEC_BCD		    ; 取变量S_PER_SEC_BCD的值
	    CJNE A,#99H,SIN3		    ; 到达100 S_PER_SEC ?
	    SJMP SIN4
SIN3:	LJMP	S_PER_SEC_INC
SIN4:	MOV	S_PER_SEC_BCD,#00H	    ; 当到达100次后,重新赋0值
	    MOV	A,S_SEC_BCD
	    CJNE A,#59H,SIN5
	    SJMP SIN6
SIN5:	LJMP	S_SEC_INC
SIN6:	MOV	S_SEC_BCD,#00H
        MOV  A,  MIN_BCD
        CJNE A,#59H,SIN7
        SJMP SIN8
SIN7:	LJMP	MIN_INC
SIN8: 	MOV MIN_BCD,#00H
        SJMP T1_RET
MIN_INC:                           ;加1m
             MOV	A,MIN_BCD
		    ADD	A,#01H
		    DA	A
		    MOV	MIN_BCD,A
		    SJMP T1_RET
S_SEC_INC:                               ;加1s
            MOV	A,S_SEC_BCD
		    ADD	A,#01H
		    DA	A
		    MOV	S_SEC_BCD,A
		    SJMP T1_RET

S_PER_SEC_INC:                           ; 加0.01s
        MOV	A,S_PER_SEC_BCD
		ADD	A,#01H
		DA	A
		MOV	S_PER_SEC_BCD,A
T1_RET:	RETI

; ————————————————————————————————————

; sub:Author: BY YUJIAN.XU  T0中断程序

;—————————————————————————————————————
TIMEUP:	MOV TL0,#0B0H		    ;重装T0的时间常数
		MOV TH0,#3CH
		DJNZ 20H,INTER1		    ;循环20次(是否达到1秒)?
            ;MOV A,SLEEP_UP
            ;CJNE A,#91H,SLADD          ;查询休眠时间到?
            SJMP INTER2
;SLADD:MOV A,SLEEP_UP           ;取自动休眠计时器秒的BCD码
    ;        ADD A,#01H                 ;加一秒
     ;       DA A                         ;BCD码调整
      ;      MOV SLEEP_UP ,A
       ;     SJMP INTER2
INTER1:	LJMP LAST
INTER2:	MOV A,21H			    ;取秒的BCD码
		CJNE A,#59H,INTER3	    ;是否达到59秒,否则转秒加一
		SJMP INTER4
INTER3:	LJMP SADD
INTER4:	MOV 21H,#00H			;存第一秒数值
		MOV A,22H			    ;取分的BCD码
		CJNE A,#59H,INTER5	    ;是否达到59分,否则转分加一
		SJMP INTER6
INTER5:	LJMP MADD
INTER6:	MOV 22H,#00H			;存第一分数值
		MOV A,23H			    ;取小时的BCD码
		CJNE A,#23H,HADD		;是否达到23时,否则转小时加一
		MOV 23H,#00H			;存第一小时数值
		MOV A,25H			    ;取月的BCD码
		CJNE A,#02H,NOTFEB	    ;是否2月,否则转大小月判断
ISFEB:	NOP
		ACALL DIVBCD			;调用平年闰年判断程序
		MOV A,R3				;程序参数传递(R3)->(A)
		CJNE A,#00H,PING		;"00H"说明是闰年
RUN:	MOV A,24H			    ;取(二月)日的BCD码
		CJNE A,#29H,DDADD	    ;是否为29号,否则转日加一
		MOV 24H,#01H			;存第一天数值(1号)
		MOV 25H,#03H			;月份改为3月
		SJMP CONT
PING:	MOV A,24H			    ;取(二月)日的BCD码
		CJNE A,#28H,DDADD	    ;是否为28号,否则转日加一
		MOV 24H,#01H			;存第一天数值(1号)
		MOV 25H,#03H			;月份改为3月
		SJMP CONT
NOTFEB:	NOP					    ;二月之外的其他月份处理
		CJNE A,#04H,YUE1		;是否为4月?
		AJMP T12
YUE1:	CJNE A,#06H,YUE2		;是否为6月?
		AJMP T12
YUE2:	CJNE A,#09H,YUE3		;是否为9月?
		AJMP T12
YUE3:	CJNE A,#11H,T11		    ;是否为11月?
		AJMP T12
T11:	MOV A,24H	     	    ;取(大月)日的BCD码
		CJNE A,#31H,DDADD	    ;是否为31号,否则转日加一
		AJMP T30
T12:	MOV A,24H			    ;取(小月)日的BCD码
		CJNE A,#30H,DDADD	    ;是否为30号,否则转日加一
T30:	MOV 24H,#01H			;存第一天数值(1号)
		MOV A,25H			    ;取月的BCD码
		CJNE A,#12H,MMADD	    ;是否为12月,否则转月加一
		MOV 25H,#01H			;存第一月数值(1月)
		MOV A,26H			    ;取年的BCD码
		CJNE A,#99H,YYADD	    ;是否为99年,否则转年加一
		MOV 26H,#00H			;存第一年数值(00年)
		SJMP CONT
YYADD:	MOV A,26H			    ;取年的BCD码
		ADD A,#01H			    ;年数值加一
		DA A					;BCD码调整
		MOV 26H,A			    ;存年的数值
		SJMP CONT
MMADD:	MOV A,25H			    ;取月的BCD码
		ADD A,#01H			    ;月数值加一
		DA A					;BCD码调整
		MOV 25H,A			    ;存月的数值
		SJMP CONT
DDADD:	MOV A,24H			    ;取日的BCD码
		ADD A,#01H			    ;日数值加一
		DA A					;BCD码调整
		MOV 24H,A			    ;存日的数值
		SJMP CONT
HADD:	MOV A,23H			    ;取时的BCD码
		ADD A,#01H			    ;时数值加一
		DA A					;BCD码调整
		MOV 23H,A			    ;存时的数值
		SJMP CONT
MADD:	MOV A,22H			    ;取分的BCD码
		ADD A,#01H			    ;分数值加一
		DA A					;BCD调整
		MOV 22H,A			    ;存分的数值
		SJMP CONT
SADD:	MOV A,21H			    ;取秒的BCD码
		ADD A,#01H			    ;秒加一
		DA A					;BCD码调整
		MOV 21H,A			    ;存秒的数值
CONT:	MOV 20H,#14H			;重置T0计时循环次数20次(新的一秒开始)
LAST:	RETI

;————————————————————————————————————

;sub:Author: By YUJIAN.XU  数码管  显示子程序

;————————————————————————————————————

DISP:	MOV DPTR,#TABLE		    ;取显示编码表头地址
		MOV A,R7				;取时间/日期转换显示标志
		CJNE A,#00H,DATE		;"00H"为显示时间
TIME:	MOV R0,#21H			    ;取秒地址
		SJMP TSAVE
DATE:
        CJNE A,#01H,WATCH
    	MOV R0,#24H			    ;"FFH"为显示日期,取日地址
        SJMP TSAVE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -