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

51单片机学习——矩阵按键

目录

gitee链接   小程吃饭饭 (xiaocheng-has-a-meal) - Gitee.comicon-default.png?t=N7T8https://gitee.com/xiaocheng-has-a-meal

1.图~突突突突突

矩阵键盘原理图

矩阵键盘的实物图

2.矩阵键盘

引入~啦啦啦啦啦

原理~沥沥沥沥沥

    代码~嗷嗷嗷嗷嗷

【1】延时函数

【2】 LCD1602

 【3】检测按键函数Matrix 

【4】主函数 

3.是图像啦 

 

4.你的阿锦啊 


     昨天没写博客,在摆烂,本来还想摆烂,最近心情可不好,好多东西缠在一起,捆住了该走的和不该走的。好怀念过去啊~~

 

1.图~突突突突突

矩阵键盘原理图

矩阵键盘的实物图

这是两个很好看的图, 一个是矩阵键盘原理图,一个是矩阵键盘,下面开始将原理

2.矩阵键盘

引入~啦啦啦啦啦

 小程看了矩阵按键后非常疑惑,为什么键盘要这么搞,直接都弄成按独立键键盘不香吗?独立按键与单片机连接时,每个按键都需要单片机的一个I/O口,但是单片机的I/O口是有限的啊,如果每个按键都要一个口的话,假如我们需要多个按键来实现功能的话,51单片机就32个I/O口,怎么够用呢?

  所以为了节省单片机的I/O口,我们引入矩阵键盘

原理~沥沥沥沥沥

     下面我们来看矩阵键盘的工作原理,其实无论是矩阵键盘还是独立键盘,我们都是通过检测与键盘对应的I/O口是否为低电平。但是我们知道,独立按键是有一端是接地的,但是矩阵键盘两边都接在I/O口上,因此检测时需要人为通过单片机I/O口输出低电平。检测时,可以通过让一行为确定一列,检测一行按键。先送一行为低电平,然后迅速轮流扫描一次各行是否变为低电平,这样我们既确定了列线,又确定了行线,就确定了这个按键。当然,在我们搞这个的时候,也不能忘记按键消抖。

     当然检测这个有多个方式,这里我们可以采取逐行或者逐列来进行检测。  

    代码~嗷嗷嗷嗷嗷

可以去我的gitee直接获得全套,纯开源

https://gitee.com/xiaocheng-has-a-meal/return-to-its-original-form

【1】延时函数

//头文件
#ifndef ___H__
#define ___H__
void Delay( int x);#endif
#include<INTRINS.H>//延时1ms
void Delay( int x)	//11.0592MHz
{unsigned char data i, j;while(x){_nop_();i = 2;j = 199;do{while (--j);} while (--i);x--;}
}

【2】 LCD1602

#ifndef __LCD1602_H__
#define __LCD1602_H__//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);#endif
#include <REGX52.H>//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0//函数定义:
/*** @brief  LCD1602延时函数,12MHz调用可延时1ms* @param  无* @retval 无*/
void LCD_Delay()//11.0592MHz的延时1ms的延时函数
{unsigned char data i, j;i = 2;j = 199;do{while (--j);} while (--i);
}/*** @brief  LCD1602写命令* @param  Command 要写入的命令* @retval 无*/
void LCD_WriteCommand(unsigned char Command)
{LCD_RS=0;LCD_RW=0;LCD_DataPort=Command;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief  LCD1602写数据* @param  Data 要写入的数据* @retval 无*/
void LCD_WriteData(unsigned char Data)
{LCD_RS=1;LCD_RW=0;LCD_DataPort=Data;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief  LCD1602设置光标位置* @param  Line 行位置,范围:1~2* @param  Column 列位置,范围:1~16* @retval 无*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{if(Line==1){LCD_WriteCommand(0x80|(Column-1));}else if(Line==2){LCD_WriteCommand(0x80|(Column-1+0x40));}
}/*** @brief  LCD1602初始化函数* @param  无* @retval 无*/
void LCD_Init()
{LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动LCD_WriteCommand(0x01);//光标复位,清屏
}/*** @brief  在LCD1602指定位置上显示一个字符* @param  Line 行位置,范围:1~2* @param  Column 列位置,范围:1~16* @param  Char 要显示的字符* @retval 无*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{LCD_SetCursor(Line,Column);LCD_WriteData(Char);
}/*** @brief  在LCD1602指定位置开始显示所给字符串* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  String 要显示的字符串* @retval 无*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++){LCD_WriteData(String[i]);}
}/*** @brief  返回值=X的Y次方*/
int LCD_Pow(int X,int Y)
{unsigned char i;int Result=1;for(i=0;i<Y;i++){Result*=X;}return Result;
}/*** @brief  在LCD1602指定位置开始显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:0~65535* @param  Length 要显示数字的长度,范围:1~5* @retval 无*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');}
}/*** @brief  在LCD1602指定位置开始以有符号十进制显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:-32768~32767* @param  Length 要显示数字的长度,范围:1~5* @retval 无*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{unsigned char i;unsigned int Number1;LCD_SetCursor(Line,Column);if(Number>=0){LCD_WriteData('+');Number1=Number;}else{LCD_WriteData('-');Number1=-Number;}for(i=Length;i>0;i--){LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');}
}/*** @brief  在LCD1602指定位置开始以十六进制显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:0~0xFFFF* @param  Length 要显示数字的长度,范围:1~4* @retval 无*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i,SingleNumber;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){SingleNumber=Number/LCD_Pow(16,i-1)%16;if(SingleNumber<10){LCD_WriteData(SingleNumber+'0');}else{LCD_WriteData(SingleNumber-10+'A');}}
}/*** @brief  在LCD1602指定位置开始以二进制显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:0~1111 1111 1111 1111* @param  Length 要显示数字的长度,范围:1~16* @retval 无*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');}
}

 【3】检测按键函数Matrix 

#ifndef __Matrix_H__
#define __Matrix_H__unsigned char matrix();#endif
#include <REGX52.H>
#include <Delay.H>
unsigned char matrix()
{unsigned char Keynumber = 0;/*P1_7那行输入低电平检测*/P1 = 0xFF;P1_7 = 0;if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);Keynumber = 1;}if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);Keynumber = 2;}if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);Keynumber = 3;}if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);Keynumber = 4;}/*P1_6那行输入低电平检测*/P1 = 0xFF;P1_6 = 0;if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);Keynumber = 5;}if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);Keynumber = 6;}if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);Keynumber = 7;}if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);Keynumber = 8;}/*P1_5那行输入低电平检测*/P1 = 0xFF;P1_5 = 0;if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);Keynumber = 9;}if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);Keynumber = 10;}if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);Keynumber = 11;}if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);Keynumber = 12;}/*P1_4那行输入低电平检测*/P1 = 0xFF;P1_4 = 0;if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);Keynumber = 13;}if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);Keynumber = 14;}if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);Keynumber = 15;}if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);Keynumber = 16;}return Keynumber;}

【4】主函数 

 

#include <REGX52.H>
#include "Delay.H"
#include "LCD1602.H"
#include "Matrix.H"
unsigned char KeyNumber = 0;void main()
{LCD_Init();while(1){KeyNumber = Matrix();if(KeyNumber){LCD_ShowNum(1,1,KeyNumber,2);}}
}  

以上便是这个工程所有的代码 

3.是图像啦 

我按下了按键05,单片机显示图像如下

 

嘎嘎准,这里我就提供一种方法啦!!! 

4.你的阿锦啊 

    面对苦难,人们往往会被打倒,但如果你坚持下去,苦难最终会给你带来回报。这种回报不一定是物质的,更多的是精神的。它会使你更加坚强,更加成熟。

 

 

 

 

 

相关文章:

51单片机学习——矩阵按键

目录 gitee链接 小程吃饭饭 (xiaocheng-has-a-meal) - Gitee.comhttps://gitee.com/xiaocheng-has-a-meal 1.图~突突突突突 矩阵键盘原理图 矩阵键盘的实物图 2.矩阵键盘 引入~啦啦啦啦啦 原理~沥沥沥沥沥 代码~嗷嗷嗷嗷嗷 【1】延时函数 【2】 LCD1602 【3】检测按…...

重写Sylar基于协程的服务器(1、日志模块的架构)

重写Sylar基于协程的服务器&#xff08;1、日志模块的架构&#xff09; 重写Sylar基于协程的服务器系列&#xff1a; 重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 重写Sylar基于协程的服务器&#xff08;1、日志模…...

ElementUI Form:Radio 单选框

ElementUI安装与使用指南 Radio 单选框 点击下载learnelementuispringboot项目源码 效果图 el-radio.vue &#xff08;Radio 单选框&#xff09;页面效果图 项目里el-radio.vue代码 <script> export default {name: el_radio,data() {return {radio: 1,radio2: 2,ra…...

react-activation实现缓存,且部分页面刷新缓存,清除缓存

1.安装依赖 npm i -S react-activation2.使用AliveScope 包裹根组件 import { AliveScope } from "react-activation" <AliveScope><Router><Switch><Route exact path"/" render{() > <Redirect to"/login" push …...

idea 中 tomcat 乱码问题修复

之前是修改 Tomcat 目录下 conf/logging.properties 的配置&#xff0c;将 UTF-8 修改为 GBK&#xff0c;现在发现不用这样修改了。只需要修改 IDEA 中 Tomcat 的配置就可以了。 修改IDEA中Tomcat的配置&#xff1a;添加-Dfile.encodingUTF-8 本文结束...

Modbus协议学习第七篇之libmodbus库API介绍(modbus_write_bits等)

写在前面 在第六篇中我们介绍了基于libmodbus库的演示代码&#xff0c;那本篇博客就详细介绍一下第六篇的代码中使用的基于该库的API函数。另各位读者&#xff0c;Modbus相关知识受众较少&#xff0c;如果觉得我的专栏文章有帮助&#xff0c;请一定点个赞&#xff0c;在此跪谢&…...

第九节HarmonyOS 常用基础组件13-TimePicker

1、描述 时间选择组件&#xff0c;根据指定参数创建选择器&#xff0c;支持选择小时以及分钟。默认以24小时的时间区间创建滑动选择器。 2、接口 TimePicker(options?: {selected?: Date}) 3、参数 selected - Date - 设置选中项的时间。默认是系统当前的时间。 4、属性…...

力扣刷题-55.跳跃游戏

给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 class Solution { publ…...

Ruby安装演示教程

安装 Ruby 的过程会根据您的操作系统&#xff08;如 Windows、MacOS、Linux&#xff09;而有所不同。以下是在这些主要平台上安装 Ruby 的基本指南。 在 Windows 上安装 Ruby 下载 Ruby Installer&#xff1a;访问 RubyInstaller 官方网站下载适合您系统的 Ruby Installer 版…...

前端使用vue-simple-uploader进行分片上传

目录 一、安装vue-simple-uploader 二、在vue中使用 一、安装vue-simple-uploader npm install vue-simple-uploader --save main.js初始化vue-simple-uploader import uploader from vue-simple-uploaderVue.use(uploader) common/config文件 export const ACCEPT_CONF…...

Java 源代码中常见的数据类型

在Java源代码中&#xff0c;常见的数据类型包括基本数据类型&#xff08;Primitive Data Types&#xff09;和引用数据类型&#xff08;Reference Data Types&#xff09;。这些数据类型在Java中用于存储不同种类的数据&#xff0c;如整数、小数、字符、布尔值以及对象等。 1.…...

Web3行业研究逐步加强,“链上数据”缘何成为关注焦点?

据中国电子报报道&#xff0c;近日&#xff0c;由中关村区块链产业联盟指导&#xff0c;中国信息通信研究院牵头&#xff0c;欧科云链控股有限公司参与编写的《全球Web3产业全景与发展趋势研究报告&#xff08;2023年&#xff09;》正式发布。研究报告通过全面追踪国内外Web3产…...

逸学区块链【solidity】真随机数

参考Get a Random Number | Chainlink Documentation 但是很贵&#xff0c;价格 Gas Price&#xff1a;当前gas价格&#xff0c;根据网络状况而波动。Callback gas &#xff1a;返回您所请求的随机值时&#xff0c;回调请求消耗的gas 量。验证gas &#xff1a;量gas 用于验证…...

【WPF.NET开发】优化性能:对象行为

本文内容 不删除对象的事件处理程序可能会使对象保持活动状态依赖属性和对象Freezable 对象用户界面虚拟化 了解 WPF 对象的内部行为有助于在功能和性能之间做出适当的取舍。 1、不删除对象的事件处理程序可能会使对象保持活动状态 对象传递给其事件的委托是对该对象的有效…...

uniapp中封装一个svg转base64的组件

uniapp中由于不支持svg--》base64&#xff0c;同时无法使用h5中atob&#xff0c;这里我们采用js-base64插件实现这样一个组件&#xff0c;只要传人svg的代码即可在uniapp中转为base64&#xff0c;同时支持自定义参数&#xff0c;比如宽度&#xff0c;高度,等 1 安装 npm inst…...

QT播放gstreamer命令(三)---使用QMediaPlayer

前文&#xff1a; 因为之前听说过&#xff0c;QMediaPlayer已经集成了gstreamer&#xff0c;但是并没有什么接口来例子来说明&#xff0c;根本看不出来有任何gstreamer的形式&#xff0c;于是在QT5助手里面搜了一下&#xff0c;发现确实有gstreamer的痕迹&#xff0c;但是例子写…...

Ubuntu22扩大分区

一台Ubuntu一直以为扩展成功了的&#xff0c;但是用起来空间不够&#xff0c;才发现空间还是那么小&#xff0c;所以赶快想办法扩展。 首先尝试使用gparted软件&#xff0c;结果在软件里面发现硬盘分区/dev/sda3已经全分配78G了。 但是看df -H&#xff0c;明明没有扩展: /dev…...

数据结构篇-05:哈希表解决字母异位词分组

本文对应力扣高频100 ——49、字母异位词分组 哈希表最大的特点就是它可以把搜索元素的时间复杂度降到O(1)。这一题就是要我们找到 “字母异位词” 并把它们放在一起。 “字母异位词”就是同一个单词中字母的不同组合形式。判断“字母异位词”有两个视角&#xff1a;1、所含字…...

添加了gateway之后远程调用失败

前端提示500&#xff0c;后端提示[400 ] during [GET] to [http://userservice/user/1] 原因是这个&#xff0c;因为在请求地址写了两个参数&#xff0c;实际上只传了一个参数 解决方案&#xff1a;加上(required false)并重启所有相关服务...

C#,哥伦布数(Golomb Number)的算法与源代码

1 哥伦布数&#xff08;Golomb Number&#xff09; 哥伦布数&#xff08;Golomb Number&#xff09;是一个自然数的非减量序列&#xff0c;使得n在序列中正好出现G&#xff08;n&#xff09;次。前几个15的G&#xff08;n&#xff09;值为&#xff1a;1 2 2 3 3 4 4 4 5 5 5 6…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...