汇编指令操作单片机键盘

一.外部中断

代码:

******************************************************************************
* 文件名:外部中断控制数码管加减
* 描  述:
* 作  者:思索与猫
* 日  期:  19/6/27
* 备  注: 
*         
******************************************************************************
ORG 0000H
AJMP MAIN
ORG 0003H					;外部中断0地址
AJMP EXINT0
ORG 0013H					;外部中断1地址
AJMP EXINT1
ORG 0100H
	
DULA BIT P2.6
WELA BIT P2.7
	
DISPLAY:DB  0FFH,03FH,006H,05BH,04FH,066H,06DH,07DH,007H,07FH,06FH
;  注意1~10为0~9
;(防止减到0出现乱码)
	
MAIN:
	MOVE SP,#60H			;指定堆栈段位置(防止程序出错)
	SETB IT0				;外部中断初始化
	SETB IT1
	SETB EX0
	SETB EX1
	SETB EA
	
	MOV R7,#5				;初值显示为4
	MOV DPTR,#DISPLAY
	
	SETB WELA				;位码
	MOV P0,#0FEH
	CLR WELA
	
LOOP:								;循环,查表选择段码
	SETB DULA	
	MOV A,R7
	MOVC A,@A+DPTR
	MOV P0,A
	CLR DULA	
	AJMP LOOP
		
EXINT0:ACALL DELAY10MS			;中断0
	JB P3.2,RE					;消抖
	JNB P3.2,$
	ACALL LOOP1
	AJMP RE
LOOP1:	
	INC R7						;自加到11清1
	CJNE R7,#11,RE		
	MOV R7,#1
	RET
	
EXINT1:ACALL DELAY10MS			;中断1
	JB P3.3,RE					;消抖
	JNB P3.3,$
	ACALL LOOP2
	AJMP RE
LOOP2:	
	DEC R7						;自减到0赋值为10
	CJNE R7,#0,RE
	MOV R7,#10
	RET	
	
RE:RETI	

DELAY10MS:			;@11.0592MHz
	PUSH 30H
	PUSH 31H
	MOV 30H,#18
	MOV 31H,#230
NEXT:
	DJNZ 31H,NEXT
	DJNZ 30H,NEXT
	POP 31H
	POP 30H
	RET
	
END

二.独立按键

代码:

******************************************************************************
* 文件名:独立按键控制数码管和LED
* 描  述:
* 		 按下S1,数码管显示1,LED1亮
* 		 按下S2,数码管显示2,LED2亮
*		 按下S3,数码管显示3,LED3亮
* 		 按下S4,数码管显示4,LED4亮
* 作  者:思索与猫
* 日  期:  19/6/27
* 备  注: 
*         
******************************************************************************
ORG 0000H
AJMP MAIN
ORG 0100H
	
K1 BIT P3.0					;位定义,P3.0~P3.3口为独立键盘
K2 BIT P3.1
K3 BIT P3.2
K4 BIT P3.3
	
DULA BIT P2.6
WELA BIT P2.7

DISPLAY:DB  03FH,006H,05BH,04FH,066H,06DH,07DH,007H,07FH,06FH	
;数码管段码0~9
	
MAIN:
	MOV SP,#60H				;指定堆栈位置(防止程序出错)

	MOV DPTR,#DISPLAY		;位选设置
	SETB WELA
	MOV P0,#0FEH
	CLR WELA
LOOP:
	JNB K1,EVENT1			;扫描键盘K1,K2,K3,K4
	JNB K2,EVENT2
	JNB K3,EVENT3
	JNB K4,EVENT4
	
	SETB DULA				;查表设置段码
	MOV A,R7
	MOVC A,@A+DPTR
	MOV P0,A
	CLR DULA
	AJMP LOOP
	
EVENT1:						;按下按键K1
	ACALL DELAY10MS			;延时10ms
	JB K1,RE				;消抖,再次判断是否按下K1,没有则返回,有则继续
	JNB K1,$				;松开K1后才执行以下程序
	MOV P1,#0FEH			;LED1亮
	MOV R7,#01H				;段码设置1
	AJMP RE					;返回

EVENT2:	
	ACALL DELAY10MS
	JB K2,RE
	JNB K2,$		
	MOV P1,#0FDH
	MOV R7,#02H
	AJMP RE
	
EVENT3:	
	ACALL DELAY10MS
	JB K3,RE
	JNB K3,$
	MOV P1,#0FBH		
	MOV R7,#3
	AJMP RE
	
EVENT4:	
	ACALL DELAY10MS
	JB K4,RE
	JNB K4,$		
	MOV P1,#0F7H
	MOV R7,#4
	AJMP RE
	
RE:RET	

DELAY10MS:			;@11.0592MHz
	PUSH 30H
	PUSH 31H
	MOV 30H,#18
	MOV 31H,#230
NEXT:
	DJNZ 31H,NEXT
	DJNZ 30H,NEXT
	POP 31H
	POP 30H
	RET
END
  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
键盘扫描是单片机应用中的一个常见问题。在汇编语言中,我们可以通过读取键盘的输入来实现键盘扫描。一般来说,键盘扫描是通过轮询的方式实现的,即不断循环读取键盘输入,直到检测到用户按下某个键。 以下是一个简单的键盘扫描程序的汇编代码示例: ``` ORG 0x0000 JMP main ; 键盘扫描函数 ScanKey: MOV P1, #0xFF ; 设置 P1 为输入模式 MOV P2, #0x00 ; 设置 P2 为输出模式 MOV A, #0xFF ; 初始化扫描码,A 存储列扫描码 MOV R0, #0x00 ; R0 存储行扫描码 MOV R1, #0x00 ; R1 存储键值 MOV R2, #0x00 ; R2 用于循环计数 MOV R3, #0x00 ; R3 用于保存扫描结果 ; 循环扫描键盘 Loop: MOV P2, A ; 输出列扫描码 NOP ; 稍作延迟 MOV R3, P1 ; 读取行扫描码 ; 检查是否有键按下 JZ Skip ; 确定键值 MOV R2, #0x01 ; 设置循环计数器 Next: RLC R3 ; 将行扫描码左移一位 JNC Skip2 ; 如果最高位为 0,跳过 INC R1 ; 增加键值 DJNZ R2, Next ; 继续检查剩余的键 Skip2: INC A ; 检查下一列 DJNZ R0, Loop ; 继续扫描下一行 Skip: INC R0 ; 检查下一行 MOV A, R0 ; 更新列扫描码 CJNE R0, #0x04, Loop ; 继续扫描下一行 RET main: CALL ScanKey ; 调用键盘扫描函数 ; 处理键值 ; ... JMP main ; 循环执行 ``` 上述代码中,`ScanKey` 函数使用了轮询的方式扫描键盘。首先,将 `P1` 设置为输入模式,将 `P2` 设置为输出模式,然后在一个双重循环中扫描每个键。内层循环按列扫描键盘,外层循环按行扫描键盘。对于每个键,检查行扫描码,如果最高位为 1,说明该键已被按下,将其对应的键值保存到 `R1` 中。最后,将 `R1` 中的键值返回给主函数进行处理。 需要注意的是,在每个循环中需要稍作延迟,以确保键盘输入稳定。在示例代码中,使用了一个 `NOP` 命令来实现延迟。如果延迟时间不够,可能会导致扫描结果不准确。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值