单片机学习笔记 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.rhkb.cn/news/478676.html

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

相关文章

道品智能科技移动式水肥一体机:农业灌溉施肥的革新之选

在现代农业的发展进程中&#xff0c;科技的力量正日益凸显。其中&#xff0c;移动式水肥一体机以其独特的可移动性、智能化以及实现水肥一体化的卓越性能&#xff0c;成为了农业领域的一颗璀璨新星。它不仅改变了传统的农业灌溉施肥方式&#xff0c;更为农业生产带来了高效、精…

android 音效可视化--Visualizer

Visualizer 是使应用程序能够检索当前播放音频的一部分以进行可视化。它不是录音接口&#xff0c;仅返回部分低质量的音频内容。但是&#xff0c;为了保护某些音频数据的隐私&#xff0c;使用 Visualizer 需要 android.permission.RECORD_AUDIO权限。传递给构造函数的音频会话 …

计算机网络八股整理(一)

计算机网络八股文整理 一&#xff1a;网络模型 1&#xff1a;网络osi模型和tcp/ip模型分别介绍一下 osi模型是国际标准的网络模型&#xff0c;它由七层组成&#xff0c;从上到下分别是&#xff1a;应用层&#xff0c;表示层&#xff0c;会话层&#xff0c;传输层&#xff0c;…

利用Python爬虫获得1688按关键字搜索商品:技术解析

在电商领域&#xff0c;1688作为中国领先的B2B电商平台&#xff0c;其商品搜索功能对于商家来说具有极高的价值。通过获取搜索结果&#xff0c;商家可以更好地了解市场趋势&#xff0c;优化产品标题&#xff0c;提高搜索排名。本文将介绍如何使用Python编写爬虫&#xff0c;以获…

Spring Boot集成MyBatis-Plus:自定义拦截器实现动态表名切换

Spring Boot集成MyBatis-Plus&#xff1a;自定义拦截器实现动态表名切换 一、引言 介绍动态表名的场景需求&#xff0c;比如多租户系统、分表分库&#xff0c;或者不同业务模块共用一套代码但操作不同表。说明 MyBatis-Plus 默认绑定固定表名的问题。 二、项目配置 1. 集成 M…

(原创)Android Studio新老界面UI切换及老版本下载地址

前言 这两天下载了一个新版的Android Studio&#xff0c;发现整个界面都发生了很大改动&#xff1a; 新的界面的一些设置可参考一些博客&#xff1a; Android Studio新版UI常用设置 但是对于一些急着开发的小伙伴来说&#xff0c;没有时间去适应&#xff0c;那么怎么办呢&am…

数据新时代:如何选择现代数据治理平台(上)

谈现代数据治理系统的十大架构特征 最近一位老友找到我&#xff0c;咨询他的数据治理平台到底该不该换&#xff0c;背景是这样的&#xff1a;若干年前采购了一个市场主流的数据治理平台&#xff0c;功能大概就是数据治理三件套——标准、元数据和质量等经典数据治理的功能。现…

抖音SEO矩阵系统:开发技术分享

市场环境剖析 短视频SEO矩阵系统是一种策略&#xff0c;旨在通过不同平台上的多个账号建立联系&#xff0c;整合同一品牌下的各平台粉丝流量。该系统通过遵循每个平台的规则和内容要求&#xff0c;输出企业和品牌形象&#xff0c;以矩阵形式增强粉丝基础并提升商业价值。抖音作…

从零开始打造个人博客:我的网页设计之旅

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 ✨特色专栏&#xff1a…

STM32F103C8T6实时时钟RTC

目录 前言 一、RTC基本硬件结构 二、Unix时间戳 2.1 unix时间戳定义 2.2 时间戳与日历日期时间的转换 2.3 指针函数使用注意事项 ​三、RTC和BKP硬件结构 四、驱动代码解析 前言 STM32F103C8T6外部低速时钟LSE&#xff08;一般为32.768KHz&#xff09;用的引脚是PC14和PC…

Jmeter中的定时器

4&#xff09;定时器 1--固定定时器 功能特点 固定延迟&#xff1a;在每个请求之间添加固定的延迟时间。精确控制&#xff1a;可以精确控制请求的发送频率。简单易用&#xff1a;配置简单&#xff0c;易于理解和使用。 配置步骤 添加固定定时器 右键点击需要添加定时器的请求…

Fakelocation Server服务器/专业版 ubuntu

前言:需要Ubuntu系统 Fakelocation开源文件系统需求 Ubuntu | Fakelocation | 任务一 任务一 更新Ubuntu&#xff08;安装下载不再赘述&#xff09; sudo -i # 提权 sudo apt update # 更新软件包列表 sudo apt upgrade # 升级已安装的软…

5.5 W5500 TCP服务端与客户端

文章目录 1、TCP介绍2、W5500简介2.1 关键函数socketlistensendgetSn_RX_RSRrecv自动心跳包检测getSn_SR 1、TCP介绍 TCP 服务端&#xff1a; 创建套接字[socket]&#xff1a;服务器首先创建一个套接字&#xff0c;这是网络通信的端点。绑定套接字[bind]&#xff1a;服务器将…

超高流量多级缓存架构设计!

文章内容已经收录在《面试进阶之路》&#xff0c;从原理出发&#xff0c;直击面试难点&#xff0c;实现更高维度的降维打击&#xff01; 文章目录 电商-多级缓存架构设计多级缓存架构介绍多级缓存请求流程负载均衡算法的选择轮询负载均衡一致性哈希负载均衡算法选择 应用层 Ngi…

信创改造 - TongRDS 替换 Redis

记得开放 6379 端口哦 1&#xff09;首先在服务器上安装好 TongRDS 2&#xff09;替换 redis 的 host&#xff0c;post&#xff0c;passwd 3&#xff09;TongRDS 兼容 jedis # 例如&#xff1a;更改原先 redis 中对应的 host&#xff0c;post&#xff0c;passwd 改成 TongRDS…

vue3 uniapp 扫普通链接或二维码打开小程序并获取携带参数

vue3 uniapp 扫普通链接或二维码打开小程序并获取携带参数 微信公众平台添加配置 微信公众平台 > 开发管理 > 开发设置 > 扫普通链接二维码打开小程序 配置链接规则需要下载校验文档给后端存入服务器中&#xff0c;保存配置的时候会校验一次&#xff0c;确定当前的配…

Git(一)基本使用

目录 一、使用git -v 查看安装git版本 二、使用mkdir 创建一个文件&#xff0c;并使用 git init 在该目录下创建一个本地仓库&#xff0c; 三、通过git clone命令接入线上仓库 四、使用git status查看仓库状态信息 五、利用echo写入一个文件 并使用cat进行查看 【Linux】e…

QML学习 —— 29、3种不同使用动画的方式(附源码)

效果 说明 第一种:属性动画 - 当启动软件时候自动执行动画。      第二种:行为动画 - 当属性发生变化则自动执行动画。      第三种:目标动画 - 将动画变为对象,指定对象的目标进行执行动画。 代码 import QtQuick 2.12 import QtQuick.Window 2.12 import QtQu…

下载并安装Visual Studio 2017过程

一、下载 1、下载链接 下载链接&#xff1a;官方网址 先登录 往下滑找到较早的下载 2、进行搜索下载 或者直接点击&#x1f517;网站跳转 3、确认系统信息进行下载 二、安装 下载完成后右键使用管理员身份运行 1、点击同意后安装 2、若报错—设置失败 打开控制面板-&g…

React(五)——useContecxt/Reducer/useCallback/useRef/React.memo/useMemo

文章目录 项目地址十六、useContecxt十七、useReducer十八、React.memo以及产生的问题18.1组件嵌套的渲染规律18.2 React.memo18.3 引出问题 十九、useCallback和useMemo19.1 useCallback对函数进行缓存19.2 useMemo19.2.1 基本的使用19.2.2 缓存属性数据 19.2.3 对于更新的理解…