当前位置: 首页 > news >正文

嵌入式开发学习(STC51-7-矩阵按键)

内容

按下S1-S16键,对应数码管最左边显示0-F

矩阵按键简介

独立按键与单片机连接时,每一个按键都需要单片机的一个I/O 口,若某单片机系统需较多按键,如果用独立按键便会占用过多的I/O口资源;而单片机
系统中I/O口资源往往比较宝贵,当用到多个按键时为了减少I/O口引脚,引入了矩阵按键;

以4*4矩阵键盘为例,键排成4行4列,第一行将每个按键的一端连接在一起构成行线,第一列将每个按键的另一端连接在一起构成列线,这样便一共有4行4列共8根线,我们将这8根线连接到单片机的8个I/O口上,通过程序扫描键盘就可检测16个键;

用这种方法也可实现3行3列9个键、5行5列25个键、6行6列36个键甚至更多;

无论是独立键盘还是矩阵键盘,单片机检测其是否被按下的依据都是一样的,也就是检测与该键对应的I/O口是否为低电平;

独立键盘有一端固定为低电平,此种方式编程比较简单;而矩阵键盘两端都与单片机I/O口相连,因此在检测时需编程通过单片机I/O口送出低电平;

检测方法有多种,最常用的是行列扫描和线翻转法:

  • 行列扫描法检测时,(可以看作是每次把一列当作独立按键来检测)依次送一列为低电平,其余几列全为高电平(行全为高电平),如果检测到该列有行电平变低,即该列有按键按下,就可以确定列,然后立即检测该行哪列为低电平,则可确定行,这样我们就可确认当前被按下的键是哪一行哪一列的;当然我们也可以依次将行线置低电平(其余行列为高电平),扫描列是否有低电平;
  • 线翻转法,就是使所有行线为低电平时,检测所有列线是否有低电平,如果有,就记录列线值;然后再翻转,使所有列线都为低电平,检测所有行线的值,由于有按键按下,行线的值也会有变化,记录行线的值;得到的行列值就是按下的按键;

矩阵键盘也少不了按键消抖的环节;

原理图

线路图
在这里插入图片描述
由线路图可知,P17-14控制行,P13-10控制列

思路

使用行列扫描法,每次把一列当作独立按键来检测,依次让每列为低电位,如果某列有行变为低电位,则该行和列即是按下的按键;

注意消抖;

编码

main.c

/** @Description: 矩阵按键-按下S1-S16键,对应数码管最左边显示0-F*/
#include "reg52.h"typedef unsigned int u16; // 对系统默认数据类型进行重定义
typedef unsigned char u8;#define KEY_MATRIX_PORT P1 // 使用宏定义矩阵按键控制口#define SMG_A_DP_PORT P0 // 使用宏定义数码管段码口// 共阴极数码管显示0~F的段码数据
u8 gsmg_code[17] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};/*** @description: 延时函数(循环一次大约10us)* @param {u16} ten_us* @return {*}*/
void delay_10us(u16 ten_us)
{while (ten_us--);
}/*** @description: 使用行列式扫描方法,检测矩阵按键是否按下,按下则返回对应键值* @return {u8} key的键值*/
u8 key_matrix_ranks_scan(void)
{u8 key_value = 0;KEY_MATRIX_PORT = 0xf7;		 // 给第一列赋值0,其余全为1if (KEY_MATRIX_PORT != 0xf7) // 判断第一列按键是否按下(如果有按键按下,即其中有行变为低位,则两边就不相等){delay_10us(1000);		 // 消抖switch (KEY_MATRIX_PORT) // 保存第一列按键按下后的键值{case 0x77:key_value = 1;break;case 0xb7:key_value = 5;break;case 0xd7:key_value = 9;break;case 0xe7:key_value = 13;break;}}while (KEY_MATRIX_PORT != 0xf7); // 等待按键松开KEY_MATRIX_PORT = 0xfb;		 // 给第二列赋值0,其余全为1if (KEY_MATRIX_PORT != 0xfb) // 判断第二列按键是否按下{delay_10us(1000);		 // 消抖switch (KEY_MATRIX_PORT) // 保存第二列按键按下后的键值{case 0x7b:key_value = 2;break;case 0xbb:key_value = 6;break;case 0xdb:key_value = 10;break;case 0xeb:key_value = 14;break;}}while (KEY_MATRIX_PORT != 0xfb); // 等待按键松开KEY_MATRIX_PORT = 0xfd;		 // 给第三列赋值0,其余全为1if (KEY_MATRIX_PORT != 0xfd) // 判断第三列按键是否按下{delay_10us(1000);		 // 消抖switch (KEY_MATRIX_PORT) // 保存第三列按键按下后的键值{case 0x7d:key_value = 3;break;case 0xbd:key_value = 7;break;case 0xdd:key_value = 11;break;case 0xed:key_value = 15;break;}}while (KEY_MATRIX_PORT != 0xfd); // 等待按键松开KEY_MATRIX_PORT = 0xfe;		 // 给第四列赋值0,其余全为1if (KEY_MATRIX_PORT != 0xfe) // 判断第四列按键是否按下{delay_10us(1000);		 // 消抖switch (KEY_MATRIX_PORT) // 保存第四列按键按下后的键值{case 0x7e:key_value = 4;break;case 0xbe:key_value = 8;break;case 0xde:key_value = 12;break;case 0xee:key_value = 16;break;}}while (KEY_MATRIX_PORT != 0xfe); // 等待按键松开return key_value;
}/*** @description: 使用线翻转扫描方法,检测矩阵按键是否按下,按下则返回对应键值* @return {u8} key的键值*/
u8 key_matrix_flip_scan(void)
{static u8 key_value = 0;KEY_MATRIX_PORT = 0x0f;		 // 给所有行赋值0,列全为1if (KEY_MATRIX_PORT != 0x0f) // 判断按键是否按下{delay_10us(1000); // 消抖if (KEY_MATRIX_PORT != 0x0f){// 测试列KEY_MATRIX_PORT = 0x0f;switch (KEY_MATRIX_PORT) // 保存行为0,按键按下后的列值{case 0x07:key_value = 1;break;case 0x0b:key_value = 2;break;case 0x0d:key_value = 3;break;case 0x0e:key_value = 4;break;}// 测试行KEY_MATRIX_PORT = 0xf0;switch (KEY_MATRIX_PORT) // 保存列为0,按键按下后的键值{case 0x70:key_value = key_value;break;case 0xb0:key_value = key_value + 4;break;case 0xd0:key_value = key_value + 8;break;case 0xe0:key_value = key_value + 12;break;}while (KEY_MATRIX_PORT != 0xf0); // 等待按键松开}}elsekey_value = 0;return key_value;
}void main()
{u8 key = 0;while (1){key = key_matrix_ranks_scan();if (key != 0)SMG_A_DP_PORT = gsmg_code[key - 1]; // 得到的按键值减1换算成数组下标对应0-F段码}
}

编译和结果

按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机

结果:按下S1-S16键,对应数码管最左边显示0-F
在这里插入图片描述

相关文章:

嵌入式开发学习(STC51-7-矩阵按键)

内容 按下S1-S16键,对应数码管最左边显示0-F 矩阵按键简介 独立按键与单片机连接时,每一个按键都需要单片机的一个I/O 口,若某单片机系统需较多按键,如果用独立按键便会占用过多的I/O口资源;而单片机 系统中I/O口资…...

WMS仓储管理系统的价值从哪些方面体现

仓库管理在不断改善,采用信息化来管理仓库。自从使用了WMS仓储管理系统解决方案后,仓库管理的效率大大提高了,而且WMS系统有很多价值。 首先,WMS系统可以帮助员工更省时省力地完成仓库管理工作,提高效率和准确性。传统…...

网站推荐第二期-沉浸式网页翻译

通过在浏览器上安装插件形式实现,接入多方翻译接口,实现全平台翻译功能,甚至可以使用openai的chatgpt,效率倍增。 不仅可以双语阅读网页,甚至pdf也支持翻译。 推荐网址如下: 双语网页翻译 - 电子书翻译 …...

【独立后台】快递小程序便宜寄快递系统小程序 对接易达

快递代发项目简介: 顾名思义就是帮发快递。原本产业链是客户-快递之间的联系,现在变成了客户-我们-快递,简单来说就是我们把客户聚集到一起团购到了更优惠的价格。很简单就是赚一个差价, 单子多就能和各个快递合作的平台&#x…...

【JVM】垃圾回收 ——自问自答2

Q: System.gc() 的理解 System.gc()底层调用的是 Runtime.getRuntime.gc(),会现实出发FullGC。 但是,它的调用附带一个免责声明,无法保证对垃圾收集器的调用。 Q: 内存溢出和内存泄漏? 内存溢出: 简而言之&#xf…...

MySQL数据库数据类型

MySQL数据库数据类型分类 在MySQL数据库中,MySQL数据类型分有四大类:数值类型、文本/二进制类型、时间日期和String类型。以下是这四大类的具体类型: 数值类型 数值类型的范围和字节大小: tinyint类型 tinyint类型只有一个字节…...

【力扣】27. 移除元素 <快慢指针、首尾指针>

【力扣】27. 移除元素 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,必须仅使用 O(1) 额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超…...

【每日一题】—— C. Challenging Cliffs(Codeforces Round 726 (Div. 2))

🌏博客主页:PH_modest的博客主页 🚩当前专栏:每日一题 💌其他专栏: 🔴 每日反刍 🟡 C跬步积累 🟢 C语言跬步积累 🌈座右铭:广积粮,缓称…...

想在金融界拥有一席之地吗—社科院杜兰大学金融管理硕士助你圆梦

追求高学历是为了什么?一纸证书吗?显然并非如此,只有读过研的人才有话语权。在上升一个平台后,你必然会发现,更高学历得到的不止是一张文凭。而是更大的平台、更广阔的视野、更包容的环境,更多样的文化。最…...

Moonbeam与Nodle网络集成,增添物联网功能

领先的波卡跨链互连开发平台Moonbeam近期宣布与Nodle Network达成XCM集成,将NODL Token带到Moonbeam生态之中。本次集成将会开启波卡中Moonbeam和Nodle网络以及通过Moonbeam互连合约相连的远程链之间的流动性。 Nodle网络是一个为物联网(Internet of Th…...

关于docker 在ubuntu16.04 上的安装

https://www.sohu.com/a/708313241_121368355 参考教程: https://www.runoob.com/docker/docker-image-usage.html 镜像网址 https://hub.docker.com/...

Cmder启动加速

Cmder是一个比较好用的命令行工具,可以通过修改默认Git地址提高启动速度: 打开vendor/init.bat添加本机Git地址,并且打开启动时间显示 :: Use /v command line arg or set to > 0 for verbose output to aid in debugging. set GIT_INSTA…...

【windows】windows上如何使用linux命令?

前言 windows上的bat命令感觉不方便,想在windows上使用linux命令。 有人提供了轮子,本文简单介绍一些该轮子的安装与使用,希望能够帮助到和我有一起需求的网友。 我的答案是busybox。 1.安装busybox.exe 在这个网站上安装busybox busyb…...

Docker Compose: 集合管理Docker的工具安装

Docker Compose:集合管理多个Docker容器的工具,在安装docker时windows,macos默认安装Docker Compose,linux需要自己手动安装 去官网https://github.com/docker/compose/releases下载需要的版本$ sudo chmod x ./docker-compose-linux-x86_64$ sudo cp .…...

Jmeter(三) - 从入门到精通 - 测试计划(Test Plan)的元件(详解教程)

1.简介 上一篇中已经教你如何通过JMeter来创建一个测试计划(Test Plan),那么这一篇我们就将JMeter启动起来,创建一个测试计划(Test plan),然后给大家介绍一下测试计划(Test Plan&am…...

20天学会rust(一)和rust say hi

关注我,学习Rust不迷路 工欲善其事,必先利其器。第一节我们先来配置rust需要的环境和安装趁手的工具,然后写一个简单的小程序。 安装 Rust环境 Rust 官方有提供一个叫做 rustup 的工具,专门用于 rust 版本的管理,网…...

嵌入式传感器将是未来智能交通发展的关键

随着移动即服务(MaaS)被视为智能移动的关键要素,对增长至关重要的一大因素是机器人车辆技术,而机器人技术又将高度依赖嵌入式传感器。 在这种情况下,高端传感器技术和原始计算能力将成为持续不断的市场扰乱的核心&…...

Vue3 实现产品图片放大器

Vue3 实现类似淘宝、京东产品详情图片放大器功能 环境&#xff1a;vue3tsvite 1.创建picShow.vue组件 <script lang"ts" setup> import {ref, computed} from vue import {useMouseInElement} from vueuse/core/*获取父组件的传值*/ defineProps<{images:…...

机器学习笔记 - 使用 YOLOv5、O​​penCV、Python 和 C++ 检测物体

一、YOLO v5简述 YOLO v5虽然已经不是最先进的对象检测器,但是YOLOv5 使用了一个简单的卷积神经网络 CNN架构(相对YOLO v8来讲,不过v8精度是更高了一些),更易理解。这里主要介绍如何轻松使用 YOLO v5来识别图像中的对象。将使用 OpenCV、Python 和 C++ 来加载和调用我们的…...

使用手机相机检测电脑屏幕刷新率Hz

使用手机相机检测电脑屏幕刷新率Hz 1、电脑打开https://www.testufo.com/frameskipping 2、相机专业模式&#xff1a;快门1/10、ISO自动&#xff0c;拍摄一张照片。120Hz至少要有12个亮块&#xff0c;50Hz至少有6个亮块。 更改刷新速率 1、选择 “开始>设置>系统>显示…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...