大家好,又见面了,我是你们的朋友全栈君。
ASM17_KeyPad4X4:矩阵键盘,LCD1602显示按键值。
(注意代码显示不全,最下面有Keil源码和Proteus工程)
/**
******************************************************************************
* @file KeyPad.asm
* @author Alex——小白
* @version V1.0
* @date 2019.9.1
* @brief 4X4矩阵键盘,LCD1602显示按键值
* @store 有家Proteus仿真店子
* @Link https://shop484534014.taobao.com/
* @Email 844545015@qq.com
******************************************************************************
* @attention All Rights Reserved
**/
KeyVal EQU 30H ;按键值
LcdRs EQU P2.0 ;LCD1602引脚定义
LcdRw EQU P2.1
LcdEn EQU P2.2
ORG 0000H ;程序执行的起始地址
LJMP Main ;跳转到main函数
ORG 0100H ;程序跳转到0100H开始执行
Main: ;最简单的按键赋值(8个按键)
MOV KeyVal,#0FFH
LCALL LCD_INIT ;初始化GUI
MOV A,#080H
LCALL LCD_WCMD
While:
LCALL KeyPad
MOV A,KeyVal
CJNE A,#0FFH,NEXT
SJMP While
NEXT:
LCALL LCD_WDAT
MOV KeyVal,#0FFH
SJMP While ;While循环
KeyPad:
MOV P1,#0FFH ;默认高电平
CLR P1.4 ;P14=0,查看第1列是否有按键触发
MOV A,P1 ;A=P1
ANL A,#0FH ;A&0FH与
XRL A,#0FH ;A^0FH异或,判断低4位是否有按键
JZ Col1 ;第1列,否则跳第2列
LCALL Delay ;消抖后,再次检测
MOV A,P1 ;A=P1,再次判断是否有按键触发
ANL A,#0FH ;A&0FH与
XRL A,#0FH ;A^0FH异或
JZ Col1
MOV A,P1
ANL A,#0FH
CJNE A,#0EH,Row1
JNB P1.0,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'1'
Row1:
CJNE A,#0DH,Row2
JNB P1.1,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'4'
LJMP Over
Row2:
CJNE A,#0BH,Row3
JNB P1.2,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'7'
LJMP Over
Row3:
CJNE A,#07H,Col1
JNB P1.3,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'0'
Col1:
MOV P1,#0FFH ;默认高电平
CLR P1.5 ;P15=0,查看第2列是否有按键触发
MOV A,P1 ;A=P1
JZ Col2 ;第2列,否则跳第3列
LCALL Delay ;消抖后,再次检测
MOV A,P1 ;A=P1,再次判断是否有按键触发
ANL A,#0FH ;A&0FH与
XRL A,#0FH ;A^0FH异或
JZ Col2
MOV A,P1
ANL A,#0FH
CJNE A,#0EH,Row4
JNB P1.0,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'2'
Row4:
CJNE A,#0DH,Row5
JNB P1.1,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'5'
Row5:
CJNE A,#0BH,Row6
JNB P1.2,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'8'
Row6:
CJNE A,#07H,Col2
JNB P1.3,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'C'
Col2:
MOV P1,#0FFH ;默认高电平
CLR P1.6 ;P16=0,查看第3列是否有按键触发
MOV A,P1 ;A=P1
ANL A,#0FH ;A&0FH与
XRL A,#0FH ;A^0FH异或
JZ Col3 ;第3列,否则跳第4列
LCALL Delay ;消抖后,再次检测
MOV A,P1 ;A=P1,再次判断是否有按键触发
ANL A,#0FH ;A&0FH与
XRL A,#0FH ;A^0FH异或
JZ Col3
MOV A,P1
ANL A,#0FH
CJNE A,#0EH,Row7
JNB P1.0,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'3'
LJMP Over
Row7:
CJNE A,#0DH,Row8
JNB P1.1,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'6'
LJMP Over
Row8:
CJNE A,#0BH,Row9
JNB P1.2,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'9'
LJMP Over
Row9:
CJNE A,#07H,Col3
JNB P1.3,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'='
LJMP Over
Col3:
MOV P1,#0FFH ;默认高电平
CLR P1.7 ;P16=0,查看第3列是否有按键触发
MOV A,P1 ;A=P1
ANL A,#0FH ;A&0FH与
XRL A,#0FH ;A^0FH异或
JZ Over ;结束
LCALL Delay ;消抖后,再次检测
MOV A,P1 ;A=P1,再次判断是否有按键触发
ANL A,#0FH ;A&0FH与
XRL A,#0FH ;A^0FH异或
JZ Over
MOV A,P1
ANL A,#0FH
CJNE A,#0EH,Row10
JNB P1.0,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'+'
Row10:
CJNE A,#0DH,Row11
JNB P1.1,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'-'
Row11:
CJNE A,#0BH,Row12
JNB P1.2,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'*'
Row12:
CJNE A,#07H,Over
JNB P1.3,$ ;长按检测,若有则一直死循环
MOV KeyVal,#'/'
Over:
RET
LCD_INIT: ;初始化LCD1602
LCALL Delay ;设置8线,5*7等
MOV A,#38H
LCALL LCD_WCMD
LCALL Delay
MOV A,#06H
LCALL LCD_WCMD
LCALL Delay
MOV A,#0CH
LCALL LCD_WCMD
LCALL Delay
MOV A,#01H
LCALL LCD_WCMD
LCALL Delay
MOV A,#80H ;显示初始化数组TABLE_INIT,最下面可随意更改
LCALL LCD_WCMD
MOV R0,#00H
MOV DPTR,#TABLE_INIT
init0: ;显示 " LCD Initial "
MOV A,R0
MOVC A,@A+DPTR
LCALL LCD_WDAT
NOP
INC R0
CJNE R0,#16,init0
MOV A,#0C0H ;显示初始化数组TABLE_KeyPad
LCALL LCD_WCMD
MOV R0,#00H
MOV DPTR,#TABLE_KeyPad
init1: ;显示 " KeyPad "
MOV A,R0
MOVC A,@A+DPTR
LCALL LCD_WDAT
NOP
INC R0
CJNE R0,#16,init1
LCALL Delay1s
LCALL Delay1s
MOV A,#01H ;清屏
LCALL LCD_WCMD
RET
LCD_WCMD: ;LCD1602写指令,具体可见LCD中解释
LCALL LCD_Wait
CLR LcdEn
CLR LcdRs
CLR LcdRw
NOP
SETB LcdEn
NOP
MOV P0,A
NOP
CLR LcdEn
NOP
RET
LCD_WDAT: ;LCD1602写数据
LCALL LCD_Wait
CLR LcdEn
SETB LcdRs
CLR LcdRw
NOP
SETB LcdEn
NOP
MOV P0,A
NOP
CLR LcdEn
RET
Delay: ;t=t1*20=10ms,修改R6的值即可更改时间(不精准)
MOV R6, #20 ;20
D1:
MOV R7, #0FAH ;t1=250*2=500
D2:
DJNZ R7, D2 ;R7=250自减,直到为0跳出循环,双周期
DJNZ R6, D1 ;R6=020自减,直到为0跳出循环,双周期
RET
Delay1s: ;t=t1*10=5ms,修改R6的值即可更改时间(不精准)
MOV R5, #08H ;单周期,8次
D3: ;t1=t2*250=500*250=125000
MOV R6, #0FAH
D4:
MOV R7, #0FAH ;t2=250*2=500
D5:
DJNZ R7, D5 ;R7=250自减,直到为0跳出循环,双周期
DJNZ R6, D4 ;R6=250自减,直到为0跳出循环,双周期
DJNZ R5, D3 ;R5=100自减,直到为0跳出循环,双周期
RET
TABLE_INIT:
DB " LCD Initial "
TABLE_KeyPad:
DB " KeyPad "
END
如需下载Proteus仿真文件和Keil工程,请关注公众号:
Proteus仿真店子
(若需Proteus和keil安装包,后台回复:安装包;若需Proteus教学视频,后台回复:Proteus视频;若需其它设计,后台回复:51汇编设计)
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/144997.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...