首页 > 其他分享 >04 - 矩阵键盘

04 - 矩阵键盘

时间:2023-12-14 17:35:47浏览次数:32  
标签:Delay P1 20 04 矩阵 chKeyNum 键盘 while 按键

04 - 矩阵键盘

前言

LCD1602液晶屏

在学习使用矩阵键盘之前,为了后续的调试和显示,有必要简单了解一下LCD1602液晶屏的使用方法。江协科技已经给我们提供了模块化的代码,所以我们只需要调用对应方法就可以了,常用方法如下:

至于LCD1602具体如何操作使用,后续会有,暂时就先放一边

扫描的概念

扫描的作用:节省I/O

  • 数码管的扫描(输出扫描)

    原理:显示第1位——>显示第2位——>显示第3位——>...,然后快速循环这个过程,最终实现所有数码管同时显示的效果

  • 矩阵键盘的扫描(输入扫描)

    原理:读取第1行(列)——>读取第2行(列)——>读取第3行(列)——>...,然后快速循环这个过程,最终实现所有按键同时检测的效果

矩阵键盘

  • 在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式

  • 采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态

注意:看江协科技视频,提到由于其开发板内部的电路连接问题,如果采用逐行扫描的话,P15端口的电平时高时低,而且蜂鸣器会一直响,无法关闭。所以为了避免这个问题,采用逐列扫描(但是我使用的开发板和其不一样,于是试了试逐行扫描,蜂鸣器并没有响。具体差异学完后面再回来看看)

一、读取矩阵键盘的键码值

#include <REGX52.H>
#include "LCD1602.H"

void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;

    while(xms)
    {
        i = 2;
        j = 239;
        do
        {
            while (--j);
        } while (--i);
        xms--;
    }
}


/**
  * @brief  矩阵键盘读取按键键码(逐列)
  * @param  无
  * @retval chKeyNum 按下按键的键码值
  *         如果按键按下不放,程序会停留在此函数,松手返回按键键码。若没有按键按下,返回0
  */
unsigned char MatrixKey()
{
    unsigned char chKeyNum = 0;
    
    P1 = 0xFF;
    P1_3 = 0;
    if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=1;}
    if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=5;}
    if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=9;}
    if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=13;}
    
    P1 = 0xFF;
    P1_2 = 0;
    if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=2;}
    if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=6;}
    if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=10;}
    if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=14;}
    
    P1 = 0xFF;
    P1_1 = 0;
    if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=3;}
    if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=7;}
    if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=11;}
    if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=15;}
    
    P1 = 0xFF;
    P1_0 = 0;
    if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=4;}
    if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=8;}
    if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=12;}
    if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=16;}
    
    return chKeyNum;
}


/**
  * @brief  矩阵键盘读取按键键码(逐行)
  * @param  无
  * @retval chKeyNum 按下按键的键码值
  *         如果按键按下不放,程序会停留在此函数,松手返回按键键码。若没有按键按下,返回0
  */
unsigned char MatrixKey_2()
{
    unsigned char chKeyNum = 0;
    
    P1 = 0xFF;
    P1_7 = 0;
    if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);chKeyNum=1;}
    if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);chKeyNum=2;}
    if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);chKeyNum=3;}
    if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);chKeyNum=4;}
    
    P1 = 0xFF;
    P1_6 = 0;
    if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);chKeyNum=5;}
    if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);chKeyNum=6;}
    if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);chKeyNum=7;}
    if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);chKeyNum=8;}
    
    P1 = 0xFF;
    P1_5 = 0;
    if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);chKeyNum=9;}
    if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);chKeyNum=10;}
    if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);chKeyNum=11;}
    if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);chKeyNum=12;}
    
    P1 = 0xFF;
    P1_4 = 0;
    if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);chKeyNum=13;}
    if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);chKeyNum=14;}
    if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);chKeyNum=15;}
    if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);chKeyNum=16;}
    
    return chKeyNum;
}

void main()
{   
    unsigned char chKeyNum = 0;
    LCD_Init();
    LCD_ShowString(1, 1, "MatrixKey: ");
    while(1)
    {
        chKeyNum = MatrixKey();
        if(chKeyNum)
        {
            LCD_ShowNum(2, 1, chKeyNum, 2);
        }  
    }
}

二、矩阵键盘密码锁

#include <REGX52.H>
#include "LCD1602.H"

void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;

    while(xms)
    {
        i = 2;
        j = 239;
        do
        {
            while (--j);
        } while (--i);
        xms--;
    }
}


/**
  * @brief  矩阵键盘读取按键键码(逐列)
  * @param  无
  * @retval chKeyNum 按下按键的键码值
  *         如果按键按下不放,程序会停留在此函数,松手返回按键键码。若没有按键按下,返回0
  */
unsigned char MatrixKey()
{
    unsigned char chKeyNum = 0;
    
    P1 = 0xFF;
    P1_3 = 0;
    if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=1;}
    if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=5;}
    if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=9;}
    if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=13;}
    
    P1 = 0xFF;
    P1_2 = 0;
    if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=2;}
    if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=6;}
    if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=10;}
    if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=14;}
    
    P1 = 0xFF;
    P1_1 = 0;
    if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=3;}
    if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=7;}
    if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=11;}
    if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=15;}
    
    P1 = 0xFF;
    P1_0 = 0;
    if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);chKeyNum=4;}
    if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);chKeyNum=8;}
    if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);chKeyNum=12;}
    if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);chKeyNum=16;}
    
    return chKeyNum;
}

void main()
{   
    unsigned char chKeyNum = 0;
    unsigned int nPassword = 0;
    unsigned int nCnt = 0;
    
    LCD_Init();
    LCD_ShowString(1, 1, "Password: ");
    while(1)
    {
        chKeyNum = MatrixKey();
        if(chKeyNum > 0 && chKeyNum < 11)   // 密码输入
        {
            if(nCnt < 4)
            {
                nPassword *= 10;
                nPassword += chKeyNum;
                LCD_ShowNum(2, 1, nPassword, 4);
            }
            
            nCnt++;
        }
        else if(chKeyNum == 11)             // 清零键
        {
            nCnt = 0;
            nPassword = 0;
            LCD_ShowNum(2, 1, nPassword, 4);
        }
        else if(chKeyNum == 12)             // 确定键
        {
            if(nPassword == 1234)
            {
                LCD_ShowString(1, 14, "OK ");
            }
            else
            {
                LCD_ShowString(1, 14, "ERR");
            }
            
            nCnt = 0;
            nPassword = 0;
            LCD_ShowNum(2, 1, nPassword, 4);
        }
    }
}

标签:Delay,P1,20,04,矩阵,chKeyNum,键盘,while,按键
From: https://www.cnblogs.com/yljblogs/p/17901632.html

相关文章

  • 04_ARM硬件基础
    04_ARM硬件基础课程目标:了解我们常用硬件接口,并且编程控制重点难点:对各个接口原理的掌握考核目标:各个接口的作用,实现原理及特性1.硬件基础概述1.1.为什么我们要去研究硬件因为要去使用他,驱动它1.2.我们要研究什么硬件原理及构造地址寄存器协议时长/频率1.3.......
  • 04_uboot全面讲解
    04_uboot全面讲解本课程希望达到目标理解底层代码的编写方式u-boot版本选择uboot官方源码地址https://ftp.denx.de/pub/u-boot/Uboot版本一直在迭代,加入的东西也越来越多,所以我们学习,只要选择适合的版本就可以了这里我们先选择下载2010.12版本的解压下来之后,进入\arch\a......
  • 59. 螺旋矩阵 II
    题目:59.螺旋矩阵II要求:给你一个正整数n,生成一个包含1到n2所有元素,且元素按顺时针顺序螺旋排列的nxn正方形矩阵matrix。答案:两种解法:一种用计算机模拟顺时针旋转的效果,这种方法看起来容易,做起来并没有那么容易,我开始就用这个思路做的,结果发现写不出来,看了下题......
  • 华擎全球首发AMD锐龙8040产品:迷你机、迷你小板齐上阵
    AMD日前官宣了代号HawkPoint的新一代锐龙8040系列移动处理器,是现有锐龙7040系列的升级版,工艺、架构不变,重点提升NPUAI性能,并调整了功耗设定。现在,华擎全球第一家发布了基于锐龙8040系列的产品,确切地说是低功耗的锐龙8040U系列,包括迷你机、迷你主板。迷你机有两款,型号分别为4X......
  • springboot004旅游路线规划系统(Java毕业设计,附数据库和源码)
    第一章绪论1.1选题背景与研究意义随着社会的不断进步,在居民生活水平提高的同时,人们当前在生活的方方面面也越来越注重服务所带来的体验,随着近几年国家政策大力发展旅游业,旅游景点的建设越来也完善,旅游业的发展速度得到了显著的提升。各大旅行社、旅游景点都不断的推出新的活动计......
  • P1004 [NOIP2000 提高组] 方格取数 题解
    P1004[NOIP2000提高组]方格取数题解题目链接P1004[NOIP2000提高组]方格取数简要思路注意一下输入可以简化为while(std::cin>>x>>y>>val&&x){ //***}运用DP的思想。用一个四维的\(DP\)数组\(dp[i][j][k][l]\)来同时记录两条路径分别走到\((i,j)\)和\((k,......
  • 代码随想录算法训练营第一天|704.二分查找、27.移除元素
    LeetCode704二分查找题目链接704.二分查找二分法确定区间(循环不变量):对于有序数组,定义循环区间二分查找元素 LeetCode27.移除元素题目链接:27.移除元素快慢指针,快指针查,慢指针存 ......
  • 代码随想录算法训练营第一天 | 数组理论基础,704. 二分查找,27. 移除元素
    一、数组理论基础学习前:1.数组定义一些在内存上连续存储的相同数据类型的数据的集合2.数组特征便于查询数组元素,不便于增删数据元素学习后:对于Java,二维数组不一定在内存上连续。如int[i][j],唯一确定的是int[i][]在内存上连续二、704.二分查找LeetCode704.二分查找......
  • 代码随想录算法训练营第一天| LeetCode704 二分查找、27移除元素
     Leetcode704:二分查找今日学习的文章链接:代码随想录(programmercarl.com) 题目链接:704.二分查找-力扣(LeetCode)●  自己看到题目的第一想法这题我会,但是还没明白卡尔说的循环不变量是什么意思。我的固定思路就是,target比中间值大,左指针右移到mid+1;target比中间值......
  • ubuntu 18.04.6 编译文件系统buildroot的时候提示 buildroot/output/host/ARM-buildro
    错误提示如下:ln::无法创建符号链接buildroot/output/host/ARM-buildroot-linux-gnueabihf/sysroot/usr/lib没有文件或目录  cd进入buildroot路径,先sudomakeclean 然后再cd..到software文件夹重新make就可以了。  ......