51单片机学习记录(五)矩阵按键

文章目录

  • 1、矩阵按键的控制原理
  • 2、矩阵按键实现
  • 1、行列式法实现矩阵按键
  • 2、线翻转法实现矩阵按键
  • 3、按键实战
  • 1、矩阵按键的控制原理

    独立按键与单片机连接时, 每一个按键都需要单片机的一个 I/O 口, 若某单片机系统需较多按键, 如果用独立按键便会占用过多的 I/O 口资源。 单片机系统中 I/O 口资源往往比较宝贵, 当用到多个按键时为了减少 I/O 口引脚, 引入了矩阵按键。

    本开发板上的矩阵按键原理图如下所示:


    可以看到是将16个按键排成4行4列,前面的四行分别连接io口的每一行,后面的四行分别连接io口的每一列,这样就实现了每个io口都连接四个按键,同样通过这样的方式也可以实现3X3,5X5等这样的布局。

    那么在检测的时候又是如何实现的呢,这种按键的检测一般是通过扫描来实现的,先使能某一列列为低电平,其余几列全为高电平,之后立即轮流检测一次每行是不是有低电平,如果没有的话,就说明这一行没有按键被按下,如果有低电平,则可以说明该行有被按下的按键,这样的话就通过行列来锁定了按键的位置,这个列的低电平使能也是在轮流进行的,通过这样的方式就可以实现按键的检测了。

    2、矩阵按键实现

    1、行列式法实现矩阵按键

    首先来看下矩阵按键的定义,如下所示:

    下面以第一步的操作为例,首先给我们对应的io口进行赋值,这里赋值为0XF7,就是1111 0111,第一列全都赋值为0,其余的全为1:

    之后在检测第第一行有没有按键被按下,如果有按键被按下应该是下面几种情况,将这几种情况一一进行枚举,结果如下所示:

    下面第二行

    下面第三行

    下面第四行

    在程序中体现出来就是下面的代码部分了:

    完整的代码如下所示:(注:本处代码来自普中科技51单片机例程

    u8 key_matrix_ranks_scan(void) //行列式扫描实现矩阵按键检测
    {
    	u8 key_value=0;
    
    	KEY_MATRIX_PORT=0xf7;//给第一列赋值0,其余全为1
    	if(KEY_MATRIX_PORT!=0xf7)//判断第一列按键是否按下
    	{
    		delay_100ms();//消抖
    		switch(KEY_MATRIX_PORT)//保存第一列按键按下后的键值	
    		{
    			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_MATRIX_PORT!=0xf7);//等待按键松开	
    	
    	KEY_MATRIX_PORT=0xfb;//给第二列赋值0,其余全为1
    	if(KEY_MATRIX_PORT!=0xfb)//判断第二列按键是否按下
    	{
    		delay_100ms();//消抖
    		switch(KEY_MATRIX_PORT)//保存第二列按键按下后的键值	
    		{
    			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_MATRIX_PORT!=0xfb);//等待按键松开	
    	
    	KEY_MATRIX_PORT=0xfd;//给第三列赋值0,其余全为1
    	if(KEY_MATRIX_PORT!=0xfd)//判断第三列按键是否按下
    	{
    		delay_100ms();//消抖
    		switch(KEY_MATRIX_PORT)//保存第三列按键按下后的键值	
    		{
    			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_MATRIX_PORT!=0xfd);//等待按键松开	
    	
    	KEY_MATRIX_PORT=0xfe;//给第四列赋值0,其余全为1
    	if(KEY_MATRIX_PORT!=0xfe)//判断第四列按键是否按下
    	{
    		delay_100ms();//消抖
    		switch(KEY_MATRIX_PORT)//保存第四列按键按下后的键值	
    		{
    			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_MATRIX_PORT!=0xfe);//等待按键松开
    	
    	return key_value;		
    }
    

    2、线翻转法实现矩阵按键

    线翻转法实现的流程为首先使所有行线为低电平时, 之后检测所有列线是否有低电平, 如果有, 就记录列线值; 然后再翻转, 使所有列线都为低电平, 检测所有行线的值,由于有按键按下, 行线的值也会有变化, 记录行线的值。 从而就可以检测到全部按键。

    线翻转法的具体实现流程为:

    完整的代码如下所示:(注:本处代码来自普中科技51单片机例程

    u8 key_matrix_flip_scan(void) //线翻转法实现矩阵按键
    {
    	static u8 key_value=0;
    
    	KEY_MATRIX_PORT=0x0f;//给所有行赋值0,列全为1
    	if(KEY_MATRIX_PORT!=0x0f)//判断按键是否按下
    	{
    		delay_100ms();//消抖
    		if(KEY_MATRIX_PORT!=0x0f)
    		{
    			//测试列
    			KEY_MATRIX_PORT=0x0f;
    			switch(KEY_MATRIX_PORT)//保存行为0,按键按下后的列值	
    			{
    				case 0x07: key_value=1;break;
    				case 0x0b: key_value=2;break;
    				case 0x0d: key_value=3;break;
    				case 0x0e: key_value=4;break;
    			}
    			//测试行
    			KEY_MATRIX_PORT=0xf0;
    			switch(KEY_MATRIX_PORT)//保存列为0,按键按下后的键值	
    			{
    				case 0x70: key_value=key_value;break;
    				case 0xb0: key_value=key_value+4;break;
    				case 0xd0: key_value=key_value+8;break;
    				case 0xe0: key_value=key_value+12;break;
    			}
    			while(KEY_MATRIX_PORT!=0xf0);//等待按键松开	
    		}
    	}
    	else
    		key_value=0;		
    	
    	return key_value;		
    }
    

    3、按键实战

    利用之前的串口函数来进行实现按键打印,代码如下:

    将程序下载到开发板,可以看到如下现象

    物联沃分享整理
    物联沃-IOTWORD物联网 » 51单片机学习记录(五)矩阵按键

    发表评论