首页 > 其他分享 >C51--06---矩阵键盘

C51--06---矩阵键盘

时间:2025-01-10 10:54:30浏览次数:1  
标签:P1 06 C51 -- 扫描 Delay while KeyNumber 20

一、矩阵键盘

1.定义:

4X4 16个按键组成,以矩阵的方式进行连接,叫做矩阵键盘;

2.优势

将按键排列成矩阵形式,两端都接在I/O口上,可以减少I/O口的占用;

注: 独立按键的模式,将一端集中接在GND上,另一端单独引出一个I/O口,这样当按键比较多时,就会占用很多I/O口;

3.读取方式

采用逐行、逐列的“扫描”,就可以读出任何位置按键的状态。

二、扫描的概念

1.数码管扫描(输出扫描)

  • 原理:
    显示 第一位--第二位--第三位--.... 快速循环此过程,
    由于MCU速度非常快 利用余晖和人眼视觉差 达到所有数码管同时显示的错觉。

    输出扫描:
     数码管:MCU I/O口 一直向数码管 输出数据  然后不断进行扫描 显示
    

2.矩阵按键扫描(输入扫描)

  • 原理:
    读取 第一行(列)--第二行(列)--第三行(列)--.... 快速循环此过程,
    由于MCU速度非常快 最终实现所有按键同时检测的效果。

    输入扫描:
     矩阵按键:按键值一直更新状态 向MCU输入数据 即MCU I/O口 不断读取矩阵按键的状态,MCU根据返回的数据 进行相应 的另外外设的操作。
    

3.扫描的目的:为了节省I/O口

  扫描很广泛的应用于 显示器 扫描,例如1920X1080  采用矩阵扫描的方式,只需要1920+1080个IO口即可 非常节省I/O口

三、单片机扫描矩阵键盘的两种方式

1.逐行扫描

逐行扫描示意图:

 ---P14-P17 扫描哪行 就赋值0 (P17-P14 逐行赋值0)
 ---然后顺序读取P10-P13的状态,0表示按下  1表示未按下 
 ---逐行循环前两个操作 完成逐行扫描

 注:一次只能扫描一行(列)不可同时赋值0

2.逐列扫描

逐列扫描示意图:

    ---P10-P13 轮流进行列扫描
    ---然后顺序读取P14-P17的状态,0表示按下  1表示未按下 
    ---逐行循环前两个操作 完成逐列扫描

    注:一次只能扫描一行(列)不可同时赋值0

```
 本开发板问题:P15口连接了蜂鸣器  在逐行扫描的过程中由于引脚冲突,蜂鸣器会一直响 而且关不掉,所以此次选择逐列扫描。
```

四、实例1:读取矩阵键盘的键码值

1、矩阵扫描函数

点击查看代码
#include <REGX52.H>
#include "Delay.h"

/**
  * @brief  读取 矩阵按键 键码值 (逐列扫描)
  * @param  无
  * @retval KeyNumber
  * 如果按下不放 就会一直在此函数循环  放开按键 会返回键码值 如果没有按下任何按键 则返回0;
  */
 unsigned int MatrixKey()
{
  unsigned int KeyNumber=0;
	
	P1=0xFF; //将P1 I/O 初始化  “1 无效 0有效”
	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 I/O 初始化  “1 无效 0有效”
	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 I/O 初始化  “1 无效 0有效”
	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 I/O 初始化  “1 无效 0有效”
	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;  //一定要将键码值返回

}

2、键码值读取显示函数

点击查看代码
#include <REGX52.H>
#include "MatrixKey.h"
#include "LCD1602.h"
unsigned int MatrixNum;
void main()
{
	
	LCD_Init();
	LCD_ShowString(1,1,"MatrixKey:");
	while(1)
	{
		MatrixNum=MatrixKey();
		if(MatrixNum)   //如果不对其进行判断,会一直扫描 这样00也会一直显示 由于扫描速度过快  就会看不到效果
    {
		 LCD_ShowNum(2,1,MatrixNum,2);
		
		}
	}
}

五、实例2:矩阵键盘密码锁

main函数中:逻辑代码

点击查看代码
#include <REGX52.H>
#include "MatrixKey.h"
#include "LCD1602.h"
unsigned int MatrixNum;
unsigned int PassWord;
unsigned int PassWord_Right=1108;
unsigned char Count;
void main()
{
	
	LCD_Init();
	LCD_ShowString(1,1,"PassWord:");
	while(1)
	{
		MatrixNum=MatrixKey();
		if(MatrixNum)   //如果不对其进行判断,会一直扫描 这样00也会一直显示 由于扫描速度过快  就会看不到效果
    {
		
			//密码区键值设置:实现密码输入
		 if(MatrixNum<=10){
			 if(Count<4)   //限制密码个数为4个
				{
					PassWord=PassWord*10+ MatrixNum%10;  //显示4位密码
			    LCD_ShowNum(2,1,PassWord,4);
					Count++;
				}
			  
		 }
		 
		 // OK键 功能实现:判断密码是否正确 并作出反应
		 
		 if(MatrixNum==11){
		    if(PassWord==PassWord_Right)
				{
				LCD_ShowString(1,14,"OK ");
				}
				else
				{
				LCD_ShowString(1,14,"ERR");
				}
				Count=0;
				PassWord=0;
				LCD_ShowNum(2,1,PassWord,4);
		 
		 }
		 
		 // 取消键 实现数据清零
		 if(MatrixNum==12){
		    Count=0;
				PassWord=0;
				LCD_ShowNum(2,1,PassWord,4);
			  LCD_ShowString(1,14,"   ");
		 }
		 
		}
	}
}

六、补充知识:单片机I/O口

1、单片机I/O口的工作模式:

(1) 准双向口/弱上拉

准双向口/弱上拉模式:
  
    不需要重新配置I/O口的输出状态,就可以控制输入输出状态的切换;
    因为0 低电平的驱动比较强   1 高电平的驱动能力比较弱,如果外部不干预,输出为1时,就是1所对应的状态(输出模式);
    但如果想改变为0对应的状态 此时我们并不需要重新更改I/O的值,而是直接使用外部装置 就可以将其拉低 变为0(此时相当于输入模式)。

注意:独立按键: 接到低电平上 检测0;而非接到高电平 检测1;原因就是:单片机是弱上拉模式

如下图:

内部接高电平  但当外部接地时,此时如果I/O口去进行读数据 那此时读取的是0 而非1 (内部高电平弱)

注:

    本开发板 P1/P2/P3 都是弱上拉的工作模式 P0接了一个电阻 也可以看做弱上拉模式;
    MCU I/O口: 双向口输出配置 ,同一个I/O 口既可以读出数据,也可以写入数据;

(2) 仅为输入(高阻)

(3) 开漏输出

七、配置固定模版代码

标签:P1,06,C51,--,扫描,Delay,while,KeyNumber,20
From: https://www.cnblogs.com/xff1218/p/18660139

相关文章

  • 快读快写
    源码此处展示的是2.0版本源码:template<typenameTp>inlinevoidread(Tp&x){x=0;registerboolz=true;registerchara=getchar_unlocked();for(;!isdigit(a);a=getchar_unlocked())if(a=='-')z=false;for(;isdigit(a);a=getchar_unlocked())x=(x<......
  • 2025 年,程序员如何找准技术“掘金点”?
    大家好,我是V哥,最近有很多小伙伴来问V哥,悲催的2024终于过去了,有的早早就给自己放假等春节了,有的也没逃过临了被约喝咖啡☕️,都想着先过完年再考虑怎么办,躺平可不行,又有谁会跟钱过不支呢。2025年,V哥也跟一些行业大佬聊过,共同的一个点就是市场经济依然不会好转,是不是心跟V哥一样,......
  • 【YashanDB知识库】审计表UNIFIED_AUDIT_TRAIL出现YAS-00220 utf8 sequence is wrong
    【问题分类】功能使用【关键字】UNIFIED_AUDIT_TRAIL,YAS-00220【问题描述】当审计对象的SQL语句包含非标准中文字符时,出现YAS-00220utf8sequenceiswrong,影响审计记录。--第一步:打开审计开关SQL>ALTERSYSTEMSETUNIFIED_AUDITING=true;Succeed.--创建审计......
  • 如何把电脑上文件云存储,把电脑上文件云存储的方法
    怎么把电脑上的文件云存储呢?在私有云存储中,设置文件自动同步是最简单的方法。在私有云环境中进行文件同步备份是确保数据安全、便捷访问和管理的重要手段。通过将文件同步到私有云服务器,用户可以在多个设备间实时同步文件,同时确保备份的数据不会丢失。下面是如何在私有云电脑上实......
  • python激活venv做了什么
    当激活Python的虚拟环境(venv)时,激活脚本会对系统环境进行一系列临时修改,让终端的Python和相关工具使用虚拟环境中的版本和依赖。这些操作不会永久改变系统环境,只在当前终端会话中生效。激活虚拟环境的操作详解1.修改PATH环境变量激活脚本会将虚拟环境的bin(Linux/MacOS......
  • Hyperledger Fabric v2.5.8 Endorsement failure
    2025-01-0916:47:36.545UTC016aWARN[vscc]Validate->Endorsmentpolicyfailureerror="validationofendorsementpolicyforchaincodefabcarintx12:0failed:implicitpolicyevaluationfailed-1sub-policiesweresatisfied,butthispolicyr......
  • cv::reprojectImageTo3D 使用
    cv::reprojectImageTo3D是OpenCV中的一个函数,用于将视差图像转换为3D点云。它依赖于相机的内参和视差值来计算每个像素的3D坐标。以下是该函数的基本使用方法。函数原型voidcv::reprojectImageTo3D(constcv::Mat&disparity,cv::Mat&_3dImage,constcv......
  • SQLSER中使用DATALENGTH 函数返回字符串的字节长度
    DATALENGTH函数返回字符串的字节长度,这对于varchar类型的字段非常有用,因为varchar类型的字段存储的是变长字符串,其实际占用的字节数可能小于定义的最大长度。示例假设有一个表Articles,其中有一个varchar类型的字段Content,你想查询每篇文章内容的实际占用字节数,可以使用......
  • 新版 Cursor 把其他 AI 编程工具按在地上摩擦了!
    大家好,我是汤师爷~AI编程助手Cursor背后的Anysphere公司刚刚完成了1亿美元的B轮融资,估值直接飙升至26亿美元。四个月前,这家公司刚拿下6000万美元,估值还只有4亿美元。如今,增长6.5倍,这速度,简直让人怀疑开挂了。Anysphere不仅融资拿到手软,收入增长更是逆天。公司从4月的年收入400......
  • 【YashanDB知识库】kettle做增量同步,出现报错:Unrecognized VM option 'MaxPermSize-25
    本文内容来自YashanDB官网,原文内容请见https://www.yashandb.com/newsinfo/7863039.html?templateId=1718516问题现象kettle在增量同步过程,出现报错:UnrecognizedVMoption'MaxPermSize=256m'问题的风险及影响无法使用kettle做增量同步,导致迁移进度会有所影响问题影响的版......