单片机学习小组
直播中

安立路

8年用户 787经验值
私信 关注

判断单片机扫描矩阵按键有无按键按下的方法是什么

4*4矩阵键盘的内部电路是如何构成的?
判断单片机扫描矩阵按键有无按键按下的方法是什么?



回帖(1)

周志光

2022-2-23 10:50:31
        单片机系统中,若使用按键较多时如电子密码锁、电话机键盘等一般都至少有12到16个按键,通常采用矩阵键盘。矩阵键盘又称行列键盘,它是用四条I/O线作为行线,四条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4*4个。这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。最常见的键盘布局一般由16个按键组成,在单片机中正好可以用一个P口实现16个按键功能,这也是在单片机系统中最常用的形式,4*4矩阵键盘的内部电路如下图所示。







        当无按键闭合时,P3.0~P3.3与P3.4~P3.7之间开路。当有键闭合时,与闭合键相连的两条I/O口线之间短路。

        判断有无按键按下的方法是:第一步,置列线P3.4~P3.7为输入状态,从行线P3.0~P3.3输出低电平,读入列线数据,若某一列线为低电平,则该列线上有键闭合。第二步,行线轮流输出低电平,从列线P3.4~P3.7读入数据,若有某一列为低电平,则对应行线上有键按下。

        综合上述两步的结果,可确定按键编号。但是键闭合一次只能进行一次键功能操作,因此须等到按键释放后,再进行键功能操作,否则按一次键,有可能会连续多次进行同样的键操作。识别按键的方法很多,其中最常见的方法是扫描法。当按键按下时,与此键相连的行线与列线导通,行线在无按键按下时处在高电平。如果所有的列线都处在高电平,则按键按下与否不会引起行线电平的变化,因此必须使所有列线处在低电平。这样,当有按键按下时,该键所在的行电平才会由高变低,才能判断相应的行有键按下。矩阵按键的位置由于行号和列号是唯一确定,因此可以分别对行号和列号进行二进制编码,然后两值合成一个字节,高4位是行号,低4位是列号。



代码如下:


#include

void delay(int t)
{
  int x, y;
  for (x = t; x > 0; x--)
    for (y = 10; y > 0; y--);
}




void main (void)
{

  while (1)
  {
    P3 = 0xfe;            //扫描第一行
    temp = P3;
    temp = temp & 0xf0;          //保留列上的信息
    if (temp != 0xf0)          //四列有输入为低电平0的?  有按键?
    {
      delay(10);                //过10ms,再观察。
      if (temp != 0xf0)                //还是四列有输入为低的情况?有按键?
      {
        temp = P3;                         //读一下信息。
        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 = P3;
          temp = temp & 0xf0;

        }

        disp(key);

      }
    }

    P3 = 0xfd;
    temp = P3;
    temp = temp & 0xf0;
    if (temp != 0xf0)
    {
      delay(10);
      if (temp != 0xf0)
      {
        temp = P3;
        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 = P3;
          temp = temp & 0xf0;
        }

        disp(key);
      }
    }
   
    P3 = 0xfb;
    temp = P3;
    temp = temp & 0xf0;
    if (temp != 0xf0)
    {
      delay(10);
      if (temp != 0xf0)
      {
        temp = P3;
        switch (temp)
        {
          case 0xeb:
            key = 8;
            break;

          case 0xdb:
            key = 9;
            break;

          case 0xbb:
            key = 10;
            break;

          case 0x7b:
            key = 11;
            break;
        }
        while (temp != 0xf0)
        {
          temp = P3;
          temp = temp & 0xf0;

        }

        disp(key);
      }
    }
   
    P3 = 0xf7;
    temp = P3;
    temp = temp & 0xf0;
    if (temp != 0xf0)
    {
      delay(10);
      if (temp != 0xf0)
      {
        temp = P3;
        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 = P3;
          temp = temp & 0xf0;

        }

        disp(key);
      }
    }
  }
}


举报

更多回帖

发帖
×
20
完善资料,
赚取积分