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

📄 a_clock.asm

📁 AT89C2051时钟程序 定时器T0、T1溢出周期为50MS
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	    ORG	  0000H
		AJMP  MAIN
		ORG   0003H
		AJMP  KEYSET
		ORG   001BH
		AJMP  SERVE1
;*****************************************************************************************
MAIN:   MOV   TMOD,#10H			  ;设T1工作于模式1
        MOV   20H,#10			  ;装入中断次数
		CLR   A
		MOV   30H,A
		MOV   31H,A
		MOV   32H,A
		MOV   33H,A				  ;对时分秒单元清0
		MOV   34H,A
		MOV   35H,A				  
		MOV   36H,A
		MOV   37H,A
		MOV   38H,A				  ;功能键0~3的操作值存储单元34~38H
		MOV   39H,A				  ;设置时闪烁定时器
		MOV   40H,A
		MOV   41H,A
		MOV   42H,A
		MOV   43H,A				  ;调时子程序暂存单元40~43H
		MOV   44H,A
		MOV   45H,A	
		MOV   46H,A
		MOV   47H,A			   	  ;调时期子程序暂存单元44~47H
		MOV   48H,A
		MOV   49H,A
		MOV   50H,A
		MOV   51H,A				  
	    MOV   52H,A
		MOV   53H,A
		MOV   54H,A
		MOV   55H,A				  ;秒表子程序时间存储单元52~55H
		MOV   56H,A
		MOV   57H,A
		MOV   58H,A
		MOV   59H,A				  ;闹钟设置暂存单元56~59H
		MOV   65H,A				  ;key3键功能中间值存储器
		MOV   66H,A
		MOV   70H,A
		MOV   71H,A
		MOV   72H,A
		MOV   73H,A				  ;闹钟设置存储单元70H~73H
		MOV   74H,A
		MOV   75H,A
		MOV   76H,A
		MOV   77H,A				  ;日期存储单元74~77H
		SETB  ET1				  ;允许T1中断
		SETB  EX0				  ;允许外部中断1
		SETB  IT0				  ;设外部中断1为边沿触发方式
		MOV   IP,#0CH
		SETB  EA				  ;允许CPU中断
		MOV   TH1,#0FCH
		MOV   TL1,#2AH
		SETB  TR1				  ;开T1中断
CYC:	MOV   A,34H
		CJNE  A,#01H,NEXT1
		MOV   66H,#00H
		LCALL ADJUST
		MOV   P1,#0F7H
		SJMP  CYC
NEXT1:	CJNE  A,#02H,NEXT2
        MOV   66H,#00H 
		LCALL DATE
		MOV   P1,#0F7H
		SJMP  CYC
NEXT2:	CJNE  A,#03H,NEXT3
        MOV   66H,#00H
		LCALL ALARMCLOCK
		MOV   P1,#0F7H
		SJMP  CYC
NEXT3:	CJNE  A,#04H,NEXT4
        LCALL STOPWATCH
		SJMP  CYC
NEXT4:  MOV   P1,#0F7H
        LCALL RING				  ;判断是否到了闹钟时间,是则报警
		MOV   P1,#0F7H
     	LCALL DISPLAY0
		SJMP  CYC
;*****************************************************************************************
ADJUST:                           ;时间校准子程序,40~43H做暂存器,将当前时间值存入并显示
       	LCALL DISPLAY1
		MOV   A,65H				  
		CJNE  A,#00H,AD_1		  ;判断是否进行时间校准设置,否则保持显示校准前时间
		MOV   A,38H				  ;
		CJNE  A,#00H,AD_ET1		  ;38H单元为1时表示没有进行功能设置,继续显示装入值
    	MOV   40H,30H
		MOV   41H,31H
		MOV   42H,32H
		MOV   43H,33H			  ;将当前时间值装入
		INC   38H
		AJMP  AD_EXIT
AD_1:	CJNE  A,#01H,AD_2		  ;选择小时的十位数进行校准
        MOV   R0,#40H			  ;R0做存储单元中转器
AD_13:  MOV   A,36H				   			
		CJNE  A,#01H,AD_3		  ;加1键按下时,进行加1运算
    	MOV   A,@R0				  
        ADD   A,66H
		MOV   B,#10
		DIV   AB				  ;将十位数个位数分开
		CJNE  R0,#40H,AD_14		  ;判断是小时的调整,否则转向分钟判断
		CJNE  A,#3,AD_4			  ;是则小时十位数为二进制	 
		MOV   A,#00H				 
		MOV   @R0,B				  ;保存个位数的值
AD_ET1:	AJMP  AD_EXIT
AD_14:	CJNE  R0,#41H,AD_15	      ;判断是否分钟的校准,否则转向秒钟判断
AD_17:	CJNE  A,#6,AD_4			  ;十位数为六进制
		MOV   A,#00H
		MOV   @R0,B				  ;保存个位数的值
		AJMP  AD_EXIT
AD_15:	CJNE  R0,#42H,AD_16		  ;判断是否秒的校准,是则秒十位数为六进制,否则转向0.01秒判断
		SJMP  AD_17
AD_16:  CJNE  R0,#43H,AD_ET1	  ;判断是否0.01秒的校准,否则退出
        CJNE  A,#10,AD_4		  ;是则十位数为十进制
		MOV   A,#00H
		MOV   @R0,B				  ;保存个位数值
		AJMP  AD_EXIT
AD_4:  	MOV   A,@R0
        ADD   A,66H
        MOV   @R0,A				  ;保存十位数校准值
        AJMP  AD_EXIT
AD_3:   CJNE  A,#02H,AD_ET1		  ;是减1键按下时
        MOV   A,@R0
		MOV   B,#10
		DIV   AB				  ;将十位数个位数分开
		CJNE  A,#00H,AD_6		  ;为负数时则返回为相应进制最高数
		MOV   A,B
		CJNE  R0,#40H,AD_23		  ;时为二进制
		ADD   A,#20
		AJMP  AD_24
AD_23:  CJNE  R0,#41H,AD_25		  ;分为六十进制
        ADD   A,#50
		AJMP  AD_24
AD_25:  CJNE  R0,#42H,AD_26		  ;秒为六十进制
        ADD   A,#50
		AJMP  AD_24
AD_26:  CJNE  R0,#43H,AD_24		  ;0.01秒为一百进制
        ADD   A,#90
AD_24:	MOV   @R0,A				  ;保存设置值
		AJMP  AD_EXIT      
AD_6:	MOV   A,@R0
        CLR   C
        SUBB  A,66H
		MOV   @R0,A				  ;保存设置值
		SJMP  AD_EXIT
AD_2:   CJNE  A,#02H,AD_7		  ;个位数调整
        MOV   R0,#40H
AD_19:  MOV   A,36H
		CJNE  A,#01H,AD_8		  ;加1键有按,没有转判断是不减1
		MOV   A,@R0
		MOV   B,#10
		DIV   AB				  ;十位数个位数分开
		MOV   A,B
		ADD   A,66H				  ;个位数加1
		CJNE  A,#10,AD_9		  ;个位数为十进制
		MOV   A,@R0
		CLR   C
		SUBB  A,B
		MOV   @R0,A				  ;保存十位数值
		SJMP  AD_EXIT
AD_9:   INC   @R0				  ;个位数加1
        SJMP  AD_EXIT
AD_8:   CJNE  A,#02H,AD_EXIT	  ;减1键按下,没有退出
        MOV   A,@R0
		MOV   B,#10
		DIV   AB				  ;十位数个位数分开
		MOV   A,B
		CJNE  A,#00H,AD_11		  ;减到为负时转回相应进制的最高数,没有则进行减1
		MOV   A,@R0
		ADD   A,#09H
		MOV   @R0,A				  ;保存设置值
		SJMP  AD_EXIT
AD_11:  MOV   A,@R0
        CLR   C
		SUBB  A,66H				  ;减1
		MOV   @R0,A				  ;保存设置值
		SJMP  AD_EXIT		
AD_7:   CJNE  A,#03H,AD_12		  ;分,十位数调整
		MOV   R0,#41H
		AJMP  AD_13
AD_12:  CJNE  A,#04H,AD_18		  ;分,个位数调整
		MOV   R0,#41H
		AJMP  AD_19
AD_18:  CJNE  A,#05H,AD_20		  ;秒,十位数调整
        MOV   R0,#42H
		AJMP  AD_13
AD_20:  CJNE  A,#06H,AD_21		  ;秒,个位数调整
        MOV   R0,#42H
		AJMP  AD_19
AD_21:  CJNE  A,#07H,AD_22		  ;0.01秒,十位数调整
        MOV   R0,#43H
		AJMP  AD_13
AD_22:  CJNE  A,#08H,AD_EXIT	  ;0.01秒,个位数调整
        MOV   R0,#43H
		AJMP  AD_19						  
AD_EXIT:MOV   30H,40H
		MOV   31H,41H
		MOV   32H,42H
		MOV   33H,43H			  ;保存设置结果
		MOV   36H,#00H			  
        RET
;*****************************************************************************************
DATE:							  ;日期校准子程序,44~47H
        LCALL DISPLAY2
		MOV   A,65H		
		CJNE  A,#00H,DA_1		  ;判断是否进行日期校准设置,否则保持显示校准前日期
		MOV   A,38H
		CJNE  A,#00H,DA_ET1
    	MOV   44H,74H
		MOV   45H,75H
		MOV   46H,76H
		MOV   47H,77H
		INC   38H
		AJMP  DA_EXIT
DA_1:	CJNE  A,#01H,DA_2		  ;选择年份的千位数进行校准
        MOV   R0,#44H			  ;R0做时间值暂存器
DA_13:  MOV   A,36H							
		CJNE  A,#01H,DA_3		  ;加1键按下时,进行加1运算
    	MOV   A,@R0
        ADD   A,66H
		MOV   B,#10
		DIV   AB
		CJNE  R0,#44H,DA_14		  ;判断是年份千百位的调整,是则年份千位数为十进制
DA_17:	CJNE  A,#10,DA_4				 
		MOV   A,#00H				 
		MOV   @R0,B
DA_ET1:	AJMP  DA_EXIT
DA_14:	CJNE  R0,#45H,DA_15		  ;判断是否年份的校准,是则年份百位数为十进制
        AJMP  DA_17
DA_15:	CJNE  R0,#46H,DA_16		  ;判断是否月的校准,是则月十位数为二进制
        CJNE  A,#02H,DA_4
		MOV   A,#00H
		MOV   @R0,B
		AJMP  DA_EXIT
DA_16:  CJNE  R0,#47H,DA_ET1	  ;判断是否日的校准,是则十位数为四进制
        CJNE  A,#4,DA_4
		MOV   A,#00H
		MOV   @R0,B
		AJMP  DA_EXIT
DA_4:   MOV   A,@R0
        ADD   A,66H
        MOV   @R0,A				  ;保存校准值
        AJMP  DA_EXIT
DA_3:   CJNE  A,#02H,DA_ET1		  ;是减1键按下时
        MOV   A,@R0
		MOV   B,#10
		DIV   AB
		CJNE  A,#00H,DA_6		  ;为负数时则返回为相应进制最高数
		MOV   A,B
		CJNE  R0,#44H,DA_23		  ;年份千高位十进制
		ADD   A,#90
		AJMP  DA_26
DA_23:  CJNE  R0,#45H,DA_24		  ;年份十位数十进制
        ADD   A,#90
		AJMP  DA_26
DA_24:  CJNE  R0,#46H,DA_25		  ;月份十位数二进制
        ADD   A,#10
		AJMP  DA_26
DA_25:  CJNE  R0,#47H,DA_EXIT	  ;日十位数四进制
        ADD   A,#30
DA_26:	MOV   @R0,A
		AJMP  DA_EXIT     
DA_6:	MOV   A,@R0
        CLR   C
        SUBB  A,66H
		MOV   @R0,A
		AJMP  DA_EXIT
DA_2:   CJNE  A,#02H,DA_7		  ;年,百位数调整
        MOV   R0,#44H
DA_19:  MOV   A,36H
		CJNE  A,#01H,DA_8
		MOV   A,@R0
		MOV   B,#10
		DIV   AB
		MOV   A,B
		ADD   A,66H
		CJNE  A,#10,DA_9
		MOV   A,@R0
		CLR   C
		SUBB  A,B
		MOV   @R0,A
		AJMP  DA_EXIT
DA_9:   INC   @R0
        SJMP  DA_EXIT
DA_8:   CJNE  A,#02H,DA_EXIT
        MOV   A,@R0
		MOV   B,#10
		DIV   AB
		MOV   A,B
		CJNE  A,#00H,DA_11
		MOV   A,@R0
		ADD   A,#09H
		MOV   @R0,A
		AJMP  DA_EXIT
DA_11:  MOV   A,@R0
        CLR   C
		SUBB  A,66H
		MOV   @R0,A
		AJMP  DA_EXIT		
DA_7:   CJNE  A,#03H,DA_12		  ;年,十位数调整
		MOV   R0,#45H
		AJMP  DA_13
DA_12:  CJNE  A,#04H,DA_18		  ;年,个位数调整
		MOV   R0,#45H
		AJMP  DA_19
DA_18:  CJNE  A,#05H,DA_20		  ;月,十位数调整
        MOV   R0,#46H
		AJMP  DA_13
DA_20:  CJNE  A,#06H,DA_21		  ;月,个位数调整
        MOV   R0,#46H
		AJMP  DA_19
DA_21:  CJNE  A,#07H,DA_22		  ;日,十位数调整
        MOV   R0,#47H
		AJMP  DA_13
DA_22:  CJNE  A,#08H,DA_EXIT	  ;日,个位数调整
        MOV   R0,#47H
		AJMP  DA_19						  
DA_EXIT:MOV   74H,44H
		MOV   75H,45H
		MOV   76H,46H
		MOV   77H,47H			  ;保存设置结果
		MOV   36H,#00H
        RET
;*****************************************************************************************
;****************************************************************************
ALARMCLOCK:             		  ;闹钟设置子程序
        LCALL DISPLAY3
		MOV   A,65H
		CJNE  A,#00H,AL_1         ;判断是否进行闹钟设置
		MOV   A,38H
		CJNE  A,#00H,AL_ET1
		MOV   56H,70H
		MOV   57H,71H
		MOV   58H,72H
		MOV   59H,73H
		INC   38H
		AJMP  AL_EXIT
AL_1:   CJNE  A,#01H,AL_2        ;选择小时的十位数进行校准
        MOV   R0,#56H
AL_13:  MOV   A,36H
        CJNE  A,#01H,AL_3        ;加1键
		MOV   A,@R0
		ADD   A,66H
		MOV   B,#10
		DIV   AB
		CJNE  R0,#56H,AL_14		  ;判断是小时的调整
		CJNE  A,#3,AL_4
		MOV   A,#00H
		MOV   @R0,B
AL_ET1: AJMP  AL_EXIT
AL_14:  CJNE  R0,#57H,AL_15       ;判断分
AL_17:  CJNE  A,#6,AL_4
        MOV   A,#00H
		MOV   @R0,B
		AJMP  AL_EXIT
AL_15:  CJNE  R0,#58H,AL_16      ;判断秒
        AJMP  AL_17
AL_16:  CJNE  R0,#59H,AL_ET1
        CJNE  A,#10,AL_4
		MOV   A,#00H
		MOV   @R0,B
		AJMP  AL_EXIT
AL_4:   MOV   A,@R0
        ADD   A,66H
		MOV   @R0,A      ;保存校准值
		AJMP  AL_EXIT
AL_3:   CJNE  A,#02H,AL_ET1    ;减1键
        MOV   A,@R0
		MOV   B,#10
		DIV   AB
		CJNE  A,#00H,AL_6
		MOV   A,B
		CJNE  R0,#56H,AL_23
		ADD   A,#20
		AJMP  AL_24
AL_23:  CJNE  R0,#57H,AL_25
        ADD   A,#50
		AJMP  AL_24
AL_25:  CJNE  R0,#58H,AL_26
        ADD   A,#50
		AJMP  AL_24
AL_26:  CJNE  R0,#59H,AL_24
        ADD   A,#90
AL_24:  MOV   @R0,A
        AJMP  AL_EXIT
AL_6:   MOV   A,@R0
        CLR   C
		SUBB  A,66H
		MOV   @R0,A
		AJMP  AL_EXIT
AL_2:   CJNE  A,#02H,AL_7				 ;时,个位数调整
        MOV   R0,#56H
AL_19:  MOV   A,36H
        CJNE  A,#01H,AL_8
		MOV   A,@R0
		MOV   B,#10
		DIV   AB
		MOV   A,B
		ADD   A,66H
		CJNE  A,#10,AL_9
		MOV   A,@R0
		CLR   C
		SUBB  A,B
		MOV   @R0,A
		AJMP  AL_EXIT
AL_9:   INC   @R0
        AJMP  AL_EXIT
AL_8:   CJNE  A,#02H,AL_EXIT
        MOV   A,@R0
		MOV   B,#10
		DIV   AB
		MOV   A,B
		CJNE  A,#00H,AL_11
		MOV   A,@R0
		ADD   A,#09H
		MOV   @R0,A
		AJMP  AL_EXIT
AL_11:  MOV   A,@R0
        CLR   C
		SUBB  A,66H
		MOV   @R0,A
		AJMP  AL_EXIT
AL_7:   CJNE  A,#03H,AL_12          ;分,十位数设置
        MOV   R0,#57H
		AJMP  AL_13
AL_12:  CJNE  A,#04H,AL_18      ;分,个位数设置
        MOV   R0,#57H
		AJMP  AL_19
AL_18:  CJNE  A,#05H,AL_20     ;秒,十位数设置
        MOV   R0,#58H
		AJMP  AL_13
AL_20:  CJNE  A,#06H,AL_21     ;秒,个位数设置
        MOV   R0,#58H
		AJMP  AL_19
AL_21:  CJNE  A,#07H,AL_22     ;0.01秒,十位数设置
        MOV   R0,#59H
		AJMP  AL_13
AL_22:  CJNE  A,#08H,AL_EXIT
        MOV   R0,#59H
		AJMP  AL_19
AL_EXIT:MOV   70H,56H
        MOV   71H,57H
		MOV   72H,58H
		MOV   73H,59H
		MOV   36H,#00H
		RET

;*******************************************************************************
STOPWATCH:							;秒表子程序,52H~55H为秒表暂存单元,35H单元为控制信号单元
        LCALL DISPLAY4
		MOV   A,35H	
		CJNE  A,#00H,ST_1
		SJMP  ST_EXIT
ST_1:   CJNE  A,#01H,ST_2			;开始计时,key1键做开始、停止控制 
        MOV   R3,#00H
ST_4:	MOV   A,34H
        CJNE  A,#04H,ST_3
        LCALL DISPLAY4
        MOV   A,35H					          
        CJNE  A,#02H,ST_4			;检测是否停止,是则退出计时,否则继续
ST_2:   CJNE  A,#03H,ST_EXIT		;复位key2键做复位控制
ST_3:   MOV   52H,#00H
		MOV   53H,#00H
		MOV   54H,#00H
		MOV   55H,#00H
        MOV   35H,#00H
ST_EXIT:RET

TIME:   							;秒表时钟源
        INC   55H
		MOV   A,55H
		CJNE  A,#100,TI_EXIT
		MOV   55H,#00H     
		INC   54H
		MOV   A,54H
		CJNE  A,#60,TI_EXIT
		MOV   54H,#00H
		INC   53H
		MOV   A,53H
		CJNE  A,#60,TI_EXIT
		MOV   53H,#00H
		INC   52H
		MOV   A,52H
		CJNE  A,#24,TI_EXIT
		MOV   52H,#00H
TI_EXIT:RET	
;**********************************************************************************
RING:								;闹钟判断及铃声产生70H~73H
		MOV   A,30H
		CJNE  A,70H,RI_EXIT
		MOV   A,31H
		CJNE  A,71H,RI_EXIT
		MOV   A,32H
		CJNE  A,72H,RI_EXIT
		MOV   50H,#01H   
RI_EXIT:
        RET	            
;***********************************************************************************
KEYSET: 				                ;键盘中断检测处理程序,34H~38H,60H,65H,66H
        PUSH  PSW
		PUSH  ACC
		PUSH  DPH
		PUSH  DPL						
	    JNB   P1.4,DELAY
	    JNB   P1.5,DELAY
	    JNB   P1.6,DELAY
	    JNB   P1.7,DELAY
	    AJMP   KEYEND
DELAY:	LCALL D10MS
	    JNB   P1.4,COL0			    ;判断是否有键按下
	    JNB   P1.5,COL1 
	    JNB   P1.6,COL2

⌨️ 快捷键说明

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