51单片机汇编学习例程(17)——KeyPad4X4篇[通俗易懂]

51单片机汇编学习例程(17)——KeyPad4X4篇[通俗易懂]​ASM17_KeyPad4X4:矩阵键盘,LCD1602显示按键值。(注意代码显示不全,最下面有Keil源码和Proteus工程)/*********************************************************************************@fileKeyPad.asm*@authorAlex——小白*@versionV1.0*@date2019.9.1*@brie.

大家好,又见面了,我是你们的朋友全栈君。

​ASM17_KeyPad4X4:矩阵键盘,LCD1602显示按键值。

(注意代码显示不全,最下面有Keil源码和Proteus工程)

51单片机汇编学习例程(17)——KeyPad4X4篇[通俗易懂]

仿真视频

/**
******************************************************************************
*   @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汇编设计

51单片机汇编学习例程(17)——KeyPad4X4篇[通俗易懂]

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/144997.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号