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

📄 key_scan.asm

📁 51系列单片机实验课程:时钟程序 (显示时刻时、分、秒)
💻 ASM
字号:
;********************************************************
;*程序功能:在单片机教学实验仪的MCU#3上			*
;*对矩阵按键进行扫描检测,将检测到的键号		*
;*以移位的形式显示在8个数码管上				*
;*							*	
;********************************************************

	ORG 0000H
	JMP	MAIN

;==================================
;RAM区变量定义

	UP_DOWN	BIT	00	;键状态指示,0按下,1弹起
	
	DISBUF	EQU	30H	;显示参数传递
	POSIT	EQU	38H	;位选
	KEYBUF	EQU	39H	;键码暂存
	KEYTEMP	EQU	40H	;暂存待确定的扫描码

;===================================
;主函数
	ORG	0030H
MAIN:
	SETB	UP_DOWN		;初始设置为弹起态
	MOV	DISBUF,#01H	;在第1个数码管上显示  1
	MOV	DISBUF+1,#02H	;在第2个数码管上显示  2
	MOV	DISBUF+2,#03H	;在第3个数码管上显示  3
	MOV	DISBUF+3,#04H	;在第4个数码管上显示  4
	MOV	DISBUF+4,#05H	;在第5个数码管上显示  5
	MOV	DISBUF+5,#06H	;在第6个数码管上显示  6
	MOV	DISBUF+6,#07H	;在第7个数码管上显示  7
	MOV	DISBUF+7,#08H	;在第8个数码管上显示  8
LOOP:	
	CALL	KEY		;查键
	CALL	DISPLAY		;显示
	JMP	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端口,单此时并未送至数码管
	CALL	SEGLOCK		;锁存数码管的段码
	MOV	P0,POSIT	;送位选至P0,以便指示哪一个数码管亮
	CALL	BITLOCK		;锁存数码管的位选信号
	CALL	DELAY		;使相应数码管亮一段时间
	MOV	P0,#00H		;送位选为00至P0口,即关闭所有的数码管,一产生消隐作用,避免数码管上产生重影现象
	CALL	BITLOCK		;锁存消隐信号
	MOV	A,POSIT		;当一个数码管完成显示后,对位选进行移位操作,以便为下一个数码管
	RR	A		;的显示作好准备,此时,位选指向下一个数码管
	MOV	POSIT,A
	INC	R0		;使R0的数自加一,指向下一个要显示的数字,若上一次指向DISBUF,则
	DJNZ	R1,DISLOOP	;本次指向DISBUF+1,并受R1控制,完成8个数在数码管上的显示
	RET			;所以,在使用此显示程序时,只需将欲显示的数字放入对应的DISBUF即可

;=============================
;数码管移位
POSI_CH:
	MOV	R0,#DISBUF
	MOV	R1,#DISBUF+1		;将DISBUF中的数,从高位到低位
UU:					;依次覆盖
	MOV	A,@R1			;然后将得到的最新键植
	MOV	@R0,A			;装入DISBUF+7
	INC	R0
	INC	R1
	CJNE	R0,#POSIT,UU
	MOV	R1,#POSIT-1
	MOV	A,R7
	MOV	@R1,A
	RET

;===================================
;延时程序
DELAY:
	MOV	R3,#0FH
LOOP1:	DJNZ	R3,LOOP1	
	NOP
	RET

;===================================
;锁存数码管段码
SEGLOCK:
	SETB	P1.3
	NOP
	CLR	P1.3
	RET

;===================================
;锁存数码管位选
BITLOCK:
	SETB	P1.2
	NOP
	CLR	P1.2
	RET

;===================================
;按键检测
KEY_SCAN:
	MOV	P2,#0FH			;列扫描
	MOV	KEYBUF,P2
	MOV	P2,#0F0H		;行扫描
	MOV	A,P2
	ORL	A,KEYBUF		;将最新的扫描码放在A中
	RET

;===================================
;判断按键状态
KEY:
	JB	UP_DOWN,KEY_DOWN_CHECH	;检测当前按键的状态,若为弹起状态,则检测键按下
	JMP	KEY_UP_CHECH		;若为按下状态,则检测键弹起
KEY_DOWN_CHECH:
	CALL	KEY_SCAN
	CJNE	A,#0FFH,KEY_CHECH	;有键按下否?
	JMP	KEY_END			;没有,返回主函数
KEY_CHECH:
	CALL	KEY_SCAN
	MOV	KEYTEMP,A		;存放最新的扫描码以被确认
	CALL	DELAY_KEY		;有,延时去抖
	CALL	KEY_SCAN		;重新检测键状态
	CJNE	A,KEYTEMP,KEY_END	;如和上次扫描的一样,说明确实有键按下
	CALL	KEY_SERCH
	CALL	POSI_CH
	CLR	UP_DOWN			;只对键号码表进行16次比对,找不到
	JMP	KEY_END			;也要终止比较
KEY_UP_CHECH:				;按键弹起检测
	CALL	KEY_SCAN
	CJNE	A,#0FFH,KEY_END
	SETB	UP_DOWN			;给出当前按键状态
KEY_END:
	RET

;===================================
;按键去抖延时
DELAY_KEY:
	MOV	R3,#0FH
L1:	MOV	R7,#0FFH
L2:	DJNZ	R7,L2
	DJNZ	R3,L1
	RET
	
;===================================
;键号查询
KEY_SERCH:
	CJNE	A,#0DEH,KEY1		;0键查询
	JMP	KEY0_SR
KEY1:
	CJNE	A,#0E7H,KEY2		;1键查询
	JMP	KEY1_SR
KEY2:
	CJNE	A,#0D7H,KEY3		;2键查询
	JMP	KEY2_SR
KEY3:
	CJNE	A,#0B7H,KEY4		;3键查询
	JMP	KEY3_SR
KEY4:
	CJNE	A,#0EBH,KEY5		;4键查询
	JMP	KEY4_SR
KEY5:
	CJNE	A,#0DBH,KEY6		;5键查询
	JMP	KEY5_SR
KEY6:
	CJNE	A,#0BBH,KEY7		;6键查询
	JMP	KEY6_SR
KEY7:
	CJNE	A,#0EDH,KEY8		;7键查询
	JMP	KEY7_SR
KEY8:
	CJNE	A,#0DDH,KEY9		;8键查询
	JMP	KEY8_SR
KEY9:
	CJNE	A,#0BDH,KEYA		;9键查询
	JMP	KEY9_SR
KEYA:
	CJNE	A,#077H,KEYB		;A键查询
	JMP	KEYA_SR
KEYB:
	CJNE	A,#07BH,KEYC		;B键查询
	JMP	KEYB_SR
KEYC:
	CJNE	A,#07DH,KEYD		;C键查询
	JMP	KEYC_SR
KEYD:
	CJNE	A,#07EH,KEYE		;D键查询
	JMP	KEYD_SR
KEYE:
	CJNE	A,#0EEH,KEYF		;E键查询
	JMP	KEYE_SR
KEYF:
	CJNE	A,#0BEH,KEY_SER_END	;F键查询
	JMP	KEYF_SR

KEY0_SR:MOV	R7,#0			;译码,将码值存放在R7中
	JMP	KEY_SER_END
KEY1_SR:MOV	R7,#1
	JMP	KEY_SER_END
KEY2_SR:MOV	R7,#2
	JMP	KEY_SER_END
KEY3_SR:MOV	R7,#3
	JMP	KEY_SER_END
KEY4_SR:MOV	R7,#4
	JMP	KEY_SER_END
KEY5_SR:MOV	R7,#5
	JMP	KEY_SER_END
KEY6_SR:MOV	R7,#6
	JMP	KEY_SER_END
KEY7_SR:MOV	R7,#7
	JMP	KEY_SER_END
KEY8_SR:MOV	R7,#8
	JMP	KEY_SER_END
KEY9_SR:MOV	R7,#9
	JMP	KEY_SER_END
KEYA_SR:MOV	R7,#0AH
	JMP	KEY_SER_END
KEYB_SR:MOV	R7,#0BH
	JMP	KEY_SER_END
KEYC_SR:MOV	R7,#0CH
	JMP	KEY_SER_END
KEYD_SR:MOV	R7,#0DH
	JMP	KEY_SER_END
KEYE_SR:MOV	R7,#0EH
	JMP	KEY_SER_END
KEYF_SR:MOV	R7,#0FH
	JMP	KEY_SER_END

KEY_SER_END:
	RET
	
;===================================
;共阳数码管码表
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   -    消隐  _

;===================================
;扫描键码		
KEYCODE:  
	DB	0DEH,0E7H,0D7H,0B7H,0EBH,0DBH,0BBH
	   ;     0     1     2   3    4     5   6   
	DB	0EDH,0DDH,0BDH,77H,7BH,07DH,07EH,0EEH,0BEH	
	   ;     7     8    9    A   B   C   D     *    #   
  
	END 

⌨️ 快捷键说明

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