【单片机/普中A2】学习笔记5-矩阵键盘
2023-09-14 09:13:57 时间
矩阵键盘原理
参考文献:点击前往
扫描模式
数码管扫描:输出扫描的一种,以人类肉眼无法分辨的速度进行扫描,呈现出同时显示的假象
矩阵键盘扫描:输入扫描的一种,高速逐行扫描,获取按键按下位置;目前的电脑显示器也是使用此方法检测,可以极大地压缩引脚数量(譬如 1920x1080,仅需引脚:1920+1080=3000)
实例展示
检测单点按键
首先我们来看一下检测按键的核心代码
代码清单 MatrixKey.c
#include <REGX52.H>
#include "Delay.h"
/**
* @brief 矩阵键盘读取按键键码
* @param 无
* @retval KeyNumber 按下按键的键码值
如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0
*/
unsigned char MatrixKey()
{
// 当前点击的按键
unsigned char KeyNumber=0;
// 第一步:全局置1,即全部上拉
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;
}
别忘了头文件 MatrixKey.h
#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__
unsigned char MatrixKey();
#endif
之后总结我们之前的 Delay 和 LCD1602 模块,不难得出以下代码
代码清单 main.c
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"
unsigned char KeyNum;
void main(){
LCD_Init(); //LCD初始化
LCD_ShowString(1,1,"MatrixKey:"); //LCD显示字符串
while(1)
{
KeyNum=MatrixKey(); //获取矩阵键盘键码
if(KeyNum) //如果有按键按下
{
LCD_ShowNum(2,1,KeyNum,2); //LCD显示键码
}
}
}
密码锁
仅需修改源文件即可
代码清单 main.c
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"
// 按键作用: S1~S9 设置数字为 1~9, S10定义为数字0, S11用作于是确认按键, S12用作于是取消按键 《《《 S13~S16,我们不去进行使用
unsigned char KeyNum; // 全局变量初始化默认为:0
unsigned int Password,Count; // 如果用6位数字的密码就会超出这个 unsigned int 的一个数值的范围了 0~65535, Count作用:计次,防止输入过多的密码
int main(void)
{
LCD_Init();
LCD_ShowString(1,1,"Password:");
while(1)
{
KeyNum=MatrixKey();
if(KeyNum)
{
if(KeyNum<=10) //如果S1~S10按键按下,输入密码
{
if(Count<4) //如果输入次数小于4
{
Password*=10; //密码左移一位 : Password = Password * 10
Password+=KeyNum%10; //获取一位密码 : Password = password + KeyNum % 10, 1~9取模10还是为原来的数字~ 获取密码用取模%运算符然后进行赋值
Count++; //计次加一
}
LCD_ShowNum(2,1,Password,4); //更新显示 0000 0000 输入第一次(1) 显示0001 》》》 0001 0010 输入第二次(2) 显示0012
}
if(KeyNum==11) //如果S11按键按下,确认 ----注意:这里不进行消抖的原因是:模块化编程的时候已经进行消抖了
{
if(Password==2345) //如果密码等于正确密码 --------------------------- 定义密码
{
LCD_ShowString(1,14,"OK "); // 显示OK
Password=0; // 密码清零
Count=0; // 计次清零
LCD_ShowNum(2,1,Password,4); // 更新显示
}
else //否则
{
LCD_ShowString(1,14,"ERR"); //显示ERR
Password=0; // 密码清零
Count=0; // 计次清零
LCD_ShowNum(2,1,Password,4); //更新显示
}
}
if(KeyNum==12) //如果S12按键按下,取消
{
Password=0; // 密码清零
Count=0; // 计次清零
LCD_ShowNum(2,1,Password,4); //更新显示
}
}
}
}
相关文章
- 求介绍一款高效记录笔记的手机应用
- python字符串格式化之学习笔记
- redis 学习笔记三(队列功能)
- [Spring学习笔记 3 ] spring 注解详解,完全注解,常用注解
- Nodejs学习笔记
- Opencv学习笔记 - 使用opencvsharp和Boosting算法处理分类问题
- 机器学习笔记 - 在QT/PyTorch/C++ 中加载 TORCHSCRIPT 模型
- Java多线程学习笔记 - 七、Java中的线程同步
- Android开发学习笔记(二)Activity的生命周期
- weka学习入门笔记
- Spartacussampledataaddon AddOn学习笔记
- Java 8里的Predicate学习笔记
- SAP Fiori后台开发的一些学习笔记
- 2021-10-28 SAP Spartacus SSR 性能方面的一些学习笔记
- 【MyBatis笔记01】MyBatis框架介绍以及开发环境搭建
- 改善C#程序的157建议——建议42学习笔记:使用泛型参数兼容泛型接口的不可变性。
- linux学习笔记1(基本命令)
- Vue3学习笔记(五)——路由,Router
- python基础===requests学习笔记
- pygame学习笔记(4)——声音
- RFSoC应用笔记 - RF数据转换器 -04- RFSoC关键配置之RF-ADC内部解析(二)
- C# 语言程序设计笔记
- 408笔记1
- JavaEE——Spring学习笔记01【Ioc开发的模式】
- 【ORACLE性能分析和优化思路学习笔记02:什么时候需要对性能进行干预】
- 西瓜书学习笔记第5章【神经网络】
- 强化学习笔记:Sutton-Book第三章小结
- 【硬件架构的艺术】学习笔记(2)同步和复位