51单片机之按键扫描和矩阵按键

目录

前言

一、按键及矩阵键盘

二、按键模块介绍

1.独立按键

2.矩阵按键

三、程序实现

1.独立按键扫描控制LED

2.矩阵键盘控制数码管输出0-F

总结



前言

      51单片机之按键输入,按键是一种开关,也是一种输入型外设,按键用于电源线上就称之为开关,就例如我们开发板的电源开关,也是一种按键。当按键接在io口上,就是一种输入型外设,例如键盘,本文基于51单片机开发板实现通过按键操作LED/数码管

一、按键及矩阵键盘

51单片机之按键扫描和矩阵按键_第1张图片

51单片机之按键扫描和矩阵按键_第2张图片

二、按键模块介绍

1.独立按键

                 关于独立按键的使用,我们首先应该了解51单片机的IO口,51单片机右4个IO口分别为P0,P1,P2,P3,四个io口内部不完全相同,根据51手册给出的内容51单片机io口有三种工作类型,分别为:准双向口/弱上拉,仅为输入(高阻)或开漏输出。P0口上电后为开漏输出,P1/P2/P3上电后为弱上拉模式,我们所示用的P3IO口即为若上拉,即在按键不被按下的时候为高电平,按键按下使IO口接地为低电平。有关开漏和弱上拉,大家可以去了解下。

2.矩阵按键

             矩阵按键使用较少的io口控制多数的按键,以达到节省io口的效果,并且当按键越多的时候,效果约为明显,通常将按键排列为4x4或8x8的矩阵进行逐行逐列扫描,来判断按键是否被按下。

    

三、程序实现

1.独立按键扫描控制LED

代码如下(示例):实现按下led亮,松开led灭 按键扫描封装函数返回键值,可进一步编程。

代码实现的过程中,遇到了很多困难,总觉得这个好难,也看了别人的代码实现,总归1000个人有1000中不同的代码,殊途同归,看到别人的代码总感觉好复杂。

#include   //51专属头文件
#include 	//延时函数头文件
#define LED P2		//定义LED
sbit  key1   =P3^1;
sbit  key2   =P3^0;
sbit  key3   =P3^2;
sbit  key4   =P3^3;

int key_function()
{
    delay_ms(2);						 //消抖
    if(key1==0||key2==0||key3==0||key4==0)	 //判断是否被按下
	  {   if(key1==0)
	         return 1;    //返回键值1
	   else if(key2==0)
	         return 2;	  //返回键值2
	   else if(key3==0)
	         return 3;	  //返回键值3
	   else if(key4==0)
	         return 4;	  //返回键值4
	  }
	  return 0;				   				 //没有按下返回0
}
int main()
{  
  
  while(1)
    {
   if(key_function()==2)					 //判断返回值
     LED = 0X00; 							 //点灯
	else 
	LED=0xFF;								//关灯
    }

return 0;
}

2.矩阵键盘控制数码管输出0-F

代码如下(示例):

行列扫描

#include   //51专属头文件
#include 	//延时函数头文件
#define led P0		//数码管io
#define key P1		//定义矩阵键盘寄存器



int led_display[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
                             0x6f,0x77,0xff,0xb9,0xbf,0xf9,0xf1};	//定义0-f

int Matrix_keyboard()             //自定义矩阵键盘函数
{
	int key_value=0;              //key_value用于返回值
	key=0xf7;                     //让矩阵键盘io一列为0
	if(key!=0xf7)                 //若key!=0xf7即有按键被按下
	 {	
	  delay_ms(1);                //消抖
	  switch(key)                 //行扫描,并输出对应的键值
	     {
		  case 0x77: key_value=1;break;
		  case 0xb7: key_value=5;break;
		  case 0xd7: key_value=9;break;
		  case 0xe7: key_value=13;break;
		  }

	 }
	  while(key!=0xf7);           //有键被按下,等待松手

	  	key=0xfb;                 //第二列为低电平
	if(key!=0xfb)
	 {	
	  delay_ms(1);
	  switch(key)
	     {
		  case 0x7b: key_value=2;break;
		  case 0xbb: key_value=6;break;
		  case 0xdb: key_value=10;break;
		  case 0xeb: key_value=14;break;
		  }

	 }
	  while(key!=0xfb);

	   	  	key=0xfd;              //第三列为低电平
	if(key!=0xfd)
	 {	
	  delay_ms(1);
	  switch(key)
	     {
		  case 0x7d: key_value=3;break;
		  case 0xbd: key_value=7;break;
		  case 0xdd: key_value=11;break;
		  case 0xed: key_value=15;break;
		  }

	 }
	  while(key!=0xfd);

	   	   	  	key=0xfe;          //第四列为低电平
	if(key!=0xfe)
	 {	
	  delay_ms(1);
	  switch(key)
	     {
		  case 0x7e: key_value=4;break;
		  case 0xbe: key_value=8;break;
		  case 0xde: key_value=12;break;
		  case 0xee: key_value=16;break;
		  }

	 }
	  while(key!=0xfe);

	  return key_value;
}
int main()                        //主函数
{  int num=0;
   while(1)
   {
   int num=0;                      //用于接收键值
   num=Matrix_keyboard();
   if(num!=0)
      {
	  led=led_display[num-1];      //数组第一位下下标为0 返回值为1
	  }
   }
   return 0;
}


总结


        以上就是今天的内容,主要操作了独立按键和矩阵按键,在操作过程中也是不断地调试,尤其在矩阵键盘时思路没有那么清晰,容易出错,心里也觉得比较复杂,不断地去理解,终于功夫不负有心人,希望大家也能形成自己的思路和风格。

本人小白一名,希望大家多多指导,多多关注,共同水贴,共同进步。

你可能感兴趣的:(51单片机,矩阵,嵌入式硬件)