微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 4*4任意双键按钮按下判断

4*4任意双键按钮按下判断

时间:10-02 整理:3721RD 点击:

请问,任意的双键按钮是怎样来判断的?单键按钮判断可以,但是双键按钮按下出现1 和 8 ,4 和 5判断是一样的,请问如何区别这角对线出现的按钮。
我使用的是行扫描法:PA2-PA5  PC3-PC5为所用的引脚。
xPORT_A=xPORT_A&(~0x3C); //0x3C(111100)
Wait_ms(10);
tmp=xPORT_C;
tmp=tmp&0x38; //00111000
if(0x38 != tmp)
{
  Wait_ms(10); // Eliminating shiver
  
  if(0x38 != (tmp & 0x38))
  {
   sccode = ~0x04; //从PA2开始扫描
   while(0xFF != sccode)
   {
    xPORT_A = sccode;
    tmp = xPORT_C;
    tmp = tmp & 0x38 ;
    if(0x38 != tmp )
    {
     recode = ((sccode & 0x3C) >> 2) & 0x0f | 0xf0; //PA: xxxx 00 >>2 = xxxx  11111101
     tmpi =  (~((tmp << 1) & 0xf0 | 0x0f)) & 0x7f | (~recode);    //Mode:xxx(pc) xxxx(pa)
     KeyCode[tmpj++] =  tmpi;
    }
     sccode = (sccode << 1)|0x01;  
       Wait_ms(10);
   }
  }
j = tmpj;
i = fnKeycode(tmpj);
ComplexFlag = ComplexFlag + 1;
}  

各位帮下忙。
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//矩阵键盘按键特征码表
uchar code KeyCodeTable[]={0x11,0x12,0x14,0x18,0x21,
0x22,0x24,0x28,0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88};
//延时
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
//键盘扫描
uchar Keys_Scan()
{
uchar sCode,kCode,i,k;
//低 4 位置 0,放入 4 行
P1=0xf0;
//若高 4 位出现 0,则有键按下
if((P1&0xf0)!=0xf0)
{
DelayMS(2);
if((P1&0xf0)!=0xf0)
{

sCode=0xfe;   

//行扫描码初值

for(k=0;k<4;k++) //对 4 行分别进行扫描
{
P1=sCode;
if((P1&0xf0)!=0xf0)
{
kCode=~P1;
for(i=0;i<16;i++) //查表得到按键序号并返回
if(kCode==KeyCodeTable[i])

上海师范大学信息与机电工程学院—倪继锋







16



}

《单片机 C 语言程序设计实训 100 例---基于
return(i);

8051 和 PROTEUS 仿真》案例




}



}


}

else
sCode=_crol_(sCode,1);

}

return(-1);

//主程序
void main()
{
uchar i,P2_LED,P3_LED;
uchar KeyNo=-1;  //按键序号,-1 表示无按键
while(1)
{
KeyNo=Keys_Scan(); //扫描键盘获取按键序号 KeyNo
    if(KeyNo!=-1)
{
P2_LED=0xff;
P3_LED=0xff;
for(i=0;i<=KeyNo;i++)键值越大,点亮的 LED 越多
{
if(i<8)
P3_LED>>=1;
else
P2_LED>>=1;
}
P3=P3_LED;           //点亮条形 LED
P2=P2_LED;
}
}
}
上面这个是仿真的程序。但是用在真的单片机板子上,对IO需要哪些修改呢?
P1=0xf0;
//若高 4 位出现 0,则有键按下
if((P1&0xf0)!=0xf0)
刚才指导说,高四位作为输入,低四位作为输出。在板子上,我是将A口置1,C口置0,请问,是不是需要将A的模式设置为输入模式,C设置为输出模式?

每次只有一行参加运算,同时按下两个是可以的。

我使用的是行扫描方法,如果按着两个按钮单步调试获取的结果没有问题,但是如果不是这样,常常只能得到其中一个按键的值。具体实现的程序如下:
if(0x38 != (tmp & 0x38))
  {
   sccode = ~0x04; //从PA2开始扫描
   while(0xFF != sccode)
   {
    xPORT_A = sccode;
    tmp = xPORT_C;
    tmp = tmp & 0x38 ;
    if(0x38 != tmp )
    {
     recode = ((sccode & 0x3C) >> 2) & 0x0f | 0xf0; //PA: xxxx 00 >>2 = xxxx  11111101
     tmpi =  (~((tmp << 1) & 0xf0 | 0x0f)) & 0x7f | (~recode);    //Mode:xxx(pc) xxxx(pa)
     KeyCode[tmpj++] =  tmpi;
    }
     sccode = (sccode << 1)|0x01;  
       Wait_ms(10);
   }
}
整个的程序上面有。但看不出哪有问题。

/*
**
** name : ScanKey
**
** function :
**                Scan from PA2 to PA5 to get the pressed key
**
**parameters:
**                NULL
*/
void ScanKey()
{
        u8 tmp, k, sccode, recode,Tmpsccode;
        u8 TmpCode ,TmpPreCode = 0,TmpKeyCode[4] = {0};
        u8 i,j, scancount = 2;
                                                                                                                          
        for(scancount; scancount > 0; scancount--)                                                                                        // Scanning repetitions
        {
                sccode = ~0x04;
                Tmpsccode = sccode & 0x3C;       
                Wait_ms(5);                                                                                                                                         // Scan from PA2
                while(0x3C != Tmpsccode)
                {
                        xPORT_A = sccode;
                        tmp = xPORT_C;
                        tmp = tmp & 0x38 ;
                        Wait_ms(5);       
                        if(0x38 != tmp)
                        {
                                recode = ((sccode & 0x3C) >> 2) & 0x0f | 0xf0;                                                        //PA: xxxx 00 >>2 = xxxx         11111101
                                TmpCode =  (~((tmp << 1) & 0xf0 | 0x0f)) & 0x7f | (~recode);                            //Mode:xxx(PC) xxxx(PA)
                                if(0 != TmpCode)                               
                                {       
                                        TmpCode = fnKeycode(TmpCode);
                                            if((0x0F < TmpCode) && (TmpCode != 0xFF))
                                            {
                                                TmpKeyCode[0]  = TmpCode;
                                                break;                                                                                                                // Press two keys at the same time
                                        }
                                        for(k = 0;k<(sizeof(TmpKeyCode)/sizeof(u8));k++)
                                        {
                                                if(0 == TmpKeyCode[k])
                                                {
                                                   TmpKeyCode[k] = TmpCode;
                                                   break;
                                                }
                                        }
                                }
                        }
                        sccode = (sccode << 1)|0x01;
                        Tmpsccode = sccode & 0x3C;
                }
                if(0x0F >= TmpKeyCode[0] )                                                                                                        // It still cannot to judgement whether click the two keys at the same time
                {
                        /*TmpKeyCode insert into gu8_KeyCode which gu8_KeyCode is 0*/
                        for(k = 0;k<(sizeof(TmpKeyCode)/sizeof(u8));k++)
                        {
                                if(0 < TmpKeyCode[k])
                                {
                                        for(i = 0; i<(sizeof(gu8_KeyCode)/sizeof(u8)); i++)
                                        {
                                                if(TmpKeyCode[k] != gu8_KeyCode[i])
                                                {
                                                        for(j = 0;k<(sizeof(gu8_KeyCode)/sizeof(u8));j++)
                                                        {
                                                                if(0 == gu8_KeyCode[j])
                                                                {
                                                                   gu8_KeyCode[j] = TmpKeyCode[k];
                                                                   TmpKeyCode[k] = 0;
                                                                   break;
                                                                }
                                                        }
                                                }
                                          if(0 == TmpKeyCode[k]) break;
                                        }
                                }
                                else break;
                         
                        }
                       
                        /*Sort as descending order*/
                   for(j=0;j<sizeof(gu8_KeyCode)/sizeof(u8) - 1; j++)      
                    {
                                 for(i=0;i<sizeof(gu8_KeyCode)/sizeof(u8) - 1 -j; i++)
                            {            
                                        if(gu8_KeyCode[i] < gu8_KeyCode[i+1])      
                                        {               
                                         TmpCode = gu8_KeyCode[i];         
                                         gu8_KeyCode[i] = gu8_KeyCode[i+1];   
                                         gu8_KeyCode[i+1] = TmpCode;           
                                        }         
                                }
                   }
                  /*Delete repeat data*/
                  for(i = 0; i < sizeof(gu8_KeyCode)/sizeof(u8) ; i++)
                   {
                                   if(0 != gu8_KeyCode[i])
                                {
                                        k = 0;
                                           if(gu8_KeyCode[i] == gu8_KeyCode[i+1])
                                           {
                                                for(j = i+1; j < sizeof(gu8_KeyCode)/sizeof(u8) -1; j++)
                                                {
                                                        gu8_KeyCode[j] = gu8_KeyCode[j+1];                                                 
                                                }
                                                gu8_KeyCode[sizeof(gu8_KeyCode)/sizeof(u8)-1-k] = 0;
                                                k++;
                                        }
                                }
                                                                else break;
                        }
                }
                else
                {
                        gu8_KeyCode[0] = TmpKeyCode[0] ;
                }
         Wait_ms(50);                                                                                                                                         //Delay time
        }
}

已经解决,时间复杂度很大,不好。但没想出好方法,头大。

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

网站地图

Top