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

📄 timer.asm

📁 带闹钟功能
💻 ASM
字号:
		HOUR	EQU	 	20H
		MIN		EQU		21H
		SEC		EQU		22H		;时钟单元
		A_HOUR	EQU		24H
		A_MIN	EQU		25H
		A_SEC	EQU		26H		;闹钟单元

		INT_NUM	EQU		23H		;中断次数
	  ADD_TIME	EQU		27H		;加16H的次数
	  ADD_NUM	EQU		28H		;按键加的数字
	REDUCE_NUM	EQU		29H		;按键减的数字
	SELECT_TIME	EQU		2AH		;选择键按的次数
	FUN_TIME	EQU		2BH		;功能键按的次数
	HIGH_NUM	EQU		2CH
	LOW_NUM		EQU		2DH		;定时器T1的计数值
	MUSIC_CODE	EQU		2EH		;音乐编码
	    CLAP 	EQU		30H		;节拍数

    ALARM_EN    BIT		78H		;2FH字节的第1位,闹钟使能标志
	ADD_SYMBOL	BIT		79H		;2FH字节的第2位,‘+’标志位
	HOUR_SYMBOL BIT		7AH		;小时标志位
ALARM_SYMBOL	BIT 	7BH		;闹钟标志位
		BUZZER	BIT		P3.7
		KEY1	BIT		P3.2
		KEY2	BIT		P3.3
		KEY3	BIT		P2.6
		KEY4	BIT		P2.7

        ORG     0000H
        LJMP    START
		ORG		000BH
        LJMP    TSERV 			;定时器T0中断入口地址
        ORG     001BH
        LJMP    ASERV			;定时器T1中断入口地址
		ORG		0030H

;****************************************************
;初始化
START:   
        CLR     BUZZER			 ;关闭蜂鸣器
		MOV     INT_NUM,#14H	 ;1s中断20次
		MOV		R0,#0FEH
		CLR		ALARM_EN
		CLR		ADD_SYMBOL
		CLR		HOUR_SYMBOL
		CLR		ALARM_SYMBOL
		MOV		A,#0
		MOV		SELECT_TIME,A
		MOV		FUN_TIME,A
		MOV		A_SEC,A
		MOV		A_MIN,A
		MOV		A_HOUR,A
        MOV     HOUR,A       	
        MOV     MIN,A        	
        MOV     SEC,A           ;时、分、秒单元初始化
		MOV		R2,A			;提取编码
		MOV		R3,A			;音乐编码
		MOV     TMOD,#11H	     ;设置定时器工作方式为方式1
        MOV		IE,#8AH          ;允许定时器中断
		MOV     TH0,#4CH
        MOV     TL0,#0			 ;装定时器T0初值,定时50ms
        SETB    TR0              ;启动定时器T0
;****************************************************
;主程序
MAIN:
KL1:	JB		KEY1,KL2
		ACALL   ALARM_FUN
		AJMP	ALR
KL2:	JB		KEY2,KL3
		ACALL	SELECT
		AJMP	ALR		  
KL3:	JB		KEY3,KL4
		ACALL   ADD_FUN
		AJMP	ALR
KL4:	JB		KEY4,ALR
		ACALL	REDUCE_FUN	  	;键盘扫描
ALR:	JNB		ALARM_EN,LOOP
		ACALL	ALARM_DIS
		AJMP	MAIN			 ;闹钟设置时的显示
LOOP:	JNB		ALARM_SYMBOL,LP
		ACALL	ALARM_DIST
LP:		ACALL	TIME_DIS		   ;时间的显示
		AJMP	MAIN
;****************************************************
;判断闹钟是否到时间
ALARM_DIST:
		MOV		A,HOUR
		CJNE	A,A_HOUR,RETAD
		MOV		A,MIN
		CJNE	A,A_MIN,RETAD
		MOV		A,SEC
		CJNE	A,A_SEC,RETAD	  ;如果时间到,即转到音乐程序
		AJMP	MUSIC
RETAD:  RET
;****************************************************
;闹钟设置键
ALARM_FUN:
WOB1:	ACALL	TIME_DIS
		JNB		KEY1,WOB1		;去抖动
		MOV		SELECT_TIME,#0	 ;清除选择键的按键次数
		INC		FUN_TIME
		MOV		A,FUN_TIME
		CJNE 	A,#1,LPA
		SETB	ALARM_EN		 ;置位闹钟设置
		SETB	ALARM_SYMBOL
		AJMP	LPAL
LPA:	CJNE	A,#2,LPAL		;第二次按键,返回时钟显示
		CLR		ALARM_EN
		MOV		FUN_TIME,#0
LPAL:	RET
;****************************************************
;选择功能键
SELECT:
WOB2:   JNB		ALARM_EN,TIMES
		ACALL	ALARM_DIS
		JNB		KEY2,WOB2
		AJMP	NORS
TIMES:	ACALL	TIME_DIS
		JNB		KEY2,WOB2		;去抖动
NORS:	INC		SELECT_TIME
		MOV		A,SELECT_TIME
		CJNE	A,#4,LPS		;超过4次,清零
		MOV		SELECT_TIME,#0
LPS:	RET	
;****************************************************		
;‘+’功能键
ADD_FUN:
		SETB	ADD_SYMBOL
		ACALL	JUDGEA
WOB3:   JNB		ALARM_EN,TIMEA	 ;判断是时钟还是闹钟
		ACALL	ALARM_DIS
		JNB		KEY3,WOB3
		AJMP	NORA
TIMEA:  ACALL	TIME_DIS
		JNB		KEY3,WOB3		;去抖动
NORA:	MOV     A,#01H
        ADD     A,ADD_NUM           
        DA      A
        MOV     ADD_NUM,A
		JNB		HOUR_SYMBOL,HOUS
		CJNE	A,#24H,BACKA
		MOV		ADD_NUM,#0		;调整小时,加到24H清零
		AJMP	BACKA		 
HOUS:	CJNE    A,#60H,BACKA	;调整分秒,60H清零
		MOV     ADD_NUM,#00H
BACKA:  ACALL	JUDGEB
		CLR		ADD_SYMBOL
		RET
;****************************************************
;‘-’功能键				
REDUCE_FUN:
		ACALL	JUDGEA
WOB4:   JNB		ALARM_EN,TIMER	 ;判断是时钟还是闹钟
		ACALL	ALARM_DIS
		JNB		KEY4,WOB4
		AJMP	NORR
TIMER:	ACALL	TIME_DIS
		JNB		KEY4,WOB4		;去抖动
NORR:	MOV		A,REDUCE_NUM
		ANL		A,#0F0H
		SWAP	A
		MOV		B,#10
		MUL		AB
		ANL		REDUCE_NUM,#0FH
		ADD		A,REDUCE_NUM	 ;将BCD码转为16进制数
		MOV		REDUCE_NUM,A
		CJNE    A,#00H,BACKR
		JNB		HOUR_SYMBOL,HOU
		MOV		REDUCE_NUM,#24
		AJMP	BACKR
HOU:    MOV     REDUCE_NUM,#60
BACKR:  DEC		REDUCE_NUM
 		MOV		A,REDUCE_NUM
		ANL		A,#0F0H
		SWAP	A
		CJNE	A,#0,UNZERO		 
		AJMP	ZERO			  ;如果十位为零,则跳转
UNZERO:	MOV		ADD_TIME,A
		CLR		A
		MOV		B,#16H
PLUS:	ADD		A,B
        DA      A
		DJNZ	ADD_TIME,PLUS
ZERO:	ANL		REDUCE_NUM,#0FH
		ADD		A,REDUCE_NUM
		DA		A
		MOV		REDUCE_NUM,A
		ACALL	JUDGEB
		RET
;****************************************************
;判断调整的时间单位,将数值赋予调整数
JUDGEA:
		MOV		A,SELECT_TIME
		JNB		ALARM_EN,LPM
;闹钟
		CJNE	A,#1,LPMA1
		MOV		ADD_NUM,A_SEC
		MOV		REDUCE_NUM,A_SEC
		AJMP	LPMA3
LPMA1:	CJNE	A,#2,LPMA2
		MOV		ADD_NUM,A_MIN
		MOV		REDUCE_NUM,A_MIN
		AJMP	LPMA3
LPMA2:	CJNE	A,#3,LPMA3
		MOV		ADD_NUM,A_HOUR
		MOV		REDUCE_NUM,A_HOUR
		SETB	HOUR_SYMBOL
LPMA3:	ACALL	ALARM_DIS
		AJMP	JDM
;时钟
LPM:	CJNE	A,#1,LPM1
		MOV		ADD_NUM,SEC
		MOV		REDUCE_NUM,SEC
		AJMP	LPM3
LPM1:	CJNE	A,#2,LPM2
		MOV		ADD_NUM,MIN
		MOV		REDUCE_NUM,MIN
		AJMP	LPM3
LPM2:	CJNE	A,#3,LPM3
		MOV		ADD_NUM,HOUR
		MOV		REDUCE_NUM,HOUR
		SETB	HOUR_SYMBOL
LPM3:	ACALL	TIME_DIS
JDM:	RET
;****************************************************
;判断调整的时间单位,从调整数返回数值
JUDGEB:
		MOV		A,SELECT_TIME
		JNB		ALARM_EN,LPJ
;闹钟
		CJNE	A,#1,LPJA1
		JNB		ADD_SYMBOL,REDA1
		MOV		A_SEC,ADD_NUM
		AJMP	LPJA3
REDA1:	MOV		A_SEC,REDUCE_NUM
		AJMP	LPJA3
LPJA1:	CJNE	A,#2,LPJA2
		JNB		ADD_SYMBOL,REDA2
		MOV		A_MIN,ADD_NUM
		AJMP	LPJA3
REDA2:	MOV		A_MIN,REDUCE_NUM
		AJMP	LPJA3
LPJA2:	CJNE	A,#3,LPJA3
	    JNB		ADD_SYMBOL,REDA3
		MOV		A_HOUR,ADD_NUM
		CLR		HOUR_SYMBOL
		AJMP	LPJA3
REDA3:	MOV		A_HOUR,REDUCE_NUM
		CLR		HOUR_SYMBOL
LPJA3:	ACALL	ALARM_DIS
		AJMP	JDJ
;时钟
LPJ:	CJNE	A,#1,LPJ1
		JNB		ADD_SYMBOL,RED1
		MOV		SEC,ADD_NUM
		AJMP	LPJ3
RED1:	MOV		SEC,REDUCE_NUM
		AJMP	LPJ3
LPJ1:	CJNE	A,#2,LPJ2
		JNB		ADD_SYMBOL,RED2
		MOV		MIN,ADD_NUM
		AJMP	LPJ3
RED2:	MOV		MIN,REDUCE_NUM
		AJMP	LPJ3
LPJ2:	CJNE	A,#3,LPJ3
		JNB		ADD_SYMBOL,RED3
		MOV		HOUR,ADD_NUM
		CLR		HOUR_SYMBOL
		AJMP	LPJ3
RED3:	MOV		HOUR,REDUCE_NUM
		CLR		HOUR_SYMBOL
LPJ3:	ACALL	TIME_DIS
JDJ:	RET

;****************************************************										
;时钟显示
TIME_DIS:
	    MOV     DPTR,#TABA		 ;送数码管编码的首地址      
        MOV     A,SEC
        ANL     A,#0FH           ;屏蔽秒单元高位
        MOVC    A,@A+DPTR
        MOV     P0,A
		MOV     P2,#0FEH
        ACALL   DELAY
        MOV     P2,#0FFH         ;消隐
        MOV     A,SEC
        ANL     A,#0F0H          ;屏蔽秒单元低位
        SWAP    A
        MOVC    A,@A+DPTR
        MOV     P0,A
		MOV     P2,#0FDH
        ACALL   DELAY            ;秒单元拆字,送出显示
        MOV     P2,#0FFH
        MOV     A,MIN
        ANL     A,#0FH           ;屏蔽分单元高位
        MOV		DPTR,#TABB
		MOVC    A,@A+DPTR
		MOV 	DPTR,#TABA
        MOV     P0,A
		MOV     P2,#0FBH
        ACALL   DELAY
        MOV     P2,#0FFH
        MOV     A,MIN
        ANL     A,#0F0H         ;屏蔽分单元低位
        SWAP    A
        MOVC    A,@A+DPTR
        MOV     P0,A
		MOV     P2,#0F7H
        ACALL   DELAY           ;分单元拆字,送出显示
        MOV     P2,#0FFH
        MOV     A,HOUR
        ANL     A,#0FH          ;屏蔽时单元高位
        MOV		DPTR,#TABB
		MOVC    A,@A+DPTR
		MOV 	DPTR,#TABA
        MOV     P0,A
		MOV     P2,#0EFH
        ACALL   DELAY
        MOV     P2,#0FFH
        MOV     A,HOUR
        ANL     A,#0F0H         ;屏蔽时单元低位
        SWAP    A
        MOVC    A,@A+DPTR
        MOV     P0,A
		MOV     P2,#0DFH
        ACALL   DELAY           ;时单元拆字,送出显示
        MOV     P2,#0FFH
        RET				        ;反复调用显示程序,等待中断
;****************************************************
;闹钟设置显示
ALARM_DIS:
	    MOV     DPTR,#TABA		 ;送数码管编码的首地址
        MOV     A,A_SEC
        ANL     A,#0FH          ;屏蔽秒单元高位
        MOVC    A,@A+DPTR
        MOV     P0,A
		MOV     P2,#0FEH
        ACALL   DELAY
        MOV     P2,#0FFH        ;消隐
        MOV     A,A_SEC
        ANL     A,#0F0H         ;屏蔽秒单元低位
        SWAP    A
        MOVC    A,@A+DPTR
        MOV     P0,A
		MOV     P2,#0FDH
        ACALL   DELAY           ;秒单元拆字,送出显示
        MOV     P2,#0FFH
        MOV     A,A_MIN
        ANL     A,#0FH          ;屏蔽分单元高位
        MOV		DPTR,#TABB
		MOVC    A,@A+DPTR
		MOV 	DPTR,#TABA
        MOV     P0,A
		MOV     P2,#0FBH
        ACALL   DELAY
        MOV     P2,#0FFH
        MOV     A,A_MIN
        ANL     A,#0F0H         ;屏蔽分单元低位
        SWAP    A
        MOVC    A,@A+DPTR
        MOV     P0,A
		MOV     P2,#0F7H
        ACALL   DELAY           ;分单元拆字,送出显示
        MOV     P2,#0FFH
        MOV     A,A_HOUR
        ANL     A,#0FH          ;屏蔽时单元高位
        MOV		DPTR,#TABB
		MOVC    A,@A+DPTR
		MOV 	DPTR,#TABA
        MOV     P0,A
		MOV     P2,#0EFH
        ACALL   DELAY
        MOV     P2,#0FFH
        MOV     A,A_HOUR
        ANL     A,#0F0H         ;屏蔽时单元低位
        SWAP    A
        MOVC    A,@A+DPTR
        MOV     P0,A
		MOV     P2,#0DFH
        ACALL   DELAY           ;时单元拆字,送出显示
        MOV     P2,#0FFH
        RET			            ;反复调用显示程序,等待中断
;****************************************************
;音乐程序
MUSIC:	SETB	TR1
MUSIC_START:
		MOV		A,R2
		MOV		DPTR,#MUSIC_TAB	  ;取音乐编码的首地址
		MOVC	A,@A+DPTR
		MOV		MUSIC_CODE,A
		JNZ		AGAIN
		MOV		R2,#0			  ;若取得的编码为0,则重新开始音乐
		AJMP	MUSIC
AGAIN:	ANL		A,#0F0H			  ;屏蔽低位
		SWAP	A
		CLR		C
		RLC		A
		MOV		R3,A
		MOV		DPTR,#TUNE_TAB	   ;送曲调地址
		MOVC	A,@A+DPTR
		MOV		HIGH_NUM,A
		INC		R3
		MOV		A,R3
		MOVC	A,@A+DPTR
		MOV		LOW_NUM,A
		MOV		A,MUSIC_CODE
		ANL		A,#0FH
		MOV		CLAP,A
		ACALL	MUSIC_DELAY		   ;一个编码运行时间
		INC		R2
		MOV		A,MIN
		CJNE	A,A_MIN,TIMEOUT
		AJMP	NEXT_TUNE
TIMEOUT:MOV		A,SEC
		CJNE	A,A_SEC,NEXT_TUNE
		CLR		TR1				  ;一分钟到,关闭T1,结束音乐
		MOV	    P1,#0FFH
		AJMP	MAIN
NEXT_TUNE:
		CPL		P1.0
		CPL		P1.1
		CPL		P1.2
		CPL		P1.3
		CPL		P1.4
		AJMP	MUSIC_START		  ;执行下一个编码

;****************************************************
;节拍延时,0.1s的整数倍
MUSIC_DELAY:
		MOV		TH1,HIGH_NUM
		MOV		TL1,LOW_NUM
		MOV		R5,CLAP
DLYM1:	MOV     R4,#16
DLYM2:	ACALL	TIME_DIS
        DJNZ    R4,DLYM2
		DJNZ	R5,DLYM1
        RET
;****************************************************
;延时1ms
DELAY:  MOV     R6,#02H
DELAY1: MOV     R7,#0FFH
        DJNZ    R7,$
        DJNZ    R6,DELAY1
        RET
;****************************************************
TABA:   DB      0C0H,0F9H,0A4H,0B0H,99H
		DB		92H,82H,0F8H,80H,90H  		;不带点数码管编码
TABB:	DB		40H,79H,24H,30H,19H
		DB		12H,02H,78H,00H,10H	  		;带点数码管编码

TUNE_TAB:
DW 64580,64684,64777,64820
DW 64898,64968,65030,64260
DW 64400,64524,65058,63835,64021			;曲调编码

MUSIC_TAB:
DB 02H,82H
DB 16H,32H,54H,02H,52H
DB 0A6H,32H,54H,02H,52H
DB 64H,74H,0B6H,64H
DB 52H,5CH,32H,22H
DB 16H,12H,14H,32H,22H
DB 16H,12H,14H,22H,32H
DB 26H,12H,94H,22H,32H
DB 2CH
DB 32H,52H
DB 36H,22H,14H,54H
DB 0ACH,92H,0A2H
DB 96H,0A2H,96H,82H
DB 3CH,54H
DB 36H,22H,14H,54H
DB 0ACH,92H,0A2H
DB 16H,12H,14H,22H,32H
DB 2CH,02H,82H
DB 16H,32H,56H,12H
DB 0A6H,32H,56H,52H
DB 66H,72H,0B6H,62H
DB 62H,52H,58H,32H,22H
DB 16H,12H,14H,32H,22H
DB 16H,12H,14H,22H,32H
DB 26H,92H,0A4H,12H,22H
DB 1CH
DB 00							   ;“月亮代表我的心”编码


;中断服务程序
;定时器T0
TSERV:  PUSH    PSW
        PUSH    ACC
        MOV     TH0,#4CH
        MOV     TL0,#0
        DJNZ    INT_NUM,RETUNT      ;1s未到,返回
        MOV     INT_NUM,#14H
        MOV     A,#01H
        ADD     A,SEC           ;秒加1
        DA      A
        MOV     SEC,A           ;秒单元转换为BCD码
        CJNE    A,#60H,RETUNT
        MOV     SEC,#00H
        MOV     A,#01H
        ADD     A,MIN           ;分加1
        DA      A
        MOV     MIN,A           ;分单元转换为BCD码
        CJNE    A,#60H,RETUNT
        MOV     MIN,#00H
        MOV     A,#01H
        ADD     A,HOUR           ;时加1
        DA      A
        MOV     HOUR,A           ;时单元转换为BCD码
        CJNE    A,#24H,RETUNT
        MOV     HOUR,#00H
RETUNT: POP     ACC
        POP     PSW
        RETI

;定时器T1
ASERV:  PUSH    PSW
        PUSH    ACC
		MOV		TH1,HIGH_NUM
		MOV		TL1,LOW_NUM			;重装计数值	
		CPL		BUZZER				;频率输出
		POP     ACC
        POP     PSW
        RETI

		END

⌨️ 快捷键说明

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