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

📄 main.asm

📁 用51单片机做的时钟
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;单片机时钟控制程序,使用DS12887时钟芯片,具有掉电保护功能
;设计:张更生,时间:2005年11月6日
;版本:1。0

;********************************************************
;编译预定义	        
	CS	EQU	P1.3
	HOUR	EQU	40H	;小时
	MUNITE	EQU	41H	;分钟
	SECOND	EQU	42H	;秒
	YEAR	EQU	43H	;年
	MONTH	EQU	44H	;月
	DAY	EQU	45H	;日
	HOLIDAY	EQU	46H	;星期
	MS	EQU	3AH	;MS,MS255共用于定时
	MS255	EQU	3BH
	KEY_DIR_1	EQU	01H
	OVER3S	EQU	02H	;是否按住按键超过三秒
	KEY_DIR	EQU	03H	;是否有按键输出
	KEY_VOL	EQU	3CH	;用于存按键值
	FLASH_BIT	EQU	3DH


	ORG	0000H
	SJMP	0030H
	ORG	000BH		;定时器T0中断控制动态显示
	LJMP	ITP_T0
	ORG 	0030H
MAIN:	
	MOV	SP,	#60H	;INIT_RAM
	CLR	EA
	CLR	KEY_DIR_1
	CLR	KEY_DIR
	CLR	OVER3S
				
	MOV	TMOD,	#01H	;初始化定时器T0
	MOV	TH0,	#0FCH	;定时1MS
	MOV	TL0,	#17H
	MOV	P0,	30H
	MOV	38H,	#0FEH
	MOV	39H,	#30H	;动态显示缓存指针
	MOV	P2,	#0FEH
	MOV	FLASH_BIT,#00H
	SETB	EA		;启动定时器1MS中断显示功能
	SETB	ET0
	SETB	TR0
;********************************************************
;DS12887初始化
DS12887:
	CLR	TR0
	CLR	CS
	PUSH	P0
	MOV	P0,	#0FFH

	MOV	DPH,	P2
	MOV	DPL,	#0AH
	MOV	A,	#20H
	MOVX	@DPTR,	A
	MOV	DPL,	#0BH
	MOV	A,	#02H
	MOVX	@DPTR,	A
	MOV	DPL,	#50H
	MOV	A,	#20H
	MOVX	@DPTR,	A

	POP	P0
	SETB	CS
	SETB	TR0
;********************************************************

LOOP:	
	CALL	TIME_DISP	;调用时间显示子程序
	CALL	KEYBO		;调用按键查询
	CALL	DATE_DISP	;调用日期显示
	CALL	CHANGE_TIME	;调用时间设置子程序
	CALL	CHANGE_RING	;改变打铃设置
	SJMP	LOOP



















;***************************************************************************************
;***************************************************************************************
;定时器一中断子程序
ITP_T0: CLR	EA
	PUSH	ACC
	MOV	R0,	39H
	INC	R0
	MOV	39H,	R0
	CJNE	R0,	#38H,	N_RESET
	MOV	R0,	#30H	;如果超出缓存范围,指针重置
	MOV	39H,	#30H
N_RESET:MOV	A,	@R0
	CPL	A
	MOV	P0,	A
	MOV	A,	38H
	RL	A
	MOV	38H,	A
	ORL	A,	FLASH_BIT
	MOV	P2,	A

	MOV	A,	MS	;计时(MS,MS255)
	ADD	A,	#01H
	MOV	MS,	A
	MOV	A,	MS255
	ADDC	A,	#00H
	MOV	MS255,	A
	MOV	A,	MS
	CJNE	A,	#0FEH,	TIP_T0_NEXT
	SETB	00H

TIP_T0_NEXT:
	MOV	TH0,	#0FCH	;定时1MS
	MOV	TL0,	#17H
	POP	ACC
	SETB	EA
	RETI
;*********************************************************
;时间显示子程序
TIME_DISP:
	JNB	00H,	TIME_RET
	CLR	00H
	CLR	TR0
	CLR	CS
	PUSH	P0
	MOV	P0,	#0FFH

	MOV	DPH,	P2
	MOV	DPL,	#0AH
	MOVX	A,	@DPTR
	JB	ACC.7,	TIME_DISP;直到UIP位为0时才能读数据
	MOV	DPL,	#04H
	MOVX	A,	@DPTR
	MOV	HOUR,	A
	MOV	DPL,	#02H
	MOVX	A,	@DPTR
	MOV	MUNITE,	A
	MOV	DPL,	#00H
	MOVX	A,	@DPTR
	MOV	SECOND,	A

	POP	P0		;恢复
	SETB	CS
	SETB	TR0

	MOV	DPTR,	#TIME_TAB	;拆字并送往显存
	MOV	32H,	#40H	;显示"-"
	MOV	35H,	#40H
	MOV	A,	HOUR	;以下产生时的高位
	ANL	A,	#0F0H
	SWAP	A
	MOVC	A,	@A+DPTR
	MOV	30H,	A
	MOV	A,	HOUR	;以下产生时的低位
	ANL	A,	#0FH
	MOVC	A,	@A+DPTR
	MOV	31H,	A
	MOV	A,	MUNITE	;以下产生分的高位
	ANL	A,	#0F0H
	SWAP	A
	MOVC	A,	@A+DPTR
	MOV	33H,	A
	MOV	A,	MUNITE	;以下产生分的低位
	ANL	A,	#0FH
	MOVC	A,	@A+DPTR
	MOV	34H,	A
	MOV	A,	SECOND	;以下产生秒的高位
	ANL	A,	#0F0H
	SWAP	A
	MOVC	A,	@A+DPTR
	MOV	36H,	A
	MOV	A,	SECOND	;以下产生秒的低位
	ANL	A,	#0FH
	MOVC	A,	@A+DPTR
	MOV	37H,	A
;	sjmp	$
	
TIME_RET:RET
TIME_TAB:DB      3FH,    06H,    5BH,    4FH,    66H,    6DH
        DB      7DH,    07H,    7FH,    6FH,    00H,    78H
        DB      31H,    40H

;***************************************************************
;日期显示子程序
DATE_DISP:
	JNB	KEY_DIR,DATE_RET2	;按键确认
	MOV	A,	KEY_VOL
	CJNE	A,	#01H,	DATE_RET
	CLR	KEY_DIR

	MOV	MS,	#00H	;对计时器清零
	MOV	MS255,	#00H	

DATE_DISP1:
	JNB	00H,	DATE_DIS_NO;每255MS调用一次日期显示
	CLR	00H
	CLR	TR0
	CLR	CS
	PUSH	P0
	MOV	P0,	#0FFH

	CALL	GET_DATE	;获取日期数据

	POP	P0		;恢复
	SETB	CS
	SETB	TR0

	MOV	DPTR,	#TIME_TAB	;拆字并送往显存
	MOV	32H,	#40H	;显示"-"
	MOV	35H,	#00H
	MOV	A,	MONTH	;以下产生月份的高位
	ANL	A,	#0F0H
	SWAP	A
	MOVC	A,	@A+DPTR
	MOV	30H,	A
	MOV	A,	MONTH	;以下产生月份的低位
	ANL	A,	#0FH
	MOVC	A,	@A+DPTR
	MOV	31H,	A
	MOV	A,	DAY	;以下产生日期的高位
	ANL	A,	#0F0H
	SWAP	A
	MOVC	A,	@A+DPTR
	MOV	33H,	A
	MOV	A,	DAY	;以下产生日期的低位
	ANL	A,	#0FH
	MOVC	A,	@A+DPTR
	MOV	34H,	A
	MOV	A,	HOLIDAY	;以下产生星期的高位
	ANL	A,	#0F0H
	SWAP	A
	MOVC	A,	@A+DPTR
	MOV	36H,	A
	MOV	A,	HOLIDAY	;以下产生星期的低位
	ANL	A,	#0FH
	MOVC	A,	@A+DPTR
	MOV	37H,	A
	

DATE_DIS_NO:
	CALL	KEYBO
	JNB	KEY_DIR,DATE_WAIT
	CLR	KEY_DIR
	SJMP	DATE_RET
DATE_RET2:SJMP	DATE_RET;中转
DATE_WAIT:
	MOV	A,	MS255	;日期显示时间超过4秒后退出
	CJNE	A,	#0FH,	DATE_DISP1	

DATE_RET:RET
;****************************************************************
;
GET_DATE:
	MOV	DPH,	P2
	MOV	DPL,	#0AH
	MOVX	A,	@DPTR
	JB	ACC.7,	DATE_DIS_NO;直到UIP位为0时才能读数据
	MOV	DPL,	#09H
	MOVX	A,	@DPTR
	MOV	YEAR,	A
	MOV	DPL,	#08H
	MOVX	A,	@DPTR
	MOV	MONTH,	A
	MOV	DPL,	#07H
	MOVX	A,	@DPTR
	MOV	DAY,	A
	MOV	DPL,	#06H
	MOVX	A,	@DPTR
	MOV	HOLIDAY,	A

;****************************************************************
;系统设置子程序
CHANGE_TIME:
	JB	KEY_DIR,	CHANGE1
CGE_RET1:LJMP	CHANGE_RET
CHANGE1:
	MOV	A,	KEY_VOL
	CJNE	A,	#81H,	CGE_RET1
	CLR	KEY_DIR	
	CLR	TR0		;以下十行程序用于关闭DS12887的时钟更新
	CLR	CS
	PUSH	P0
	MOV	DPH,	P2
	MOV	DPL,	#0BH
	MOV	A,	#82H
	MOVX	@DPTR,	A
	CALL	GET_DATE
	POP	P0
	SETB	CS
	SETB	TR0
		
	MOV	DPTR,	#TIME_TAB	;拆字并送往显存
	MOV	32H,	#00H	;显示"="
	MOV	35H,	#00H
	MOV	A,	YEAR	;以下产生年的高位
	ANL	A,	#0F0H
	SWAP	A
	MOVC	A,	@A+DPTR
	MOV	30H,	A
	MOV	A,	YEAR	;以下产生年的低位
	ANL	A,	#0FH
	MOVC	A,	@A+DPTR
	MOV	31H,	A
	MOV	A,	MONTH	;以下产生月份的高位
	ANL	A,	#0F0H
	SWAP	A
	MOVC	A,	@A+DPTR
	MOV	33H,	A
	MOV	A,	MONTH	;以下产生月份的低位
	ANL	A,	#0FH
	MOVC	A,	@A+DPTR
	MOV	34H,	A
	MOV	A,	DAY	;以下产生日期的高位
	ANL	A,	#0F0H
	SWAP	A
	MOVC	A,	@A+DPTR
	MOV	36H,	A
	MOV	A,	DAY	;以下产生日期的低位
	ANL	A,	#0FH
	MOVC	A,	@A+DPTR
	MOV	37H,	A
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^关于年份的设置

CHANGE_YEAR:
	MOV	R7,	#00000011B	;位闪
	CALL	FLASH
 CHANGE_YEAR2:

	CALL	KEYBO
	JNB	OVER3S,	YEAR_NEXT
	MOV	A,	KEY_VOL
	CJNE	A,	#82H,	YEAR_NEXT

	CALL	INC_YEAR
	CALL	DLY100MS

	CALL	SAVE_12887	;更新DS12887的数据
	SJMP	CHANGE_YEAR2

YEAR_NEXT:		
	JNB	KEY_DIR,CHANGE_YEAR
	CLR	KEY_DIR
	MOV	A,	KEY_VOL
	CJNE	A,	#01H,	YEAR_KEY2	;按功能键的处理
	SJMP	CHANGE_MONTH
YEAR_KEY2:CJNE	A,	#02H,	YEAR_KEY3	;按调整键的处理
	CALL	INC_YEAR
	CALL	SAVE_12887
	SJMP	CHANGE_YEAR
YEAR_KEY3:CJNE	A,	#04H,	CHANGE_YEAR	;按返回键的处理
	CALL	UPDATA_ON
	RET
	
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^关于月份的调置
CHANGE_MONTH:
	MOV	R7,	#00011000B
	CALL	FLASH

CHANGE_MONTH2:

	CALL	KEYBO
	JNB	OVER3S,	MONTH_NEXT
	MOV	A,	KEY_VOL
	CJNE	A,	#82H,	MONTH_NEXT

	CALL	INC_MONTH
	CALL	DLY100MS

	CALL	SAVE_12887	;更新DS12887的数据
	SJMP	CHANGE_MONTH2

MONTH_NEXT:		
	JNB	KEY_DIR,CHANGE_MONTH
	CLR	KEY_DIR
	MOV	A,	KEY_VOL
	CJNE	A,	#01H,	MONTH_KEY2	;按功能键的处理
	SJMP	CHANGE_DAY
MONTH_KEY2:CJNE	A,	#02H,	MONTH_KEY3	;按调整键的处理
	CALL	INC_MONTH
	CALL	SAVE_12887
	SJMP	CHANGE_MONTH
MONTH_KEY3:CJNE	A,	#04H,	CHANGE_MONTH	;按返回键的处理
	CALL	UPDATA_ON
	RET

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^关于天的设置
CHANGE_DAY:
	MOV	R7,	#11000000B
	CALL	FLASH

CHANGE_DAY2:

	CALL	KEYBO
	JNB	OVER3S,	DAY_NEXT
	MOV	A,	KEY_VOL
	CJNE	A,	#82H,	DAY_NEXT

	CALL	INC_DAY
	CALL	DLY100MS

	CALL	SAVE_12887	;更新DS12887的数据
	SJMP	CHANGE_DAY2

DAY_NEXT:		
	JNB	KEY_DIR,CHANGE_DAY
	CLR	KEY_DIR
	MOV	A,	KEY_VOL
	CJNE	A,	#01H,	DAY_KEY2	;按功能键的处理
	SJMP	CHANGE_HOUR_L
DAY_KEY2:CJNE	A,	#02H,	DAY_KEY3	;按调整键的处理
	CALL	INC_DAY
	CALL	SAVE_12887
	SJMP	CHANGE_DAY
DAY_KEY3:CJNE	A,	#04H,	CHANGE_DAY	;按返回键的处理

⌨️ 快捷键说明

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