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

📄 clock.txt

📁 汇编语言编写的电子日历时钟程序:显示/校准时间
💻 TXT
字号:

		ORG 0000H
		LJMP MAIN
		ORG 0003H
		LJMP AJ0			    ;外部中断0
		ORG 000BH
		LJMP TUP		        ;定时/计数器T0中断
		ORG 0013H
		LJMP AJ1		     	;外部中断1
		ORG 0030H
MAIN:	NOP				    ;主程序
		MOV SP,#60H            ;设置堆栈指针
		MOV 21H,#00H			;秒BCD码存储单元
		MOV 22H,#00H			;分BCD码存储单元
		MOV 23H,#00H			;小时BCD码存储单元
		MOV 24H,#00H			;日BCD码存储单元
		MOV 25H,#00H			;月BCD码存储单元
		MOV 26H,#00H			;年BCD码存储单元
		MOV 27H,#00H			;闪烁标志
		MOV R7,#00H		    ;时间/日期转换标志
		MOV TL0,#0B0H		    ;装T0的时间常数
		MOV TH0,#3CH			;T0一次中断时间为0.05秒
		MOV 20H,#14H	        ;T0循环计时次数20次
		MOV TMOD,#01H		    ;T0初始化:方式1,计数位16位
		SETB ET0				;开T0中断
		SETB EX0				;开外部中断0(INT0)
		SETB EX1				;开外部中断1(INT1)
		SETB EA			    ;CPU开中断
		SETB PT0				;设置T0中断为高优先级
		SETB TR0				;T0开始计时
		SJMP $				    ;等待中断
	
; // sub: T0中断程序 //

TUP:	MOV TL0,#0B0H		    ;重装T0的时间常数
		MOV TH0,#3CH
		DJNZ 20H,INTER1	    ;循环20次(是否达到1秒)?
		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: LED显示程序 //

DISP:	MOV DPTR,#TABLE		 ;取显示编码表头地址
		MOV A,R7				;取时间/日期转换显示标志
		CJNE A,#00H,DATE		 ;“00H”为显示时间
TIME:	MOV R0,#21H		    ;取秒地址
		SJMP TSAVE
DATE:	MOV R0,#24H			;“FFH”为显示日期,取日地址
TSAVE:	MOV A,@R0			    ;取日的BCD码
		ANL A,#0FH			    ;得到低四位
		MOVC A,@A+DPTR		;取编码表中的相应编码
		MOV R1,A				;存显示数值到(R1)
		MOV A,@R0
		SWAP A
		ANL A,#0FH			    ;得到高四位
		MOVC A,@A+DPTR	    ;取编码表中的相应编码
		MOV R2,A				;存显示数值到(R2)
		INC R0                  ;地址增一
		MOV A,@R0			    ;取分/月的BCD码
		ANL A,#0FH			    ;得到低四位
		MOVC A,@A+DPTR      ;取编码表中的相应编码
		MOV R3,A				;存显示数值到(R3)
		MOV A,@R0
		SWAP A
		ANL A,#0FH			    ;得到高四位
		MOVC A,@A+DPTR      ;取编码表中的相应编码
		MOV R4,A				;存显示数值到(R4)
		INC R0
		MOV A,@R0			    ;取时/年的BCD码
		ANL A,#0FH			    ;得到低四位
		MOVC A,@A+DPTR      ;取编码表中的相应编码
		MOV R5,A				;存显示数值到(R5)
		MOV A,@R0
		SWAP A
		ANL A,#0FH			    ;得到高四位
		MOVC A,@A+DPTR      ;取编码表中的相应编码
		MOV R6,A				;存显示数值到(R6)
	NOP TDISP:	MOV P2,#0FFH			;熄灭所有的LED 		MOV P0,R1			    ;数值输往DS6 		MOV A,27H			    ;取闪烁标志 		CJNE A,#03H,AA		    ;“03H”则DS5&DS6闪烁  		SJMP AAA AA:		CJNE A,#06H,AAAA		;“06H”则DS5&DS6闪烁 AAA:	MOV A,20H			    ;取T0计时循环次数
		RRC A				    
		JNC AAAAA			    ;最低位为1则开DS6
AAAA:	MOV P2,#0FEH			
AAAAA:	LCALL DELAY           ;调用延迟程序
		MOV P2,#0FFH			;熄灭所有的LED
		MOV P0,R2			    ;数值输往DS5
		MOV A,27H			    ;取闪烁标志
		CJNE A,#03H,BB		    ;“03H”则DS5&DS6闪烁 
		SJMP BBB
BB:		CJNE A,#06H,BBBB		;“06H”则DS5&DS6闪烁
BBB:	MOV A,20H			    ;取T0计时循环次数
		RRC A
		JNC BBBBB			    ;最低位为1则开DS5
BBBB:	MOV P2,#0FDH			
BBBBB:	LCALL DELAY          ;调用延时程序
		MOV P2,#0FFH			;熄灭所有的LED
		MOV P0,R3			    ;数值输往DS4
		MOV A,27H			    ;取闪烁标志
		CJNE A,#02H,CC		    ;“02H”则DS3&DS4闪烁 
		SJMP CCC
CC:		CJNE A,#05H,CCCC		;“05H”则DS3&DS4闪烁
CCC:	MOV A,20H		    	;取T0计时循环次数
		RRC A
		JNC CCCCC			    ;最低位为1则开DS4
CCCC:	MOV P2,#0FBH			;
CCCCC:	LCALL DELAY          ;调用延时程序
		MOV P2,#0FFH			;熄灭所有的LED 
		MOV P0,R4			    ;数值输往DS3
		MOV A,27H			    ;取闪烁标志
		CJNE A,#02H,DD		    ;“02H”则DS3&DS4闪烁
		SJMP DDD
DD:		CJNE A,#05H,DDDD		;“05H”则DS3&DS4闪烁
DDD:	MOV A,20H    			;取T0计时循环次数
		RRC A
		JNC DDDDD			    ;最低位为1则开DS3
DDDD:	MOV P2,#0F7H			;
DDDDD:	LCALL DELAY          ;调用延时程序
		MOV P2,#0FFH			;熄灭所有的LED
		MOV P0,R5			    ;数值输往DS2		
		MOV A,27H			    ;取闪烁标志
		CJNE A,#01H,EE		    ;“01H”则DS1&DS2闪烁
		SJMP EEE
EE:		CJNE A,#04H,EEEE		;“04H”则DS1&DS2闪烁
EEE:	MOV A,20H		    	;取T0计时循环次数
		RRC A
		JNC EEEEE			    ;最低位为1则开DS2
EEEE:	MOV P2,#0EFH			;
EEEEE:	LCALL DELAY          ;调用延时程序
		MOV P2,#0FFH			;熄灭所有的LED
		MOV P0,R6			    ;数值输往DS1	
		MOV A,27H			    ;取闪烁标志
		CJNE A,#01H,FF		    ;“01H”则DS1&DS2闪烁
		SJMP FFF
FF:		CJNE A,#04H,FFFF	   ;“04H”则DS1&DS2闪烁 
FFF  :	MOV A,20H		       ;取T0计时循环次数
		RRC A	
		JNC FFFFF		    	;最低位为1则开DS1
FFFF:	MOV P2,#0DFH			;
FFFFF:	LCALL DELAY           ;调用延时程序
RET

; // sub:延时程序 //

DELAY:	MOV 28H,#03H
D2:		MOV 29H,#0FFH
D1:		DJNZ 29H,D1
		DJNZ 28H,D2
		RET

; // sub: INT0中断服务程序 //

AJ0    :NOP					    ; 切换/调整时间/日期
		PUSH PSW
		LCALL DMS			    ;调用按键操作程序(包括LED显示)
		JNB P3.3,OUT			;检查端口INT1,高电平表示key0按下
		NOP					    
		MOV A,27H			    ;取闪烁标志
		CJNE A,#00H,ADJYY	    ;“00H”则不闪烁

		MOV A,R7				;取时间/日期显示转换标志
		XRL A,#0FFH			    ;修改标志
		MOV R7,A				;保存标志
		LCALL DISP			    ;LED显示
OUT:	LJMP AEND0
ADJYY:	NOP					 ;“01 to 06”闪烁
CJNE A,#01H,ADJMM	    ;“01H”表示调整年
		MOV A,26H			    ;取年的BCD码
		CJNE A,#99H,ADJYY0	    ;是否为99年,否则转年加一
		MOV 26H,#00H			;保存第一年数值(00年)
		LJMP ADJYYF
ADJYY0:ADD A,#01H			    ;年数值加一 
		DA A					;BCD调整
		MOV 26H,A			    ;保存年的数值
ADJYYF:LJMP AEND0
ADJMM:	CJNE A,#02H,ADJDD	    ;“02H”表示调整月
		MOV A,25H			    ;取月的BCD码
		CJNE A,#12H,ADJMM0    ;是否为12月,否则转月加一
		MOV 25H,#01H			;存第一个月数值(1月)
		LJMP ADJMMF
ADJMM0:ADD A,#01H		    	;月数值加一
		DA A					;BCD码调整
		MOV 25H,A			    ;存月的数值
ADJMMF:LJMP AEND0
ADJDD:	CJNE A,#03H,AA1 		;“03H”表示调整日
		LJMP BB1
AA1:	LJMP ADJH	
BB1:	MOV A,25H	     		;取月的BCD码
		CJNE A,#02H,NFEB		;判断是否为二月,是则转二月处理
FEB:	NOP			
		ACALL  BCD			;调用平年闰年判断程序
		MOV A,R3				;程序参数传递
		CJNE A,#00H,APING	    ;“00H”则表示闰年
ARUN:	MOV A,24H			    ;取(闰年)日的BCD码
		CJNE A,#29H,DDA	    ;是否为29号,否则转日加一
		LJMP DD01
APING:	MOV A,24H			    ;取(平年)日的BCD码
		CJNE A,#28H,DDA	    ;是否为28号,否则转日加一
		LJMP DD01
NFEB:	NOP				    ;判断大小月
		CJNE A,#04H,YUE4		;4月?
		LJMP ADD1
YUE4:	CJNE A,#06H,YUE5		;6月?
		LJMP ADD1
YUE5:	CJNE A,#09H,YUE6		;9月?
		LJMP ADD1
YUE6:	CJNE A,#11H,YUE7		;11月?
		LJMP ADD1
YUE7:	NOP				    ;大月处理
		MOV A,24H			    ;取日的BCD码
		CJNE A,#31H,DDA		;是否31号,否则转日加一
		LJMP DD01
ADD1:	NOP				    ;小月处理
MOV A,24H			    ;取日的BCD码
		CJNE A,#30H,DDA		;是否30号,否则转日加一
DD01:	MOV 24H,#01H			;保存第一天(1号)
		LJMP ADJDDF
DDA:	ADD A,#01H	     		;日加一 		DA A					;BCD码调整
		MOV 24H,A			    ;存日的数值
ADJDDF:LJMP AEND0
ADJH:	CJNE A,#04H,ADJM		;“04H”表示调整时
		MOV A,23H			    ;取时的BCD码
		CJNE A,#23H,ADJH0	    ;是否为23时,否则转时加一
		MOV 23H,#00H			;保存第一小时数值(00时)
		LJMP ADJHF
ADJH0:	ADD A,#01H			    ;时加一
		DA A					;BCD码调整
		MOV 23H,A			    ;保存时的数值
ADJHF:	LJMP AEND0
ADJM :  CJNE A,#05H,ADJS		;“05H”表示调整分
		MOV A,22H			    ;取分的BCD码
		CJNE A,#59H,ADJM0	    ;是否59分,否则转分加一
		MOV 22H,#00H			;存第一分钟(00分)
		LJMP ADJMF
ADJM0: ADD A,#01H			    ;分加一
		DA A					;BCD码调整
		MOV 22H,A			    ;存分的数值
ADJMF: LJMP AEND0
ADJS:   MOV A,21H			    ;取秒的BCD码
		CJNE A,#59H,ADJS0	    ;是否为59秒,否则转秒加一
		MOV 21H,#00H			;存第一秒的数值(00秒)
		LJMP ADJSF
ADJS0:  ADD A,#01H			    ;秒加一
		DA A					;BCD码调整
		MOV 21H,A			    ;存秒的数值
ADJSF:  NOP
AEND0: NOP
		POP PSW                 ;恢复标志寄存器内容
		RETI

; // sub: INT1中断服务程序 //

AJ1:    NOP					  
		PUSH PSW                ;保护标志寄存器内容
		LCALL DMS			    ;调用按键操作程序(包括LED显示)
		JNB P3.2,AEND1		    ;检查端口INT0,高电平表示key1按下
		NOP					    
		MOV A,R7				;取时间/日期显示转换标志
		CJNE A,#00H,EDIT0	    ;“00H”则显示时间
		MOV A,27H			    ;取闪烁标志
		CJNE A,#00H,EDIT2	    ;“00H”则在不闪烁状态
		MOV 27H,#04H			;存闪烁标志,表示DS1&DS2闪烁
		SJMP AEND1
EDIT2:  CJNE A,#06H,EDIT1	    ;“06H”表示DS5&DS6闪烁
		MOV 27H,#00H			;恢复到不闪烁状态
		SJMP AEND1
EDIT0:	NOP					 ;“R7=FFH”表示显示日期
 	    MOV A,27H		        ;取闪烁标志
		CJNE A,#03H,EDIT1	    ;“03H”表示DS5&DS6闪烁
		MOV 27H,#00H			;恢复到不闪烁状态
		SJMP AEND1
EDIT1:  INC A				    ;闪烁标志加一
		MOV 27H,A			    ;存闪烁标志
		NOP
AEND1: NOP
		POP PSW                 ;恢复标志寄存器内容
		RETI

; // sub:按键操作及LED显示程序 // 

DMS:    MOV 2AH,#09H   		   ; or(#0BH)
DMSS:   LCALL DISP			   ; with LED display
		DJNZ 2AH,DMSS
		RET

; // sub: BCD除法/

BCD:   MOV R0,26H			     ;存被除数BCD码
		MOV R1,#04H			 ;存除数BCD码
		MOV R2,#00H			 ;存商数BCD码
		MOV A,R1				 ;除数求补码
		CPL A				     ;
		ADD A,#9BH			     ;
		MOV R1,A				 ;存除数的补码
		MOV A,R0				 ;取被除数
		ANL A,#0F0H			     ;屏蔽被除数低四位
		SWAP A				     ;高四位转低四位
LP0:	    MOV R3,A				 ;存余数BCD码
		ADD A,R1				 ;加除数补码
		DA A					 ;BCD码调整
		JNC LP1				     ;C=1,被除数大于除数,继续加
		INC R2				     ;商数加一
		SJMP LP0
LP1:	    MOV A,R3				  ;取余数
		SWAP A				     ;高四位低四位对调
		MOV R3,A				 ;存余数
		MOV A,R2				 ;取商数
		SWAP A				     ;商数置高四位 
		MOV R2,A				 ;存商数
		MOV A,R0				 ;取被除数
		ANL A,#0FH			     ;屏蔽被除数高四位
		ORL A,R3				 
LP2:  	MOV R3,A				 ;存余数
		ADD A,R1				 ;加除数补码
		DA A					 ;BCD码调整
		JNC LP3				     ;C=1,被除数大于除数,继续加
		INC R2				     ;商加一
		SJMP LP2
LP3:	    NOP		    	 
		RET

; // code table 显示编码表//

TABLE:  DB 40H				; for “0”
		DB 79H				; for “1”
		DB 24H              ; for “2”
		DB 30H              ; for “3”
		DB 19H              ; for “4”
		DB 12H              ; for “5”
		DB 02H              ; for “6”
		DB 78H              ; for “7”
		DB 00H              ; for “8”
		DB 10H				; for “9”
		END

⌨️ 快捷键说明

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