微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 矩阵按键处理多个键值问题

矩阵按键处理多个键值问题

时间:10-02 整理:3721RD 点击:
矩阵怎么处理在有键已按下的情况下,识别出后面按下去是什么键,有相关的解决方法或相关的程序,请提供借鉴一下,谢谢了。

大神们,帮帮忙呀,我都弄两天了还是不能解决

用状态机……          

假设一个4行4列的矩阵键盘,一共需要8条IO,假设使用的P0口的8个脚
那么定时去读取P0口的数据,那一个被按下去,就会有两个脚电平产生变化,然后分辨是那个按键就可以了
注意需要去抖

比如是4*4矩阵按键,检测时可以通过单片机的I/O口送出低电平。检测时,先送出一列为低电平,其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平,则我们就能确定是哪个按键被按下了。  你可以看一下下面的代码,希望对你帮助。

uint matrixkeyscan()
{
        uchar temp,key;
        P3=0xfe;        //第一行键盘
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
                }                               
        }
       
        P3=0xfd;         //第二行键盘
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
                }                               
        }

        P3=0xfb;                              //第三行键盘   
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
               
                }                               
        }

        P3=0xf7;            //第四行键盘
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
               
                }                               
        }
        return key;
}
不懂的话,可以加我好友,大家一起讨论,我也是新手,希望大家能互相进步!

比如是4*4矩阵按键,检测时可以通过单片机的I/O口送出低电平。检测时,先送出一列为低电平,其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平,则我们就能确定是哪个按键被按下了。  你可以看一下下面的代码,希望对你帮助。

uint matrixkeyscan()
{
        uchar temp,key;
        P3=0xfe;        //第一行键盘
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
                }                               
        }
       
        P3=0xfd;         //第二行键盘
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
                }                               
        }

        P3=0xfb;                              //第三行键盘   
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
               
                }                               
        }

        P3=0xf7;            //第四行键盘
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
               
                }                               
        }
        return key;
}
不懂的话,可以加我好友,大家一起讨论,我也是新手,希望大家能互相进步!

比如是4*4矩阵按键,检测时可以通过单片机的I/O口送出低电平。检测时,先送出一列为低电平,其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平,则我们就能确定是哪个按键被按下了。  你可以看一下下面的代码,希望对你帮助。 代码的返回值就是哪个按键的值,可以用一个变量进行标记,记录按下的次数。

uint matrixkeyscan()
{
        uchar temp,key;
        P3=0xfe;        //第一行键盘
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
                }                               
        }
       
        P3=0xfd;         //第二行键盘
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
                }                               
        }

        P3=0xfb;                              //第三行键盘   
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
               
                }                               
        }

        P3=0xf7;            //第四行键盘
        temp=P3;
        temp=temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);    //消除按键抖动
                temp=P3;
                temp=temp&0xf0;
                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)  //条件满足时是1;等待按键释放;
                        {
                                temp=P3;         //这两句是增加程序的稳定性
                                temp=temp&0xf0;
                        }
               
                }                               
        }
        return key;
}
不懂的话,可以加我好友,大家一起讨论,我也是新手,希望大家能互相进步!

谢谢你的好意,但是我想要的不是这个结果

比如是4*4矩阵按键,在矩阵按键扫描的时候行和列分别送相反电平此时该组IO口有一个8位二进制数值,在按第一个按键时.该组IO口数值有所变化,保持此时按键值,再按下另外按键时,此时该组IO口数值发生第二次变化,弟弟两次按键值,即可判断出第二次按键值。依次对比,就可以判断出后面按键。

  1. #define Key_4_4_NULL  0xff   
  2. uchar Read_Keyboart_4_4()    //4*4键盘
  3. {
  4.   static uchar Key_Static=0; //状态机变量
  5.         uchar Key_Press;           //读取按键值变量
  6.         uchar Key_H=0;             //行
  7.         uchar Key_L=0;             //列
  8.        
  9.   P1=0x0f;
  10.         Key_H=P1&0x0f;
  11.         switch(Key_Static)         //选择按键状态
  12.         {
  13.     case 0:if(Key_H!=0x0f) Key_Static=1;//有按键按下,转到下一状态
  14.                              break;
  15.                
  16.                 case 1:if(Key_H!=0x0f)
  17.                        {
  18.                                                 Key_Static=2;
  19.             Key_H=P1&0x0f;
  20.                                                 P1=Key_H|0xf0;
  21.                                                 Key_L=P1&0xf0;
  22.                                                 Key_Press=Key_H+Key_L;     //读取行和列
  23.             return Key_Press;                                                 
  24.                                          }
  25.            else        Key_Static=0;                                 
  26.                              break;
  27.                                          
  28.                 case 2:if(Key_H==0x0f) Key_Static=0;     //判断按键是否松开,松开就返回到0态                                                          
  29.                              break;
  30.                
  31.                 default:Key_Static=0;break;
  32.   }
  33.        
  34.         return Key_4_4_NULL;             //返回按键值       
  35. }

  36. uchar Set_Keyboart_4_4() //每20ms扫描一次,消抖动就是20ms
  37. {
  38.   uchar Key_Data;           
  39.        
  40.         Key_Data=Read_Keyboart_4_4();//读取按键值
  41.         switch(Key_Data)               
  42.         {
  43.    case 0xee:return Key_4_4_NULL;break; //
  44.          case 0xde:return Key_4_4_NULL;break; //
  45.          case 0xbe:return Key_4_4_NULL;break; //
  46.          case 0x7e:return Key_4_4_NULL;break; //
  47.                                                  
  48.          case 0xed:return 9;break;   //9
  49.          case 0xdd:return 6;break;   //6
  50.          case 0xbd:return 3;break;   //3
  51.          case 0x7d:return Key_4_4_NULL;break; //
  52.                                                  
  53.          case 0xeb:return 8;break;   //8
  54.          case 0xdb:return 5;break;   //5
  55.          case 0xbb:return 2;break;   //2
  56.          case 0x7b:return 0;break;   //0
  57.                                                          
  58.          case 0xe7:return 7;break;   //7
  59.          case 0xd7:return 4;break;   //4
  60.          case 0xb7:return 1;break;   //1
  61.          case 0x77:return Key_4_4_NULL;break; //
  62.                                                  
  63.    default:break;                                          
  64.   }
  65.        
  66.         return Key_4_4_NULL;         
  67. }

复制代码

      
自己写的状态机按键程序,看不懂可以多看几次,多想几次,慢慢研究,对实际应用很有价值

真不知道这么多,词不达意的人,怎么当软件工程师的。小编要的是按下第一个按键后,再检测之后的键值,是怎么实现。而不是扫键函数。

时隔一年了,小编,怎么解决问题的,分享下,可以不

你看看这段程序怎么样?我自己写的。
#include <reg51.h>
#define KEY P1
//按键码,按键之间按位或运算
#define KEY1  0x11
#define KEY2  0x12
#define KEY3  0x14
#define KEY4  0x18
#define KEY5  0x21
#define KEY6  0x22
#define KEY7  0x24
#define KEY8  0x28
#define KEY9  0x41
#define KEY10 0x42
#define KEY11 0x44
#define KEY12 0x48
#define KEY13 0x81
#define KEY14 0x82
#define KEY15 0x84
#define KEY16 0x88
void Delay10ms(u8 c)//延时10ms
{
        u8 a,b;
        for( ; c>0; c--)
                for(b=38; b>0; b--)
                        for(a=130; a>0; a--);
}
u8 GetKeyboard()//获取矩阵键盘按键值,支持多按键
{
        u8 key,i;
        key = 0xFF;
        for(i=KEY_Delay; i>0; i--)//按键延时 KEY_Delay*10ms
        {
                KEY = 0x0F;
                if(KEY == 0x0F) break;
                if(KEY != (key & 0x0F))
                {
                        Delay10ms(1);//消抖
                        if(KEY != (key & 0x0F))
                                key &= (KEY | 0xF0);
                }
                KEY = 0xF0;
                if(KEY == 0xF0) break;
                if(KEY != (key & 0xF0))
                {
                        Delay10ms(1);//消抖
                        if(KEY != (key & 0xF0))
                                key &= (KEY | 0x0F);
                }
                Delay10ms(1);
        }
        return (~key);
}

本于技术交流原则。请不要用该代码用于商业用途

你这个不是多键值的问题,应该算是多键同时按下的问题,这种情况通常当作按键动作异常处理,是认为当前按键无效的

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top