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

📄 clock24.asm

📁 51系列单片机实验课程:时钟程序 (显示时刻时、分、秒)
💻 ASM
字号:
;*****************************************
;程序功能:在MCU#3中的数码管上显示一个时钟
;程序是用中断方式来处理的,也可以自己改写为查询方式
;*****************************************
	ORG	0000H
	AJMP	START
;=============================================
;中断入口
	ORG	000BH
	AJMP	T0INT
;=============================================
;RAM区变量定义
	DISBUF	EQU	30H	;显示参数传递
	POSIT	EQU	38H	;位选
	NUM	EQU	40H	;秒循环次数
	SEC	EQU	50H	;秒
	MIN	EQU	51H	;分钟
	HOR	EQU	52H	;小时
;=============================================
;程序开始部分(主函数)
	ORG	0100H
START:
	MOV	SP, #60H	;设置堆栈指针位置
	MOV	TMOD, #01H	;设置定时器T0的工作方式为定时器模式,方式一
	MOV	TH0, #42H	;给定时器赋初值
	MOV	TL0, #0A0H
	MOV	DISBUF+2, #16	;给显示部分赋值"-"
	MOV	DISBUF+5, #16
	MOV	SEC, #0		;设置秒的初值
	MOV	MIN, #59	;设置分钟的初值
	MOV	HOR, #23	;设置小时的初值
	MOV	NUM, #19	;设置定时器循环的次数,也就是确定循环多少次为一秒
	SETB	TR0		;启动定时计数器T0
	SETB	ET0		;开启定时计数器T0的中断	
	SETB	EA		;开启单片机的总中断
LOOP:	LCALL	CHANGE		;调用小时,分秒处理子程序
	LCALL	DISPLAY		;调用显示程序
	AJMP	LOOP

	
;=============================================
;8路数码管驱动
DISPLAY:
	MOV	POSIT, #80H	;用于指示数码管位选,初始化为第一个数码管亮
	MOV	R1, #08H	;用于指示程序循环,8个数码管每个送一次数后,本子程序结束
	MOV	DPTR, #DISCODE	;指向数码管的码表
	MOV	R0, #DISBUF	;指向显示数组
DISLOOP:			;为方便起见,只将第一个数码管的执行过程讲明,其余依次类推
	MOV	A, @R0		;当R0=#DISBUF时,通过间接寻址将DISBUF中的内容放入A中
	MOVC	A, @A+DPTR	;通过查表,A为地址偏移量,找出A中的数所对应的码值(即段码),还放在A中
	MOV	P0, A		;将A中的数送至P0端口,单此时并未送至数码管
	SETB	P1.3		;使能573锁存器,此时,段码才送至数码管的段选端
	CLR	P1.3		;关闭573锁存器,此时,数据锁存在数码管的段选端
	MOV	P0, POSIT	;送位选至P0,以便指示哪一个数码管亮
	SETB	P1.2		;使能573锁存器,此时,位选信号才送至数码管的位选端,相应的数码管亮
	CLR	P1.2		;关闭573锁存器,此时,数据锁存在数码管的位选端
	CALL	DELAY		;使相应数码管亮一段时间
	MOV	P0, #00H	;送位选为00至P0口,即关闭所有的数码管,一产生消隐作用,避免数码管上产生重影现象
	SETB	P1.2
	CLR	P1.2
	MOV	A, POSIT	;当一个数码管完成显示后,对位选进行移位操作,以便为下一个数码管
	RR	A		;的显示作好准备,此时,位选指向下一个数码管
	MOV	POSIT, A
	INC	R0		;使R0的数自加一,指向下一个要显示的数字,若上一次指向DISBUF,则
	DJNZ	R1, DISLOOP	;本次指向DISBUF+1,并受R1控制,完成8个数在数码管上的显示
	RET			;所以,在使用此显示程序时,只需将欲显示的数字放入对应的DISBUF即可
;================================================
;延时程序
DELAY:
	MOV	R3, #0FH
	DJNZ	R3, $	
	RET
;================================================
;显存更新程序
CHANGE:
	PUSH	ACC		;保护现场,将累加器A入栈
	MOV	A, SEC		;将秒变量分十位和个位,分别存放在两个显存空间中
	MOV	B, #10
	DIV	AB
	MOV	DISBUF+6, A
	MOV	DISBUF+7, B
	
	MOV	A, MIN		;将分变量分十位和个位,分别存放在两个显存空间中
	MOV	B, #10
	DIV	AB
	MOV	DISBUF+3, A
	MOV	DISBUF+4, B
	
	MOV	A, HOR		;将小时变量分十位和个位,分别存放在两个显存空间中
	MOV	B, #10
	DIV	AB
	MOV	DISBUF, A
	MOV	DISBUF+1, B
	POP	ACC		;释放累加器A
	RET
;================================================
;定时器T0中断服务程序
T0INT:
	PUSH	ACC		;保护现场,将累加器A入栈
	MOV	TL0, #0A0H	;重新赋初值
	MOV	TH0, #42H
	DJNZ	NUM, OUT	;判断1秒时间是否到达
	MOV	NUM, #19
	INC	SEC		;如果1秒时间到达,对秒加一
	MOV	A, SEC
	CJNE	A, #60, OUT	;判断秒是否超过60
	MOV	SEC, #0		;如果超过60,将秒变量清零,同时将分变量加一
	INC	MIN
	MOV	A, MIN
	CJNE	A, #60, OUT	;判断分变量是否超过60
	MOV	MIN, #0		;如果超过60,将分变量清零,同时将小时变量加一
	INC	HOR
	MOV	A, HOR
	CJNE	A, #24, OUT	;判断小时变量是否超过23
	MOV	HOR, #0		;超过23,对小时变量清零
OUT:
	POP	ACC		;释放累加器A
	RETI
;================================================
;共阳数码管码表
DISCODE:  
	DB 	0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
	  ;	  0   1     2    3   4   5   6    7   8   9
	DB	88H,83H,0C6H,0A1H,86H,08EH,0BFH,0FFH,0F7H
          ;	 A   B    C   D    E    F   -   消隐  _
;================================================
	END

⌨️ 快捷键说明

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