打印
[疑难问答]

矩阵按键

[复制链接]
1133|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lzmm|  楼主 | 2024-10-26 22:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
将16个按键按照4*4排列,矩阵键盘的每一行分别连接P3.0~P3.3;矩阵键盘的每一列连接P3.4~P3.7。扫描的原理大致是这样的:先将P30置零,其余都为1(P3-0xfe),然后读取P3口的状态,如果P3!=0xfe了(这里主要是高四位会变化,第四位不变),说明有按键按下了,而且一定是第一行中的某个按键。然后就去判断P3口的状态,如果第一个按键按下(左上角),那应该是P3.4=0,刚才P3.0=0,那么P3口的状态就是P3=0xee,以此类推,第一行第二个,第三个,第四个按键按下,对应P3=0xde, P3=0xbe, P3=0x7e。这样就可以判断是哪个按键按下了,如果P3=0xfe,就说明第一行没有按键按下,那么同样的方法,令P3=0xfd,判断第二行是否有按键按下,依次给每一行置零(P3=0xfb,P3=0xf7),读取列的状态,判断是哪个按键按下,如果都没有,说明没有按键按下。

C51代码:

#include <reg51.h>

void Delay10ms()         //@11.0592MHz

{

       unsigned char i, j;



       i = 18;

       j = 235;

       do

       {

              while (--j);

       } while (--i);

}

void key_scan()

{

       unsigned char temp;

       P3=0xfe;

       temp=P3;

       temp&=0xf0;

       if(temp!=0xf0)

       {

              delay10ms();

              temp=P3;

              temp&=0xf0;

              if(temp!=0xf0)

              {

                     temp=P3;

                     switch(temp)

                     {

                            case 0xee:

                                   P2=0x00;

                            break;

                            case 0xde:

                                   P2=0x01;

                            break;

                            case 0xbe:

                                   P2=0x02;

                            break;

                            case 0x7e:

                                   P2=0x03;

                            break;

                     }

                     while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

              }

       }



       P3=0xfd;

       temp=P3;

       temp&=0xf0;

       if(temp!=0xf0)

       {

              delay10ms();

              temp=P3;

              temp&=0xf0;

              if(temp!=0xf0)

              {

                     temp=P3;

                     switch(temp)

                     {

                            case 0xed:

                                   P2=0x04;

                            break;

                            case 0xdd:

                                   P2=0x05;

                            break;

                            case 0xbd:

                                   P2=0x06;

                            break;

                            case 0x7d:

                                   P2=0x07;

                            break;

                     }

                     while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

              }

       }





       P3=0xfb;

       temp=P3;

       temp&=0xf0;

       if(temp!=0xf0)

       {

              delay10ms();

              temp=P3;

              temp&=0xf0;

              if(temp!=0xf0)

              {

                     temp=P3;

                     switch(temp)

                     {

                            case 0xeb:

                                   P2=0x08;

                            break;

                            case 0xdb:

                                   P2=0x09;

                            break;

                            case 0xbb:

                                   P2=0x0a;

                            break;

                            case 0x7b:

                                   P2=0x0b;

                            break;

                     }

                     while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

              }

       }







       P3=0xf7;

       temp=P3;

       temp&=0xf0;

       if(temp!=0xf0)

       {

              delay10ms();

              temp=P3;

              temp&=0xf0;

              if(temp!=0xf0)

              {

                     temp=P3;

                     switch(temp)

                     {

                            case 0xe7:

                                   P2=0x0c;

                            break;

                            case 0xd7:

                                   P2=0x0d;

                            break;

                            case 0xb7:

                                   P2=0x0e;

                            break;

                            case 0x77:

                                   P2=0x0f;

                            break;

                     }

                     while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

              }

       }





}



void main()

{

       P2=0x00;

       while(1)

       {

              key_scan();

       }

}

Key_scan()是键盘扫描函数,主要分为四大部分,每个部分核心都是一样的,就是实现上述矩阵键盘扫描原理,下面拿出第一段介绍:

P3=0xfe;

       temp=P3;

       temp&=0xf0;

       if(temp!=0xf0)

       {

              delay10ms();

              temp=P3;

              temp&=0xf0;

              if(temp!=0xf0)

              {

                     temp=P3;

                     switch(temp)

                     {

                            case 0xee:

                                   P2=0x00;

                            break;

                            case 0xde:

                                   P2=0x01;

                            break;

                            case 0xbe:

                                   P2=0x02;

                            break;

                            case 0x7e:

                                   P2=0x03;

                            break;

                     }

                     while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

              }

       }

首先P3=0xfe,再将P3赋值给temp,temp再与0xf0与运算,如果P3的高四位有0出现,那么temp一定不等于0xf0,但是这样还不能直接判断就是有按键按下了,可能是一些干扰,而且按键按下时候初期时不稳定的,不是一个理想的下降沿,所以需要消抖,其实就是延时10ms再次读取P3口状态,如果现在tmep依然不等于0xf0,那么可以判断有按键按下了,然后就可以吧p3幅值给temp,进而判断temp的状态了。

然后下面这段程序就是判断按键是否抬起,否则的话会一直在这个循环,无法执行其他程序:

while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

上述代码时通过while循环实现的,也可以中断实现:

#include <reg51.h>

unsigned char num;

void Delay10ms()         //@11.0592MHz

{

       unsigned char i, j;



       i = 18;

       j = 235;

       do

       {

              while (--j);

       } while (--i);

}

void key_scan()

{

       unsigned char temp;

       P3=0xfe;

       temp=P3;

       temp&=0xf0;

       if(temp!=0xf0)

       {

              delay10ms();

              temp=P3;

              temp&=0xf0;

              if(temp!=0xf0)

              {

                     temp=P3;

                     switch(temp)

                     {

                            case 0xee:

                                   P2=0x00;

                            break;

                            case 0xde:

                                   P2=0x01;

                            break;

                            case 0xbe:

                                   P2=0x02;

                            break;

                            case 0x7e:

                                   P2=0x03;

                            break;

                     }

                     while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

              }

       }



       P3=0xfd;

       temp=P3;

       temp&=0xf0;

       if(temp!=0xf0)

       {

              delay10ms();

              temp=P3;

              temp&=0xf0;

              if(temp!=0xf0)

              {

                     temp=P3;

                     switch(temp)

                     {

                            case 0xed:

                                   P2=0x04;

                            break;

                            case 0xdd:

                                   P2=0x05;

                            break;

                            case 0xbd:

                                   P2=0x06;

                            break;

                            case 0x7d:

                                   P2=0x07;

                            break;

                     }

                     while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

              }

       }





       P3=0xfb;

       temp=P3;

       temp&=0xf0;

       if(temp!=0xf0)

       {

              delay10ms();

              temp=P3;

              temp&=0xf0;

              if(temp!=0xf0)

              {

                     temp=P3;

                     switch(temp)

                     {

                            case 0xeb:

                                   P2=0x08;

                            break;

                            case 0xdb:

                                   P2=0x09;

                            break;

                            case 0xbb:

                                   P2=0x0a;

                            break;

                            case 0x7b:

                                   P2=0x0b;

                            break;

                     }

                     while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

              }

       }







       P3=0xf7;

       temp=P3;

       temp&=0xf0;

       if(temp!=0xf0)

       {

              delay10ms();

              temp=P3;

              temp&=0xf0;

              if(temp!=0xf0)

              {

                     temp=P3;

                     switch(temp)

                     {

                            case 0xe7:

                                   P2=0x0c;

                            break;

                            case 0xd7:

                                   P2=0x0d;

                            break;

                            case 0xb7:

                                   P2=0x0e;

                            break;

                            case 0x77:

                                   P2=0x0f;

                            break;

                     }

                     while(temp!=0xf0)

                     {

                            temp=P3;

                            temp&=0xf0;

                     }

              }

       }





}



void main()

{

       TMOD=0x01;

       TH0 = (65536-917)/256;       //1000/1.09   

       TL0 = (65536-917)%256;;            

       EA=1;

       ET0=1;

       TR0=1;

       P2=0x00;

       while(1)

       {

              if(num==2)

              {

                     num=0;

              key_scan();

              }

       }

}

void Timer0() interrupt 1

{

  TH0 = (65536-917)/256;         

       TL0 = (65536-917)%256;      

       num++;

}

核心的内容都一样,就不多解释了。  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

401

主题

8829

帖子

11

粉丝