汇总:本文将带您详细介绍矩阵键盘的工作原理

电脑杂谈  发布时间:2020-12-09 10:01:13  来源:网络整理

简述行列式扫描键盘的工作原理_简述行列式扫描键盘的工作原理

矩阵键盘应该是一种可以经常使用的设备。 4X4矩阵键盘只需要8个IO端口即可读取16位键。基本原理是扫描行和列。本文将带您详细学习矩阵键盘和代码编写的原理。

矩阵键盘的性质:

矩阵键盘的本质是使用8个io端口来控制和读取16个键,这可以减少io端口的使用。 4条I / O线用作行线,4条I / O线用作列线。组成键盘。在行线和列线的每个交叉点处,设置一个按钮。这种按钮中的按钮数是4 X 4。

这种确定性的键盘结构可以有效地提高微控制器系统中I / O端口的利用率。节省单片机的资源。其本质类似于独立密钥的本质。它是逐行扫描并逐列扫描,然后确定第一行和第一列中的哪个键,然后确定整体键值。收到我们使用的矩阵键盘。微控制器的P1端口可以通过读取P1端口的电平转换来读取矩阵键盘的值。具体原理图如下:

在这里插入图片描述

第一条线连接到p17,第二条线连接到p16,第三条线连接到p15,第四条线连接到p14

第一列连接到p13,第二列连接到p12,第三列连接到p11,第四列连接到p10

扫描矩阵键盘有两种方法:1.行和列扫描,2.行/列扫描

行和列扫描适用于连接到微控制器的8个连续IO端口的8个IO端口,然后可以执行行和列扫描。

逐行/列扫描适用于连接到任何IO端口的矩阵键盘,然后使用逐行和逐列扫描

接下来,我们将分别介绍这两种方法:

行和列扫描:

原理:

首先从端口P1的高四位(四行)输出高电平,然后从低四位(四列)输出低电平。假设按下了一个键,请从端口P1状态的高四位读取键盘。判断高四位的哪一行变为低电平,知道是哪一行,然后从P1端口的低四位(四列)输出高电平,并输出高四位(四行)低电平,从端口P1的低四位读取键盘状态。通过判断下面四列的哪一行已变低,您将知道它是哪一列。合并两个读取结果,以获取当前按钮的功能代码。通过以上方法,我们得到了16个按键的功能代码。

在这里插入图片描述

红色高电平,蓝色低电平

简述行列式扫描键盘的工作原理_简述行列式扫描键盘的工作原理

详细说明:

根据矩阵键盘的,如果矩阵键盘的8个IO端口连续连接到一个人P10-P17,则在不按任何键的情况下,将P1端口的P1 ^ 0和P13设置为P14和P17的高电平设置为低电平,即4行的IO端口设置为高电平,4列的IO端口设置为低电平。那就是P1 = 0x0f(0000 1111);

如果此时按任意键,则P1 ^ 0和P13之一将变为低电平。因此,P1的值不等于0x0f,并且按下按钮的行将变为低电平,这可以确定存在按下的按钮。

将对应的P1端口的值与0x0f(00001111)和&进行比较,可以得到高四位数字,并且前几行变为0

按位“与”&(双目运算符):仅当两个操作数均为1时,结果为1,否则为0。

例如:0&0 = 0; 0&1 = 0; 1&0 = 0; 1&1 = 1

即:两个同时为1,结果为1,否则为0

例如,按下的1x1的第一行和第一列

示例:

0000 1110 -------------按下1x1后的P1值

&0000 1111 ------------- 0x0f

----------

0000 1110 -------------最终结果,第一行为0

然后将0X0f分配给端口P1。将端口P1的P1 ^ 0和P13设置为低电平。将P14和P17设置为高电平,即将4个低IO端口设置为高电平,将4个列IO端口设置为高电平,然后读取低电平的4位,此时P1端口(1111 0000)

此时读取P1端口和0xf0(11110000)相位和&,您可以得到低四位数字,而前几列变为低电平

例如,我们按下1x1按钮,即第一行和第一列。这时,按下它后,您可以看到p 1. 0和p 1. 3都较低,并且Row = P1&0x0f;(行值)和Col = P1&0xf0; // column值相加了,你可以获得按下哪个按钮

简述行列式扫描键盘的工作原理_简述行列式扫描键盘的工作原理

1x1 :(一行一行)

行= P1&0x0f = 0000 1110

Col = P1&0xf0 = 1110 0000

Row + Col = 1110 1110 = 0xee

低级别0表示按下了相应的行和列。

您会看到下面的p 1. 0和p 1. 4变为低电平

在这里插入图片描述

2x2 :(两行两列)

行= P1&0x0f = 0000 1101

Col = P1&0xf0 = 1101 0000

Row + Col = 1101 1101 = 0xdd

3x4 :(三行四列)

行= P1&0x0f = 0000 1011

Col = P1&0xf0 = 0111 0000

Row + Col = 0111 1011 = 0x7b

通过这种方式,可以获得所有16个按钮的值。具体代码如下:

简述行列式扫描键盘的工作原理_简述行列式扫描键盘的工作原理

unsigned char keyscan(){
	unsigned char key,Row,Col;
	P1=0x0f;
	if(P1!=0x0f){
		delay(10);//去抖
		if(P1!=0x0f){
			Row=P1&0x0f;//确保端口值正确(行的值)
			P1=0xf0;
			Col=P1&0xf0;//列值
		}
		while((P1&0xf0)!=0xf0);//判断键是否抬起
	}
	switch(Row+Col){
		case 0xee:key=0;break;
		case 0xde:key=1;break;
		case 0xbe:key=2;break;
		case 0x7e:key=3;break;
		case 0xed:key=4;break;
		case 0xdd:key=5;break;
		case 0xbd:key=6;break;
		case 0x7d:key=7;break;
		case 0xeb:key=8;break;
		case 0xdb:key=9;break;
		case 0xbb:key=10;break;
		case 0x7b:key=11;break;
		case 0xe7:key=12;break;
		case 0xd7:key=13;break;
		case 0xb7:key=14;break;
		case 0x77:key=15;break;
	}
	return key;
}

运行效果图:

在这里插入图片描述

逐行/列扫描:

逐行扫描和逐列扫描的本质类似于行列扫描。本质是给某个行/某个列低级,而所有其他七个都为高级。这时,读取电平发生变化,有一个电平。当电平变低时,表示按下按钮并可以读取按钮数据。

例如,逐行扫描:

将第一行设置为低电平,其余的N-1行和N列为高电平,读取列线数据,列线为低电平表示该行有按键,例如为1行三列(1x3),则第三列的列线IO端口为低电平。将第二行设置为低电平,其余N-1行和N列为高电平,读取该列行数据,列线为低电平表示该行中有一个按钮被按下,以此类推,逐行扫描,根据行线和列线的级别,可以确定是否有按钮(n)根据键号跳转到相应的键处理程序。

以我们的P1端口为例:

首先,将P1 = 0xfe(1111 1110);分配给P1,此时P 1. 0为低电平,如果此时P 1. 1〜p 1. 7为高电平当按下按钮时有四列线,P 1. 4,P 1. 5,P 1. 6,P 1. 7且一列将变为低电平,因此,P1的值不等于设为0xfe,则可以判断为已按下按钮。

然后延迟一段时间以消除抖动,然后将0xfd(1111 1101)分配给P1,即P 1. 1为低电平,其他为高电平。 ,如果第1行上有P 1. P 1. 4,P 1. 5,P 1. 6,P 1. 7按下了按钮,则将显示低电平以确定按下哪个按钮;如果不是,则仅将0xfb(1111 1011)分配给P1,即P 1. 2为低电平,其他为高电平。使用相同的方法确定是否按下了按钮;··· ···依此类推,总共进行了四次检查。

例如,当在第一行中按下按钮时,P1的对应值为:

1X1(11101110 = 0xee)

1x2(11011110 = 0xde)

1X3(10111110 = 0xbe)

1X4(01111110 = 0x7e)

在第二行中按下按钮时对应的P1值:

简述行列式扫描键盘的工作原理_简述行列式扫描键盘的工作原理

2X1(11101101 = 0xed)

2x2(11011101 = 0xdd)

2X3(10111101 = 0xbd)

2X4(01111101 = 0x7d)

P1 ^ 2输出低电平,其他引脚输出高电平,即P1 = 0xfb,则当第三行中有按钮时,对应的P1值:

3X1(11101011 = 0xeb)

3x2(11011011 = 0xdb)

3X3(10111011 = 0xbb)

3X4(01111011 = 0x7b)

最后,第四行的相应值为:

4X1(11100111 = 0xe7)

4x2(11010111 = 0xd7)

4X3(10110111 = 0xb7)

4X4(01110111 = 0x77)

然后,我们终于可以获取代码:

/*****************************************************************************
** 函数名称:keyscan
** 功能描述:按键获取函数
******************************************************************************/
void keyscan(void)
{
	P1=0xfe;
   temp=P1;
   temp=temp&0xf0;
   if(temp!=0xf0)
   {
		delay(10);
      if(temp!=0xf0)
      {	
			temp=P1;
			switch(temp)
			{
				case 0xee:	key=0;break;
				case 0xde:	key=1;break;
				case 0xbe:	key=2;break;
				case 0x7e:	key=3;break;
         }
         while(temp!=0xf0) 
			{
				temp=P1;
				temp=temp&0xf0;				
         }		
		}
	}
	P1=0xfd;
	temp=P1;
	temp=temp&0xf0;
	if(temp!=0xf0)
	{
		delay(10);
		if(temp!=0xf0)
      {
			temp=P1;
			switch(temp)
			{
				case 0xed: 	key=4;break;
				case 0xdd:	key=5;break;
				case 0xbd:	key=6;break;
				case 0x7d:	key=7;break;
         }
         while(temp!=0xf0)
         {
           temp=P1;
           temp=temp&0xf0;
         }
      }
	}
	P1=0xfb;
	temp=P1;
	temp=temp&0xf0;
	if(temp!=0xf0)
	{
		delay(10);
      if(temp!=0xf0)
      {
			temp=P1;
			switch(temp)
			{
				case 0xeb:	key=8;break;
				case 0xdb:	key=9;break;
				case 0xbb:	key=10;break;
				case 0x7b:	key=11;break;				
         }
			beep=0;delay(50);beep=1;
			while(temp!=0xf0)
         {
				temp=P1;
				temp=temp&0xf0;
         }
      }
   }
	P1=0xf7;
   temp=P1;
   temp=temp&0xf0;
   if(temp!=0xf0)
   {
      delay(10);
      if(temp!=0xf0)
      {
			temp=P1;
			switch(temp)
			{
				case 0xe7:	key=12;break;	
				case 0xd7:	key=13;break;	
				case 0xb7:	key=14;break;	
				case 0x77:	key=15;break;	
         }
			while(temp!=0xf0)
         {
				temp=P1;
				temp=temp&0xf0;
         }
      }
	}
}

运行效果图:

在这里插入图片描述

在这里插入图片描述


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-339198-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...