【51单片机学习过程记录】4矩阵键盘

来源:互联网 发布:ai mac中文版免费下载 编辑:程序博客网 时间:2024/05/22 15:47

aa硬件分析:

矩阵键盘是指S1--S16按键, 其 连接单片机引脚分别是 P3^0--P3^7,其中可以看出,按键的左端分别连接P3^0--P3^3, 按键的右端分别连接P3^4--P3^7。

电平;然后当按键被按下之后,会改变按键两端的电平状态,例如,S1左端是低电平,记作0,右端是高电平,记作1,那么当S1被按下,左右两端连通,那么按键的右端被拉低,那么按键两端都为0。

(**这里要注意一点,就是单片机IO口的状态,或者说是内部结构需要了解下,例如IO口内部有没接上拉电阻......这个我还没了解,当问题出现时的确需要继续了解的。这里P123口应该是接上拉电阻的,只有P0口没有接,通常P0口是在开发板上外部接上拉电阻。再有,当IO口作接收数据时,要先置1。)


bb实现原理分析:

那么对于四行四列的十六个按键,如何去检测时哪一个按键被按下呢?当然,想到是当按键按下时的电平变化,也就是说,需要设定按键两端为不一样的电平。(当然,这里的假设哪个引脚低哪个引脚高就不多说了,可以自己想下)


设定引脚初始状态,为的是后面检测被按下按键的位置。

设定第一行,即P3^0为低电平,其他都为高电平。  因此,当第一行的第1个按键被按下,那么对应按键右端的引脚P3^4被拉低为0,从而判断出被按下的按键是第一个,S1。

然后,在这种情况下?如何检测得到其他行的按键被按下呢,显然是不足以的。

所以,继续给引脚设定不同的初始状态,进行其他按键的检测。

设定第二行,即P3^1为低电平,其他都是高电平,注意,第一行这时也要设为高电平,因为这次的检测是从第二行开始的(第一行没有被按下时,就需要运行这次的检测了)


如此操作,一共设定四个不同的初始状态,就是分别第一行、第二行、第三行以及第四行为低电平其他都为高电平。注意,这四个不同的状态,是程序的一个整体,就是说当第一种状态检测完之后,继续第二种状态去检测,从而最后把全部四行四列的十六个按键都检测一遍,即四个状态去检测一个被按下的按键,而不是当第一行检测完就跳出检测。



cc实现代码:


#include <reg52.h>
#define uchar unsigned char
sbit beep=P2^3;


void delay(uchar x)
{
uchar i,y;
for(i=x;i>0;i--)
for(y=110;y>0;y--);
}


void main()
{

while(1)
{
P3=0xfe;                                                                    //初始状态1
if(P3!=0xfe&&P3)
{
delay(1);
if(P3!=0xfe&&P3)
  {
switch(P3)
{
case 0xee:beep=0;P1=0xfe;break;
case 0xde:beep=0;P1=0xfc;break;
case 0xbe:beep=0;P1=0xf8;break;
case 0x7e:beep=0;P1=0xf0;break;
  }
}


} //row1


P3=0xfd;                                                                   //初始状态2
if(P3!=0xfd&&P3)
{
delay(1);
if(P3!=0xfd&&P3)
{
switch(P3)
{
case 0xed:beep=0;P1=0xe0;break;
case 0xdd:beep=0;P1=0xc0;break;
case 0xbd:beep=0;P1=0x80;break;
case 0x7d:beep=0;P1=0x0;break;
}
}


} //row2


P3=0xfb;  //初始状态3
if(P3!=0xfb&&P3)                                                 //当按键被按下,P3口的电平状态就会和初始状态不同
{
delay(1);                                                       //延时去抖
if(P3!=0xfb&&P3)
{
switch(P3)                                           //检测P3口的高四位,看是哪个口被拉低,就可以确定是该行的第几个按键被按下
{
case 0xeb:beep=0;P1=0x7f;break;                                     //这里的高四位e d  b  7用来判断第几列,即该行的第几个按键
case 0xdb:beep=0;P1=0x3f;break;
case 0xbb:beep=0;P1=0x1f;break;
case 0x7b:beep=0;P1=0xf;break; 
}
}


} //row3


P3=0xf7;  //初始状态4
if(P3!=0xf7&&P3)
{
delay(1);
if(P3!=0xf7&&P3)
{
switch(P3)
{
case 0xe7:beep=0;P1=0x7;break;
case 0xd7:beep=0;P1=0x3;break;
case 0xb7:beep=0;P1=0x1;break;
case 0x77:beep=0;P1=0x0;break;
}
}


} //row4
delay(1000);                                                                                         //延时,让蜂鸣器响
beep=1; //关闭蜂鸣器
}  


}


dd代码分析:

分析为代码中的注释。


ee总结:

1 判断一个按键被按下很简单,就是按下前后按键两端的电平状态,即一端被拉低。

注意的是如何去检测整个四行四列的矩阵按键。

首先想到的是,去检测一行,这样比较容易的,初始状态和被按下的状态比较。

然后在成功检测一行被按下的按键的情况下,去实现检测四行,其实就是一行一行的来作为一个整体,先检测第一行,然后检测第二行,直到检测完第四行,那么所有的按键就被检测完成了。当然,这个过程是一个整体。


2   再者,检测值是要清楚的,就是要清楚,当第一行的第一个按键被按下后,P3口的值是多少,这个要清楚,因为这个是判断按键被按下的根据。例如设定第一行为低电平时,第一个按键被按下,那么P3的值则为0xee......


3  程序中判断按键被按下的代码可以改成:

(状态1,第一行设定为低电平时)

   P3=0xfe;
    temp=P3;
    temp=temp&0xf0;
    if(temp!=0xf0)   //即有按键被按下。

0 0
原创粉丝点击