基于51单片机的矩阵键盘设计

描述

12.1 项目分析

矩阵键盘,是一种在节省端口的前提下控制大量按键的一种方法,对于传统的独立对地键盘,一个按键就需要占用一个单片机IO口,虽然有时候会加一些扩展芯片之类的用于一个端口控制多个按键,但是电路结构比较复杂,矩阵键盘则是一种尽可能的既不用驱动芯片又能最大限度的使用大量按键的方法,一个a行b列的矩阵键盘,它所占用的端口数量是a+b个端口,所控制的按键数量则是a×b个按键,比如常见的4×4矩阵键盘只需要占用8个端口就可以控制16个按键,矩阵键盘的接法如下图所示。

单片机

从图中可以看出,每一列的按键取一端接在一起,每一行的按键取按键的另一列接在一起,这样就会引出四条行扫描线和列扫描线,假设某个端口产生了低电平,那么对应的就会有四个按键变成了独立对地键盘,当这四个键按下的时候,对应的端口电平就会拉低,所以矩阵键盘的按键检测主要就是进行扫描检测,在短暂的时间内不停的扫描键盘,可以根据行扫描判断,也可以根据列扫描判断,矩阵键盘的识别主要有以下几种判断方法:

算法1 :对矩阵键盘的行(或者列)不停的扫描,然后检测对应的列(或者行),当扫描的频率超过人的反应时间时,便不会被感觉出来,但是这种方法的优点是程序编写较为简单,但是代码很长,且浪费CPU的资源。

算法2: 对矩阵键盘的列(或者行)全部赋低电平,然后判断是否有行(或者列)的端口有低电平产生,没有,证明按键没有被按下,如果有,那么此时将端口对应的数据存放入一个变量,并同时将列(或者行)的低电平转移到行(或者列)上,此时列(或者行)必然也会有一个低电平的端口,将这时候的数据存放入第二个变量,最后,撤销所有的低电平,将两个变量的数据相加,则必然会得出所有按键值的其中一个,那么这个按键值所对应的按键必然就是按下的按键,这种算法比较复杂,编程或者理解起来比较困难,但是代码短,节省CPU资源。

12.2 原理图

单片机

现在我们以原理图为例,实现如下功能,用0~F代表按键的编号,按下某个按键后,在数码管上显示按键的编号(要求采用算法2方式实现)。

**12.3 **源代码

/*********************************************************************************************************
                头    文    件    引    用
*********************************************************************************************************/
#include <reg51.h>                                            //导入51单片机头文件
#include <intrins.h>
/*********************************************************************************************************
              数    据    类    型    定    义
*********************************************************************************************************/
#define u8 unsigned char                                        //定义无符号字符型数据(0~255)
#define u16 unsigned int                                        //定义无符号整型数据(0~65535)
/********************************************************
Name    :KEY_Scan
Function  :键盘扫描
Paramater  :None
Return    :None
********************************************************/
void KEY_Scan()
{
  u8 x, y ;
  u8 TAB[] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10, 0x08, 0x03, 0x46, 0x21, 0x06, 0x0E } ;
  P2 = 0xF0 ;
  if( P2!=0xF0 )
  {
    x = P2 ;
    P2 = 0x0F ;
    if( P2!=0x0F )
    {
      y = P2 ;
      switch( x+y )
      {
        case 0xEE:  P0 = TAB[ 0 ] ;    break ;
        case 0xDE:  P0 = TAB[ 1 ] ;    break ;
        case 0xBE:  P0 = TAB[ 2 ] ;    break ;
        case 0x7E:  P0 = TAB[ 3 ] ;    break ;
        case 0xED:  P0 = TAB[ 4 ] ;    break ;
        case 0xDD:  P0 = TAB[ 5 ] ;    break ;
        case 0xBD:  P0 = TAB[ 6 ] ;    break ;
        case 0x7D:  P0 = TAB[ 7 ] ;    break ;
        case 0xEB:  P0 = TAB[ 8 ] ;    break ;
        case 0xDB:  P0 = TAB[ 9 ] ;    break ;
        case 0xBB:  P0 = TAB[ 10 ] ;  break ;
        case 0x7B:  P0 = TAB[ 11 ] ;  break ;
        case 0xE7:  P0 = TAB[ 12 ] ;  break ;
        case 0xD7:  P0 = TAB[ 13 ] ;  break ;
        case 0xB7:  P0 = TAB[ 14 ] ;  break ;
        case 0x77:  P0 = TAB[ 15 ] ;  break ;
      }
    }
  }
}
/*********************************************************************************************************
                    主    函    数
*********************************************************************************************************/
void main()
{
  while( 1 )
  {
    KEY_Scan() ;
  }
}

12.4 仿真效果

单片机

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分