壹拾肆:矩阵按键的读取

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17017545/article/details/81349250

扫描方法

1)逐行逐列扫描法(K6被按下)
比如说现在 K6 按下,那怎么知道哪个按下了呢?
首先第0行输出低电平0,其他行输出高电平1,所有列输出高电平,此时发现每一列的引脚仍然为高,说明第0行没有被按下。然后第1行输出低电平0,其他行输出高电平1,所有列输出高电平,发现第2列变成了低电平。可知第1行第2列有按键按下。(K6)
2)行列反转法(K6被按下)
首先让第0行,第1行,第2行,第3行,一次性输出0,0,0,0,而第0列,第1列,第2列,第3列跟51单片机相连的引脚全部拉高(1),之后读取第0列,第1列,第2列,第3列的电平,得到的是列的编码(1,1,0,1);然后第0列,第1列,第2列,第3列全置0,把行全部置1,再来判断行的编码(1,0,1,1),整个编码为:1101 1011,我们可以将它设计对应为K6(第1行第2列),从而得出是哪个按键被按下.

电路图
这里写图片描述
代码

******************************************************************/	
*   【课程15】 ****矩阵按键的读取***********
*   【说  明】 ****采用逐列扫描法(没做松开按键的处理,后面介绍)
*   【描  述】 ****扫描一个按键按下,做键值处理,并通过数码管显示出来
******************************************************************/
#include<reg51.h>		//51头文件,

//---------常用的两个宏定义-------------- 
#define uint8	unsigned char
#define uint16  unsigned int

//--------定义全局变量-------------------
uint8 Temp,Key_value;

//------------数码管段选显示数据-------------------
uint8 SEG_Data[16]={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,
~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};

//------------函数的声明-----------------
void DelayMS(uint16 dly);
void Key_Scan1(void);		//扫描按键方法1
void Key_Scan2(void);       //扫描按键方法2
void Key_Down(void);        //判断是否有按键被按下


//-------------主函数--------------------
void main(void)
{
	while(1)
	{
		Key_Down();	
	}		
}

/********************************************************
** 名称 :void Key_Down(void)
** 功能 :判断是否有按键被按下
** 入口参数 :无  
** 出口参数 :无   
*********************************************************/
void Key_Down(void)
{
	P2 = 0xf0;				//设置I/O的输入输出
	Temp = P2;
	Temp = 	Temp&0xf0;	
	if(Temp!=0xf0)         //只要有按键按下Temp就不等于0xf0
	{
		DelayMS(100);		//软件延时去抖	
		if(Temp!=0xf0)      //再次判断是否仍处于按下状态
		{
		//	Key_Scan1();	//按键扫描方法一
			Key_Scan2();	//按键扫描方法二							
		}
	}		
}

/********************************************************
** 名称 :void Key_Scan1(void)
** 功能 :扫描按键方法一
** 入口参数 :无  
** 出口参数 :无   
*********************************************************/
void Key_Scan1(void)
{
	P2 = 0xfe;
	Temp = P2;
	switch(Temp)
	{
		case 0xee:	Key_value=0;	
						break;
		case 0xde:	Key_value=1;	
						break;
		case 0xbe:	Key_value=2;	
						break;
		case 0x7e:	Key_value=3;	
						break;
	}
	P2 = 0xfd;
	Temp = P2;
	switch(Temp)
	{
		case 0xed:	Key_value=4;	
						break;
		case 0xdd:	Key_value=5;	
						break;
		case 0xbd:	Key_value=6;	
						break;
		case 0x7d:	Key_value=7;	
						break;
	}
	P2 = 0xfb;
	Temp = P2;
	switch(Temp)
	{
		case 0xeb:	Key_value=8;	
						break;
		case 0xdb:	Key_value=9;	
						break;
		case 0xbb:	Key_value=10;	
						break;
		case 0x7b:	Key_value=11;	
						break;
	}
	P2 = 0xf7;
	Temp = P2;
	switch(Temp)
	{
		case 0xe7:	Key_value=12;	
						break;
		case 0xd7:	Key_value=13;	
						break;
		case 0xb7:	Key_value=14;	
						break;
		case 0x77:	Key_value=15;	
						break;
	}
	P1 = SEG_Data[Key_value];								
}

/********************************************************
** 名称 :void Key_Scan2(void)
** 功能 :扫描按键方法二
** 入口参数 :无  
** 出口参数 :无   
*********************************************************/
void Key_Scan2(void)
{
	uint8 key_row,key_col,key;

	key_col = P2;	//以第一个按键为例 (11101110)		
	key_col = key_col & 0xf0;	//11100000	
	key_col = key_col |0x0f;	//11101111
	P2 = key_col;				//11101111
	key_row = P2;				//11101110
//	key_row = key_row & 0x0f;	//00001110	
//	key_col = key_col & 0xf0;	//11100000
//	key = key_row +	key_col;	//11101110	
	key = key_row;
	switch(key)
	{
		case 0xee:	Key_value=0;	
						break;
		case 0xde:	Key_value=4;	
						break;
		case 0xbe:	Key_value=8;	
						break;
		case 0x7e:	Key_value=12;	
						break;
		case 0xed:	Key_value=1;	
						break;
		case 0xdd:	Key_value=5;	
						break;
		case 0xbd:	Key_value=9;	
						break;
		case 0x7d:	Key_value=13;	
						break;
		case 0xeb:	Key_value=2;	
						break;
		case 0xdb:	Key_value=6;	
						break;
		case 0xbb:	Key_value=10;	
						break;
		case 0x7b:	Key_value=14;	
						break;
		case 0xe7:	Key_value=3;	
						break;
		case 0xd7:	Key_value=7;	
						break;
		case 0xb7:	Key_value=11;	
						break;
		case 0x77:	Key_value=15;	
						break;
	}
	P1 = SEG_Data[Key_value];		
}

/********************************************************
** 名称 :void DelayMS(uint16 dly)
** 功能 :毫秒级延时(24M的晶振)
** 入口参数 :dly   用户的延时参数   
** 出口参数 :无   
*********************************************************/
void DelayMS(uint16 dly)
{
	uint16 x,y;
	for(x=dly;x>0;x--)
		for(y=247;y>0;y--);
}

猜你喜欢

转载自blog.csdn.net/qq_17017545/article/details/81349250
今日推荐