51之矩阵键盘

目录

1.矩阵键盘简介

2.获取矩阵键盘键码值

3.矩阵键盘实现密码锁


1.矩阵键盘简介

        矩阵键盘就是一个基于独立按键的Plus版本,它的原理图就是下面这样:

        和独立按键就像表兄弟一样,为什么这么说呢?因为这个矩阵键盘上可以找到很多独立按键的影子,比如这个独立按键的原理图:

        就是一端接地了,其他的没有什么区别,我们使用这个矩阵键盘可以参照我们的独立按键的使用。

        矩阵键盘的使用又有点我们的数码管显示的感觉,就是数码管使用循环显示各个数位上的数字,使这个间隔无限短以至于我们的数字可以在同一时间显示,我们的这个矩阵键盘也是差不多的,就是使用循环扫描行/列,然后在另外一边判断按键按下情况,从而推断出到底是哪个按键按下,这样我们的接口就从4x4变成了4+4,大大减少了IO口的占用。

        循环是怎么循环的呢?我们在使用独立按键的时候是相当于一排独立按键,我们把它们的一端都连接起来并接地,然后再在另外一边设置IO口,然后我们通过判断IO口来判断具体是哪个按键按下;这里矩阵键盘也是类似的,我们想要使用第一行的某个按键,我们就把第一行它们的共同连接”模拟接地“,就是设置为0,然后再在另外一边列的四个IO口判断哪个按键按下,如果还要判断你整个键盘不知道哪个按键的话,我们只需要循环把每一行的IO口置为0,然后判断,只要我们的循环速度足够快,我们就可以检测到任意位置的按键按下情况,我们的电脑键盘也是基于这样的底层原理,只是加了很多复杂的优化。

2.获取矩阵键盘键码值

        矩阵键盘一共有16个键盘按键,从s1到s16,我们使用循环读取来获得每个按键的键码值。和独立按键一样的是,我们还需要要使用消抖操作来防止出错,使用循环确保按键留在函数内部,只是多了循环和读取并返回键码值的过程。

        由于引脚有限,我们的共用IO口的情况是存在的,所以我们循环把行(P14到P17)置为0就会间接导致我们的蜂鸣器响,所以我们最好使用列的扫描来实现按键检测。

        这里就是函数的实现:

int Key()
{P1 = 0xff;P1_3 = 0;if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);return 1;}if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);return 5;}if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);return 9;}if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);return 13;}P1 = 0xff;P1_2 = 0;if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);return 2;}if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);return 6;}if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);return 10;}if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);return 14;}P1 = 0xff;P1_1 = 0;if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);return 3;}if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);return 7;}if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);return 11;}if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);return 15;}P1 = 0xff;P1_0 = 0;if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);return 4;}if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);return 8;}if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);return 12;}if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);return 16;}return 0;
}

        这里主要思路就是先把所有位置为高电平1,然后循环把列置为0,再判断每行获取按键的坐标,然后把按键值返回。这样就获取了按键键码。

        我们再使用前面使用的矩阵键盘的代码用来调试我们的获取键码值的代码:

#include "LCD1602.h"
#include "MatrixKey.h"void main()
{int num = 0;while(1){num = Key();if(num){LCD_Init();LCD_ShowNum(1,1,num,2);}}
}

        这样我们就可以实现这个键码值的获取和显示了,有一点要注意的是,这里的if(num)判断条件是不能去掉的,因为我们如果没有这个条件的话,函数的返回值就默认是0,就算我们按下了按键,我们的显示屏可能那一刻显示出了对应键码值,但是一瞬间又会被这个键码值0刷新,所以我们需要加上这个判断条件来确保我们的显示稳定可靠。

3.矩阵键盘实现密码锁

        我们可以用一个小项目增加我们对矩阵键盘的理解:使用矩阵键盘1到9代表数字1到9,按键10代表数字0,按键11和按键12分别代表确认和删除,按键13代表清零,其他的按键就不作处理,并且按下无效。

        这样我们就可以开始我们的思路:

        我们想要制作一个密码锁,最重要的就是用户输入,我们可以使用四位输入,获取一个最大位4位的数,然后判断我们的输入是不是和这个密码一样,如果一样就输出True否则输出ERR。但是,这个是我的老师——UP江协科技教我的

        我需要一个更为接近真实的密码输入,所以我决定采用六位密码,并且不打算使用一个长的数来得到我的输入,我想要使用一个一个的数值填入一个字符串数组,这样我们就可以在我们原本的代码上更改,可以实现更复杂更长的密码,不会受到限制。原版的老师教的输入是从最后一位像是一点点插入进输出框的,这里我也要做一点更改,就把初始界面设置为******,然后我们输入一个数字就会填充并取代一个*,还可以使用键11确认并核验密码,键12删除最后一位的值,用键13把所有输入清零。

#include "LCD1602.h"
#include "MatrixKey.h"
#include <stdio.h>
#include <string.h>
void Delay(unsigned int xms);void MyLock()
{int count = 0;int GetNum = 0;char Input[7] = "******";char PassWord[7]="123456";LCD_ShowString(1,1,Input);while(1){LCD_ShowString(1,1,"PassWord:");LCD_ShowString(1,10,Input);Delay(1);//ÔöÇ¿ÏÔʾGetNum =Key();//»ñÈ¡¼üÖµif(GetNum && GetNum<=10){GetNum%=10;if(count<6){sprintf(Input+count,"%d",GetNum);//дÈëLCD_ShowString(1,10,Input);count++;}else//³¬³ö·¶Î§{LCD_ShowString(2,12,"     ");//Çå¿Õ״̬À¸LCD_ShowString(2,12,"FULL");//״̬À¸}}else if(GetNum==11)//È·Èϼü{if(strcmp(Input,PassWord) == 0)//Input == PassWord{LCD_ShowString(2,12,"     ");//Çå¿Õ״̬À¸LCD_ShowString(2,12,"RIGHT");//״̬À¸}else{LCD_ShowString(2,12,"     ");//Çå¿Õ״̬À¸LCD_ShowString(2,12,"ERROR");//״̬À¸}}else if(GetNum == 12)//ɾ³ý¼ü{if(count)//È·±£ÓÐÊý×Ö{count--;Input[count]='*';LCD_ShowString(2,12,"     ");//Çå¿Õ״̬À¸}}else if(GetNum == 13)//ÇåÁã¼ü{strcpy(Input,"******");count = 0;}}
}void main()
{LCD_Init();while(1){MyLock();}
}

这里有几个比较重要的点:

  • 我们的头文件引用最好在c文件中,而且这个自定义的头文件只能使用一次,不然会显示函数未定义的报错。假设我们定义了A.h,而这个头文件里又包含了别的头文件,但是我们使用A.c或者B.c或者B.h都是不能使用A.h里包含的头文件的
  • 还有就是上一节讲到的函数在多个c文件中使用的话,我们无法通过包含头文件多次声明这个函数,但是我可以直接在需要使用的c文件中直接声明这个函数,实现多个c文件调用同一个函数的情况(一般来说我们的防止重复包含的头文件预处理是针对头文件中的一些定义而不是声明,预处理防的是多次定义同一个东西)
  • 然后就是使用LCD1602函数之前要初始化,否则不会有显示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/298551.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java——文件上传

一、文件上传——简介 文件上传的简介&#xff1a;文件上传是指将本地计算机中的文件传输到网络上的服务器或另一台计算机上的过程。在 Web 开发中&#xff0c;文件上传通常指的是将用户通过 Web 页面提交的文件&#xff08;如图像、文档、音频、视频等&#xff09;传输到服务器…

大数据实验统计-1、Hadoop安装及使用;2、HDFS编程实践;3、HBase编程实践;4、MapReduce编程实践

大数据实验统计 1、Hadoop安装及使用&#xff1b; 一&#xff0e;实验内容 Hadoop安装使用&#xff1a; 1&#xff09;在PC机上以伪分布式模式安装Hadoop&#xff1b; 2&#xff09;访问Web界面查看Hadoop信息。 二&#xff0e;实验目的 1、熟悉Hadoop的安装流程。 2、…

【Rust】生命周期

Rust 生命周期机制是与所有权机制同等重要的资源管理机制。 之所以引入这个概念主要是应对复杂类型系统中资源管理的问题。 引用是对待复杂类型时必不可少的机制&#xff0c;毕竟复杂类型的数据不能被处理器轻易地复制和计算。 但引用往往导致极其复杂的资源管理问题&#x…

归并排序解读

在算法领域中&#xff0c;排序算法一直是一个核心话题。归并排序&#xff08;Merge Sort&#xff09;作为一种典型的分治思想应用&#xff0c;以其稳定、高效的特点受到了广泛的关注和应用。本文将深入探讨归并排序的原理、实现方式&#xff0c;以及它在实际应用中的价值。 一…

KeyguardClockSwitch的父类

KeyguardClockSwitch 定义在KeyguardStatusView中, mClockView findViewById(R.id.keyguard_clock_container);KeyguardClockSwitch的父类为&#xff1a; Class Name: LinearLayout Class Name: KeyguardStatusView Class Name: NotificationPanelView Class Name: Notificat…

如何在iPhone上恢复永久删除的照片?

2007 年&#xff0c;Apple Inc. 推出了这款震撼人心的智能手机&#xff0c;后来被称为 iPhone。您会惊讶地发现&#xff0c;迄今为止&#xff0c;Apple Inc. 已售罄 7 亿台 iPhone 设备。根据 2023 年 8 月的一项调查数据&#xff0c;95% 的智能手机利润都落入了苹果公司的口袋…

关系型数据库与非关系型数据库、Redis数据库

相比于其他的内存/缓存数据库&#xff0c;redis可以方便的实现持久化的功能&#xff08;保存至磁盘中&#xff09; 一、关系数据库与非关系型数据库 1.1 关系型数据库 一个结构化的数据库&#xff0c;创建在关系模型基础上一般面向于记录 SQL语句 (标准数据查询语言) 就是一种…

【攻防世界】ics-05

php://filter 伪协议查看源码 preg_replace 函数漏洞 1.获取网页源代码。多点点界面&#xff0c;发现点云平台设备维护中心时&#xff0c;页面发生变化。 /?pageindex 输入什么显示什么&#xff0c;有回显。 用php://filter读取网页源代码 ?pagephp://filter/readconvert.…

MPLS-基础、LSR、LSP、标签、体系结构

MPLS技术 MPLS基础 MPLS&#xff1a;转发数据时&#xff0c;只在网络边缘分析IP报文头&#xff0c;不在每一跳都分析&#xff0c;节约了转发时间。 MPLS&#xff1a;Multiprotocol Label Switching&#xff0c;多协议标签交换骨干网技术。主要应用&#xff1a;VPN、流量工程…

【数据库】MySQL InnoDB存储引擎详解 - 读书笔记

MySQL InnoDB存储引擎详解 - 读书笔记 InnoDB 存储引擎概述InnoDB 存储引擎的版本InnoDB 体系架构内存缓冲池LRU List、Free List 和 Flush List重做日志缓冲&#xff08;redo log buffer&#xff09;额外的内存池 存储结构表空间系统表空间独立表空间通用表空间undo表空间临时…

PyQt qrc2py 使用PowerShell将qrc文件转为py文件并且将导入模块PyQt或PySide转换为qtpy模块开箱即用

前言 由于需要使用不同的qt环境&#xff08;PySide&#xff0c;PyQt&#xff09;所以写了这个脚本&#xff0c;使用找到的随便一个rcc命令去转换qrc文件&#xff0c;然后将导入模块换成qtpy这个通用库(支持pyside2-6&#xff0c;pyqt5-6)&#xff0c;老版本的是Qt.py(支持pysi…

Scaling Law解析

文章目录 scaling law一个token的计算量幂律关系幂律规律实际指导 scaling law 幂律法则&#xff1a;对大模型数据量、参数量、算力之间的最优分配 不仅仅是对语言大模型&#xff0c;对主要基于tranformer的多模态大模型基本都有效 对于Decoder-only结构模型(GPT架构)&#…

[技术闲聊]我对电路设计的理解(十)-示波器选取

电路出故障了&#xff0c;要解决问题就需要循证辩药&#xff0c;调试工具有多样&#xff0c;但对于硬件工程师来说&#xff0c;调试时的眼睛必是示波器无疑&#xff0c;波形样式、幅度、频率等都是疑难杂症散发出的信息&#xff0c;捕获流量密码&#xff0c;就能淘到金&#xf…

Ps:合并到 HDR Pro

Ps菜单&#xff1a;文件/自动/合并到 HDR Pro Automate/Merge to HDR Pro 合并到 HDR Pro Merge to HDR Pro命令可以将同一场景的具有不同曝光度的多个图像合并起来&#xff0c;从而捕获单个 HDR 图像中的全部动态范围。 合并到 HDR Pro 命令分两步进行。 首先&#xff0c;需要…

java -网络编程socket-聊天室-02

完整版代码 java -聊天室的代码: 用于存放聊天室的项目的代码和思路导图https://gitee.com/to-uphold-justice-for-others/java---code-for-chat-rooms.git 先引入线程的正统解释 线程&#xff08;Thread&#xff09;是程序执行流的最小单元。线程是操作系统分配CPU时间片的基…

【HTML】制作一个简单的三角形动态图形

目录 前言 开始 HTML部分 CSS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段HTML和CSS代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建两个文本文档&#xff0c;其中HTML的文件名改为[index.html]&#xff0c;CSS的文件名…

Day83:服务攻防-开发组件安全JacksonFastJson各版本XStreamCVE环境复现

目录 J2EE-组件Jackson-本地demo&CVE 代码执行 (CVE-2020-8840) 代码执行 (CVE-2020-35728&#xff09; J2EE-组件FastJson-本地demo&CVE FastJson < 1.2.24 FastJson < 1.2.47 FastJson < 1.2.80 (利用条件比较苛刻) J2EE-组件XStream-靶场&CVE …

【JAVA】postman import certificates in project 导入证书pfx

1. 打开这个按钮 2. File ->Settings 3. 打开“certificates”, Add certificates 添加证书 4. 输入证书地址&#xff0c;然后选择证书文件pfx , 输入证书密码。点击添加就可以了。 特别提醒&#xff1a; 推荐本地自己证书验证软件&#xff0c;“KeyStore” 这个软件可以…

Revit模型进入虚幻引擎UE5教程

一、背景 小伙伴们是否有Revit进入虚幻引擎交互的需求呢&#xff1f; 二、实现功能 1.Revit进入虚幻UE5,包含模型属性&#xff0c;材质等 2.实现BIM构件点选&#xff0c;高亮&#xff0c;属性展示 3.实现BIM模型分层显示&#xff0c;爆炸等效果 三、教程地址 教程&#x…

软考 系统架构设计师系列知识点之数据库基本概念(1)

所属章节&#xff1a; 第6章. 数据库设计基础知识 第1节 数据库基本概念 数据&#xff08;Data&#xff09;是描述事务的符号记录&#xff0c;它具有多种表现形式&#xff0c;可以是文字、图形、图像、声音和语言等。信息&#xff08;Information&#xff09;是现实世界事物的…