我所知道的矩阵键盘工作原理

最近在笔记本EC中使用到了18*8矩阵键盘,我原本以为这应该是很简单的实现原理:按下某个键时有一根行线与一根列线电平变化。简单地举个例子,比如18根列线为C0~C178根行线和R0~R7, 初始时所有的26线全为高电平, 按下按键‘A’时R0C0为低电平,按下按键‘B’时R0C1为低电平, 按下按键‘C’时R1C0为低电平, 按下按键‘D’时R1C1和低电平…,以此类推。这个实现原理看起来似乎非常准确又设计简便。然而, 仔细想想这样的设计在检测多个按键同时按下时是有BUG存在的,比如当检测到R0R1C0C14根线全为低时你根本无法判断‘A’,‘B’,‘C’,‘D’这4个按键到底被同时按了几个, ADABDACDBCABCBCDABCD这些组合都是可能的。

为了解决这个问题,矩阵键盘采用了另外一种方式,逐行扫描方式,为方便理解,我们采用4*4的矩阵键盘来分析。首先看下原理图:

 

P10~P134根设计成输出口的行线,P14~P174根设计成输入口的列线。如此的设计该怎样区别是什么按键被按下了呢?判断方法如下:

1.  扫描P10行:

a)         P10~P13输出为0 111

b)        P14~P174个输入口的电平。如果S0~S3都没被按下,则因为P14~P17都是上拉到VCC,所以都为高;如果有1个被按下比如是S1,则因P10输出为低,所以S1开关导通后P16应为低;如果有2个按下比如是S1S2,则P16P17应为低。

c)        根据P14~P17的电平即可得知S0~S3中共有几个按键被按下。

2.  扫描P11行:

a)            P10~P13输出为1 011

b)        P14~P174个输入口的电平。如果S4~S7都没被按下,则因为P14~P17都是上拉到VCC,所以都为高;如果有1个被按下比如是S5,则因P10输出为低,所以S5开关导通后P16应为低;如果有2个按下比如是S5S6,则P16P17应为低。

c)        根据P14~P17的电平即可得知S4~S7中共有几个按键被按下。

3.  扫描P12行:将P10~P13输出为1 101,其他步骤同上。

4.  扫描P13行:将P10~P13输出为1 110,其他步骤同上。

通过这4行的扫描,我们已经能够确定S0~S1516个按键当前的状态了。

 

C语言实现如下:

void key_scan()   //键盘扫描函数

{

    int i;

unsigned char n, row, rowmask ;

row = 1;

for(i=0; i<4; i++)  //共扫描4条行线

{

    rowmask = ~(row<时,rowmask=0xfe, i=1rowmask=0xfd…

P1=rowmask;

n = P1;

n &= 0xf0;

if(n != 0xf0)

{

        Delay();//防抖动

        P1=rowmask;

n = P1;

n &= 0xf0;

if(n != 0xf0)

{

        switch(n)

        {

        case 0xE0://S(3+i*4)按下

          break;

        case 0xD0://S(2+i*4)按下

          break;

        case 0xB0://S(1+i*4)按下

          break;

        case 0x70://S(0+i*4)按下

          break;

        }

}

}

    }

}

void Delay() //延时函数

{

    int i,j;

for(i=0; i<100; i++)

{

    for(j=0; j<100; j++);

}

}

你可能感兴趣的:(底层及驱动开发)