单片机学习笔记 8. 矩阵键盘按键检测

更多单片机学习笔记:
单片机学习笔记 1. 点亮一个LED灯
单片机学习笔记 2. LED灯闪烁
单片机学习笔记 3. LED灯流水灯
单片机学习笔记 4. 蜂鸣器滴~滴~滴~
单片机学习笔记 5. 数码管静态显示
单片机学习笔记 6. 数码管动态显示
单片机学习笔记 7. 独立键盘


目录

0、实现的功能

1、Keil工程

1-1 矩阵键盘识别方法

1-2 swich语句

2、代码实现


0、实现的功能

        4*4矩阵键盘+独立键盘的按键检测,可拓展为四管显示

1、Keil工程

1-1 矩阵键盘识别方法

        主要采用列扫描(1111 0000)和行扫描(0000 1111)的方法。

        列扫描的初始操作是输入P3口为0xF0,当S6被按下时,P34由1会变为0,此时P3口为0xE0;同理,S10被按下时,P3也为0xE0。所以第一列被按下时,P3为1110 0000;第二列被按下时,P3为1101 0000;第三列被按下时,P3为1011 0000;第四列被按下时,P3为0111 0000。
所以P30--P33为行线,P34--P37为列线

        再做行扫描,P3初始为0x0F。当S6被按下时,P30会从1变为0,P3为0000 1110.最后再和列扫描的结果相加:1110 0000 + 0000 1110 = 1110 1110,得到确切的位置(第一列,第一行)

        所以P3的数据中,前四位为哪一列,后四位为哪一行。谁为0就是哪一行列

1-2 swich语句

        主要涉及到c语言中的switch语句

2、代码实现

        显示的按键序号和对应显示数字表如下: 
​       
        只要是涉及到按键的,都要进行软件消抖+松手检测。赋值P3=0xf0进行列扫描,找到是哪一列,KeyValue可以直接为0 1 2 3------赋值P3=0x0f进行行扫描,每行之间相差4,此时KeyValue对应的+4即可
        独立按键扫描的话,赋值P3=0xff,这样就不是列扫描和行扫描了。按下哪个,哪一位就为0,找到对应的显示数字即可

代码实现:

#include <reg52.h>
#include <intrins.h>#define uchar unsigned char
#define uint unsigned intsbit WE = P2^7; //锁存器位选,U8的LE,选择哪个数码管
sbit DU = P2^6; //锁存器段选,U9的LE,控制亮什么数字uchar KeyValue = 6;		//按键显示值//共阴极数码管段选表0-9
uchar code table1[] = {
//0		1	  2		3	  4		5	  6		7	  8	
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 
//9		A	  B		C	  D		E	  F		H	  L
0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x76, 0x38,
//n		u	  -		熄灭
0x37, 0x3e, 0x40, 0x00} ;//延时模块
void delay(uint z)
{uint x;uint y;for(x = z; x > 0; x--)for(y = 114; y > 0; y--);
}void KeyScan()
{//4*4矩阵键盘扫描P3 = 0xf0;		//列扫描初始化if(P3 != 0xf0)		//判断按键是否被按下{delay(10);		//软件消抖10msif(P3 != 0xf0)	//再判断是否真正被按下,有可能是误触{switch(P3)		//判断哪一列被按下{case 0xe0:	KeyValue = 0; break;	//第一列case 0xd0:	KeyValue = 1; break;	//第二列case 0xb0:	KeyValue = 2; break;	//第三列case 0x70:	KeyValue = 3; break;	//第四列}P3 = 0x0f;		//行扫描初始化switch(P3)		//判断哪一行被按下{case 0x0e:	KeyValue = KeyValue; break;	//第一行case 0x0d:	KeyValue = KeyValue + 4; break;	//第二行case 0x0b:	KeyValue = KeyValue + 8; break;	//第三行case 0x07:	KeyValue = KeyValue + 12; break;	//第四行}while(P3 != 0x0f);		//松手检测}}//独立按键扫描P3 = 0xff;if(P3 != 0xff){delay(10);		//软件消抖10msif(P3 != 0xff){switch(P3)		//判断哪一行被按下{case 0xfe:	KeyValue = 16; break;	//S2case 0xfd:	KeyValue = 17; break;	//S3case 0xfb:	KeyValue = 18; break;	//S4case 0xf7:	KeyValue = 19; break;	//S5}while(P3 != 0xff);		//松手检测		}}
}void main()
{//指定第一个数码管,不用放在循环里P0 = 0xff;//清除断码,让位锁存器哪个都不选WE = 1;//位选锁存打开P0 = 0xfe;//选第一个管WE = 0;	//进入锁存while(1){KeyScan();		//20个按键扫描DU = 1;//段选锁存打开P0 = table1[KeyValue];DU = 0;//进入锁存}	
}

        可以结合数码管动态显示,弄点好玩的
 

#include <reg52.h>
#include <intrins.h>#define uchar unsigned char
#define uint unsigned intsbit WE = P2^7; //锁存器位选,U8的LE,选择哪个数码管
sbit DU = P2^6; //锁存器段选,U9的LE,控制亮什么数字uchar KeyValue = 6;		//按键显示值//共阴极数码管段选表0-9
uchar code table1[] = {
//0		1	  2		3	  4		5	  6		7	  8	
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 
//9		A	  B		C	  D		E	  F		H	  K
0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x76, 0x76,
//n		u	  -	  熄灭
0x37, 0x3e, 0x40, 0x00} ;//延时模块
void delay(uint z)
{uint x;uint y;for(x = z; x > 0; x--)for(y = 114; y > 0; y--);
}void KeyScan()
{//4*4矩阵键盘扫描P3 = 0xf0;		//列扫描初始化if(P3 != 0xf0)		//判断按键是否被按下{delay(10);		//软件消抖10msif(P3 != 0xf0)	//再判断是否真正被按下,有可能是误触{switch(P3)		//判断哪一列被按下{case 0xe0:	KeyValue = 0; break;	//第一列case 0xd0:	KeyValue = 1; break;	//第二列case 0xb0:	KeyValue = 2; break;	//第三列case 0x70:	KeyValue = 3; break;	//第四列}P3 = 0x0f;		//行扫描初始化switch(P3)		//判断哪一行被按下{case 0x0e:	KeyValue = KeyValue; break;	//第一行case 0x0d:	KeyValue = KeyValue + 4; break;	//第二行case 0x0b:	KeyValue = KeyValue + 8; break;	//第三行case 0x07:	KeyValue = KeyValue + 12; break;	//第四行}while(P3 != 0x0f);		//松手检测}}//独立按键扫描P3 = 0xff;if(P3 != 0xff){delay(10);		//软件消抖10msif(P3 != 0xff){switch(P3)		//判断哪一行被按下{case 0xfe:	KeyValue = 16; break;	//S2case 0xfd:	KeyValue = 17; break;	//S3case 0xfb:	KeyValue = 18; break;	//S4case 0xf7:	KeyValue = 19; break;	//S5}while(P3 != 0xff);		//松手检测		}}
}void main()
{while(1){KeyScan();		//20个按键扫描P0 = 0xff;//清除断码,让位锁存器哪个都不选WE = 1;//位选锁存打开P0 = 0xfe;//选第一个管WE = 0;	//进入锁存DU = 1;//段选锁存打开P0 = table1[KeyValue];DU = 0;//进入锁存delay(5);P0 = 0xff;//清除断码,让位锁存器哪个都不选WE = 1;//位选锁存打开P0 = 0xfd;//选第2个管WE = 0;	//进入锁存DU = 1;//段选锁存打开P0 = table1[KeyValue+4];DU = 0;//进入锁存delay(5);P0 = 0xff;//清除断码,让位锁存器哪个都不选WE = 1;//位选锁存打开P0 = 0xfb;//选第3个管WE = 0;	//进入锁存DU = 1;//段选锁存打开P0 = table1[KeyValue-3];DU = 0;//进入锁存delay(5);P0 = 0xff;//清除断码,让位锁存器哪个都不选WE = 1;//位选锁存打开P0 = 0xf7;//选第4个管WE = 0;	//进入锁存DU = 1;//段选锁存打开P0 = table1[KeyValue+2];DU = 0;//进入锁存delay(5);}	
}

实物展示: 

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

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

相关文章

使用 Django 构建支持 Kubernetes API 测试连接的 POST 接口

文章目录 使用 Django 构建支持 Kubernetes API 测试连接的 POST 接口功能需求使用 kubectl 获取 Token命令解析输出示例 完整代码实现Kubernetes API 客户端类功能说明 Django 接口视图关键点解析 路由配置 接口测试请求示例响应结果成功错误 优化建议1. 安全性2. 错误处理3. …

【AI日记】24.11.26 聚焦 kaggle 比赛

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 核心工作 1 内容&#xff1a;研究 kaggle 比赛时间&#xff1a;3 小时 核心工作 2 内容&#xff1a;学习 kaggle 比赛 Titanic - Machine Learning from Disaster时间&#xff1a;4 小时备注&#xff1a;这…

排序算法2

排序算法1-CSDN博客 排序算法1中提及的是较为基础(暴力实现&#xff0c;复杂度较高)的排序算法&#xff0c;不适合于数据量较大的场景&#xff0c;比如序列长度达到1e5 接下来以蓝桥另一道题目来理解其它的排序算法 蓝桥3226 蓝桥账户中心 样例 5 1 5 9 3 7 4、快速排序 快速排…

【数据结构实战篇】用C语言实现你的私有队列

&#x1f3dd;️专栏&#xff1a;【数据结构实战篇】 &#x1f305;主页&#xff1a;f狐o狸x 在前面的文章中我们用C语言实现了栈的数据结构&#xff0c;本期内容我们将实现队列的数据结构 一、队列的概念 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端…

macos 14.0 Monoma 修改顶部菜单栏颜色

macos 14.0 设置暗色后顶部菜单栏还维持浅色&#xff0c;与整体不协调。 修改方式如下&#xff1a;

长三角文博会:Adobe国际认证体系推动设计人才评价新标准

2024年11月22日&#xff0c;由上海、江苏、浙江、安徽三省一市党委宣传部共同发起的第五届长三角文化博览会&#xff08;简称“长三角文博会”&#xff09;在上海国家会展中心盛大启幕。长三角文博会自2018年起已成功举办多届&#xff0c;已成为展示区域文化产业发展成果、推动…

安装数据库客户端工具

如果没有勾选下面的&#xff0c;可以运行下面的两个命令 红框为自带数据库 新建数据库 右键运行mysql文件&#xff0c;找到数据库&#xff0c;并刷新

SQL 复杂查询

目录 复杂查询 一、目的和要求 二、实验内容 &#xff08;1&#xff09;查询出所有水果产品的类别及详情。 查询出编号为“00000001”的消费者用户的姓名及其所下订单。&#xff08;分别采用子查询和连接方式实现&#xff09; 查询出每个订单的消费者姓名及联系方式。 在…

Angular面试题汇总系列一

1. 如何理解Angular Signal Angular Signals is a system that granularly tracks how and where your state is used throughout an application, allowing the framework to optimize rendering updates. 什么是信号 信号是一个值的包装器&#xff0c;可以在该值发生变化时…

ES 和Kibana-v2 带用户登录验证

1. 前言 ElasticSearch、可视化操作工具Kibana。如果你是Linux centos系统的话&#xff0c;下面的指令可以一路CV完成服务的部署。 2. 服务搭建 2.1. 部署ElasticSearch 拉取docker镜像 docker pull elasticsearch:7.17.21 创建挂载卷目录 mkdir /**/es-data -p mkdir /**/…

esp32触发相机

esp32触发相机&#xff0c;测试成功上升沿触发 串口发送命令 up 20000 1 20000 触发 #include <Arduino.h>const int outputPin 12; // 输出引脚 String inputCommand ""; // 串口输入缓冲区// 解析命令参数&#xff0c;例如 "up 10 5" 解析为…

【踩坑】git中文乱码问题

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 背景说明 使用git diff显示中文乱码&#xff0c;如&#xff1a; 修复方法 执行一次&#xff1a; export LESSCHARSETutf-8 如果需要下次登录免输入…

Spring Boot中配置Flink的资源管理

在 Spring Boot 中配置 Flink 的资源管理&#xff0c;需要遵循以下步骤&#xff1a; 添加 Flink 依赖项 在你的 pom.xml 文件中&#xff0c;添加 Flink 和 Flink-connector-kafka 的依赖项。这里以 Flink 1.14 版本为例&#xff1a; <!-- Flink dependencies --><de…

c++学习:json库例子

目录 初始化 解析string字符串并输出 赋值 给json赋值string&#xff0c;char *&#xff0c;QString&#xff0c;bool&#xff0c;int 赋值 将json转为string&#xff0c;char *&#xff0c;QString 删除 嵌套对象和数组的组合与解析 JSON 数组 遍历&#xff0c;添加…

【环境搭建】更新Docker Compose到v2.x版本以支持--profile选项

Docker版本陈旧也是搭建的环境起不来的一个重要原因&#xff0c;比如 --profile 选项是 Docker 20.10.0 版本及以上版本才开始支持的&#xff0c;在 Docker Compose v2.1&#xff08;及以上版本&#xff09;中引入用于对服务进行分组和按需启动。 更新 Docker Compose 到 v2.x…

网络——浏览器发送一个请求到收到响应经历了哪些步骤

当浏览器发送一个请求到服务器并收到响应时&#xff0c;通常会经历以下几个步骤。这个过程可以分为几个主要阶段&#xff1a;DNS解析、建立TCP连接、发送HTTP请求、服务器处理请求和返回响应、浏览器接收响应等。下面是更详细的步骤说明&#xff1a; 输入URL&#xff1a;用户在…

Python基础速通

Python基础速通 Python是一门强大的编程语言&#xff0c;广泛应用于数据分析、自动化、网络安全等多个领域。本文将系统地介绍Python的基础知识&#xff0c;包括环境配置、基础语法、数据结构、函数、面向对象编程以及常见的文件操作和异常处理技巧。 Python 环境安装 在开始…

.Net与C#

.NET 与 C# 的关系 .NET 是一个由微软开发的软件框架&#xff0c;它提供了一套用于开发、运行和部署应用程序的工具和库。C# 是一种面向对象的编程语言&#xff0c;它是专门为.NET平台设计的。以下是.NET与C#之间关系的详细说明&#xff1a; 目标平台&#xff1a;C# 是.NET平…

go语言逆向-基础basic

文章目录 go 编译命令 ldflags -w -s的作用和问题使用 file 命令查看文件类型 go 语言逆向参考go ID版本GOROOT和GOPATHGOROOTGOPATHGOROOT和GOPATH的关系示例 go build和 go modpclntab &#xff08;Program Counter Line Table 程序计数器行数映射表&#xff09;Moduledata程…

D2761 适合在个人电脑、便携式音响等系统中作音频限幅用。

概述&#xff1a; D2761是为保护扬声器所设计的音频限幅器&#xff0c;其限幅值可通过外接电阻来调节&#xff0c;适合在个人电脑、便携式音响等系统中作音频限幅用。D2761采用SSOP10、MSOP10、TSSOP14的封装形式封装。 主要特点&#xff1a;  工作电压范围宽&#xff1a;2.7…