07节-51单片机-矩阵键盘

文章目录

    • 1矩阵键盘原理
    • 2.扫描的概念
    • 3.弱上拉
    • 4.实战-实现矩阵键盘对应按钮按下显示对应值
        • 4.1配置代码模板
    • 5.键盘锁

1矩阵键盘原理

在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式
采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态
按行扫描:
例如,我将P1赋初值为0xFF,如果我们需要按行扫描,我选择将P1_7赋值为0,就是选择了P17所在的第一行按键(即S1,S2,S3,S4),那么我如果再要选择这一行的某个按键,则只需要将按列选择就行了,比如我要表示按下S1出发的反应,那么P1_3=0,即可表示按下了S1,其他的同理可得
按列扫描也不过是先将P_3赋初值为0,再选择某行,从而来定位某个按键。
在这里插入图片描述
根据情况选择按行,还是按列扫描,如果按行扫描存在和其他模块的引脚存在强烈冲突,那么就选择按列。

2.扫描的概念

数码管扫描(输出扫描)
原理:显示第1位→显示第2位→显示第3位→……,然后快速循环这个过程,最终实现所有数码管同时显示的效果
矩阵键盘扫描(输入扫描)
原理:读取第1行(列)→读取第2行(列) →读取第3行(列) → ……,然后快速循环这个过程,最终实现所有按键同时检测的效果
以上两种扫描方式的共性:节省I/O口

3.弱上拉

弱上拉,即输出的1驱动能力是有限的
弱上拉内部简单模型:
在这里插入图片描述
如果内部接高电平,外界也是高电平,那么读入的肯定是高电平;
如果内部接高电平,外界接地,是一种强GND,保持不了高电平,会被外界的强下拉拉到低电平,即输出1外界输入0,读进来的是0。
其他高系列的单片机,还有推挽输出,没有上拉电阻,高电平直接接到VCC,低电平直接接到GND,只能输出不能输入。
高阻输入:仅作为输入开漏输出:PO口
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
有源蜂鸣器和无源蜂鸣器的区别
有无振荡源,有源蜂鸣器内部带振荡源,所以只要一通电就会叫;而无源蜂鸣器内部不带振荡源,所以如果用直流信号无法令其鸣叫。

4.实战-实现矩阵键盘对应按钮按下显示对应值

目录结构:(仍然需要将之前的延时模块和LCD1602模块添加进来)
在这里插入图片描述

4.1配置代码模板

在这里插入图片描述
在这里插入图片描述
双击即可添加模板,方便快速写代码
在这里插入图片描述
MatrixKey.h

#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__
unsigned char MatrixKey();
#endif

MatrixKey.c

/**
  * @brief  矩阵键盘读取按键键码
  * @param  无参
  * @retval  KeyNumber 按下按键的键码值
	*          按下按键如果不放,那么程序将停留在该程序中,松手的一瞬间,返回按键键码:
  */
#include <REGX52.H>
#include "Delay.h"
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	P1=0xFF;
	P1_3=0; //选择第一列
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	P1=0xFF;
	P1_2=0; //选择第二列
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
  P1=0xFF;
	P1_1=0; //选择第三列
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	P1=0xFF;
	P1_0=0; //选择第四列
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	return KeyNumber;
}

main.c

#include <REGX52.H>  //安装目录下找
#include "Delay.h"  //本文件目录找
#include "LCD1602.h"
#include "MatrixKey.h"
unsigned char KeyNum;
void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"MatrixKey-wind:");
	while(1)
	{
		KeyNum=MatrixKey();
		if(KeyNum)
		{
			LCD_ShowNum(2,1,KeyNum,2);
		}
	}
}

其他的延时函数和LCD1602见前面的文章。

5.键盘锁

通过设计一个密码锁,其中键1-10,作为输入密码按键,表示数字1-9和0,11按键作为确认键,12作为取消键。
注意:除了main.c文件,其他的和上一个文件相同,可直接复制上一个工程的文件。
main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "MatrixKey.h"
#include "Delay.h"
unsigned char KeyNum;
unsigned int Password,Count;
void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"PassWord:");
	while(1)
	{
		KeyNum=MatrixKey();
		if(KeyNum)
		{
			if(KeyNum<=10) //如果键码值小于等于10,作为按键,密码输入。
			{
				if(Count<4)
				{
					Password*=10;
					Password+=KeyNum%10;
					Count++;
					LCD_ShowNum(2,1,Password,4);
				}
			}
			if(KeyNum==11)  //如果键码值为11,则,表示确认密码
			{
				if(Password==2345)  //如果密码正确
				{
					Count=0;   //计数器和密码都清零
					Password=0;
					LCD_ShowString(1,14,"OK "); //显示ok
				}
				else
				{
					Count=0;
					Password=0;
					LCD_ShowString(1,14,"ERR");
				}
				LCD_ShowNum(2,1,Password,4); //清零之后显示
			}
			if(KeyNum==12)  //如果按键12,则取消,即清零。
			{
				Count=0;
				Password=0;
				LCD_ShowNum(2,1,Password,4);
			}
		}
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前程贷v6.5系统测试报告

1.引言部分 1&#xff0e;1 项目背景 本测试报告的具体编写目的&#xff0c;指出预期的读者范围。(3-4句) 项目描述 &#xff08;项目内容&#xff0c;用户需求&#xff09; 本测试报告为**&#xff08;系统名称&#xff09;**系统测试报告&#xff1b;本报告目的在于总结测试…

【JavaEE初阶系列】——数据链路层以太网以及Mac地址

目录 &#x1f6a9;认识以太网 &#x1f6a9;以太网帧格式 &#x1f6a9;IP地址和Mac地址各自的用途 &#x1f6a9;认识以太网 "以太网"不是一种具体的网络&#xff0c;而是一种技术标准&#xff1b;既包含了数据链路层的内容&#xff0c;也包含了一些物理层的内…

在ios设备上运行Unity Profiler

久违了朋友们。 最近基于Unity 2021.3 和AR Foundation开发了个应用&#xff0c;需要在ipad上实际运行时查看程序的各项指标功耗。 于是乎&#xff0c;我尝试跟随者官方教程来实时调试&#xff0c;现在附上一些心得。 按照官方的三步走&#xff0c;Build and Run理论上会自动…

SSH远程连接服务实战

题目&#xff1a; 一.配置两台主机 主机1、 主机名: server.example.com ip: 192.168.78.129 建立用户timinglee&#xff0c;其密码为timinglee 主机2、 主机名&#xff1a;client.example.com ip: 192.168.78.128 2.安需求完成项目 192.168.78.128 在远程登录192.168.78.129的…

MySQL处理并发访问和高负载的关键技术和策略

大家好&#xff0c;我是咕噜铁蛋。今天&#xff0c;我想和大家聊聊MySQL处理并发访问和高负载的关键技术和策略。在当今这个数据爆炸的时代&#xff0c;数据库作为数据存储和处理的核心&#xff0c;其性能的稳定性和高效性显得尤为重要。MySQL作为广泛使用的关系型数据库管理系…

【语音识别】在Win11使用Docker部署FunASR服务器

文章目录 在 Win11 使用 Docker 部署 FunASR 服务器镜像启动服务端启动监控服务端日志下载测试案例使用测试案例打开基于 HTML 的案例连接ASR服务端 关闭FunASR服务 在 Win11 使用 Docker 部署 FunASR 服务器 该文章因官网文档不详细故写的经验论 官网文章&#xff1a;https:/…

安装多个MySQL版本时如何连接到不同的数据库

当安装多个版本的数据库时&#xff0c;不同版本的端口名不一样&#xff0c;可以使用以下命令进行连接 mysql -uroot -p数据库密码 -h主机名 -P端口号 数据库主机名默认是localhost&#xff0c;端口号默认是3306&#xff0c;当安装多个版本数据库时&#xff0c;需要记住数据库的…

Prompt-to-Prompt Image Editing with Cross Attention Control

Prompt-to-Prompt Image Editing with Cross Attention Control TL; DR&#xff1a;prompt2prompt 提出通过替换 UNet 中的交叉注意力图&#xff0c;在图像编辑过程中根据新的 prompt 语义生图的同时&#xff0c;保持图像整体布局结构不变。从而实现了基于纯文本&#xff08;不…

2024HW --->蓝队面试题

这段时间在写横向移动&#xff0c;搞得鸽了很久&#xff08;内网真的很玄学&#xff09; 还没写完。。。 但是这不是准备HW了吗。小编也来整理一下自己收集到的题目吧&#xff01;&#xff01;&#xff01; &#xff08;仅为个人见解&#xff0c;不代表最终答案&#xff09;&…

select实现echo服务器的并发

select实现echo服务器的并发 代码实现 #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <stdlib.h> #include <arpa/inet.h> #include <sys/select.h> #include <sys/time.h…

Nodejs - 异步I/O

异步I/O 利用单线程&#xff0c;远离多线程死锁&#xff0c;状态同步等问题&#xff0c;利用异步I/O&#xff0c; 让单线程原理阻塞&#xff0c;更好的使用cpu异步I/O实现现状 阻塞IO 操作系统内对于I/O只有两种方式: 阻塞和非阻塞。在调用阻塞I/O的时候&#xff0c;应用程序需…

无损以太网的ROCE革命,队列的缓存空间优化分析

ROCE无损以太网&#xff0c;队列的缓存空间优化 多级缓存架构优化芯片性能&#xff1a;* 缓存空间细分为芯片级、端口级和队列级&#xff0c;实现精细管理。* 无损队列引入Headroom缓存空间&#xff0c;确保数据完整性。 在芯片层面&#xff1a; 静态缓存为端口提供保证的缓存空…

Tomcat弱口令及war包漏洞复现(保姆级教程)

1.环境搭建 靶机&#xff1a;Ubuntu 安装参考&#xff1a;安装Ubuntu详细教程_乌班图安装教程-CSDN博客 vulhub docker搭建tomcat漏洞环境 参考&#xff1a;vulhub docker靶场搭建-CSDN博客 工具&#xff1a;burpsuite 2.漏洞复现 2.1弱口令爆破 进入http://192.168.143…

分类神经网络1:VGGNet模型复现

目录 分类网络的常见形式 VGG网络架构 VGG网络部分实现代码 分类网络的常见形式 常见的分类网络通常由特征提取部分和分类部分组成。 特征提取部分实质就是各种神经网络&#xff0c;如VGG、ResNet、DenseNet、MobileNet等。其负责捕获数据的有用信息&#xff0c;一般是通过…

创新案例|Amazon.com 2023 年营销策略:电子商务零售巨头商业案例研究

2022 年最后一个季度&#xff0c;亚马逊报告净销售额超过 1,492 亿美元。这种季节性峰值是亚马逊季度报告的典型特征&#xff0c;但增长是不可否认的&#xff0c;因为这是该公司有史以来最高的季度。毫无疑问&#xff0c;这家电商零售巨头继续引领电商增长。本文将介绍我们今天…

Elasticsearch进阶篇(三):ik分词器的使用与项目应用

ik分词器的使用 一、下载并安装1.1 已有作者编译后的包文件1.2 只有源代码的版本1.3 安装ik分词插件 二、ik分词器的模式2.1 ik_smart演示2.2 ik_max_word演示2.3 standard演示 三、ik分词器在项目中的使用四、ik配置文件4.1 配置文件的说明4.2 自定义词库 五、参考链接 一、下…

mysql基础10——函数

数学函数 处理数值数据 取整函数 round(X,D) X表示要处理的数 D表示要保留的小数位数 处理的方式是四舍五入 round(X) 保留0位小数 金额要精确到分 说明保留两位小数 select round(salevalue,2) from demo.transactiondetails where transactionid1 and itemnum1; cei…

matplotlib从起点出发(15)_Tutorial_15_blitting

0 位图传输技术与快速渲染 Blitting&#xff0c;即位图传输、块传输技术是栅格图形化中的标准技术。在Matplotlib的上下文中&#xff0c;该技术可用于&#xff08;大幅度&#xff09;提高交互式图形的性能。例如&#xff0c;动画和小部件模块在内部使用位图传输。在这里&#…

记录一个hive中跑insert语句说没创建spark客户端的问题

【背景说明】 我目前搭建离线数仓&#xff0c;并将hive的执行引擎改成了Spark&#xff0c;在将ods层的数据装载到dim层&#xff0c;执行insert语句时报如下错误 【报错】 [42000][40000] Error while compiling statement: FAILED: SemanticException Failed to get a spark…

Rust序列化和反序列化

Rust 编写python 模块 必备库 docker 启动 nginx 服务 NGINX 反向代理配置