原理
什么叫矩阵键盘呢?
33
这里要想形成4*4的矩阵键盘就需要将J5跳冒的12脚相连。
矩阵键盘的连接是有一定要求的,仔细看图你可以发现P30连接着第一排按键的右边,同理P31-P33都连接这2.3.4行的按键的右边
这里你也可以发现,P44这里连接的是第一列按键的左边,同理,P42.P35.P34都连接的是2.3.4列的按键的左边。
矩阵键盘的扫描可以用行扫描和列扫描,两种的工作原理一样,效果也是一样的。其实分开,也就是先扫描第一行,再扫描第二行。。。最后到第四行。每次扫描和独立键盘的方式是一样的,这样组合起来也就成了矩阵键盘。
下面简单举个例子,理解一下矩阵键盘是如何工作的。
比如,现在使用行扫描的方法。我们现在要检测3第一行的按键,让P30为低电平,然后根据判断P44.P42.P35以及P34的电平即可检测第一行的按键,然后依次让P31为低电平,扫描第二行的按键,再扫描第三行最后第四行。这样就达到了矩阵键盘的目的。
代码
#include "STC15F2K60S2.h"
#define SEL(x) P2 = (P2 & 0x1f) | (x << 5); P2 = (P2 & 0x1f)
#define P0FF P0 = 0xff
typedef unsigned char uchar;
typedef unsigned int uint;
enum{
LED = 4, EXT, DIG, CODE};
sbit BP = P0^6; sbit RY = P0^4;
uchar code r[] = {
0xfe, 0xfd, 0xfb, 0xf7};
sbit K1 = P3^7; sbit K2 = P3^6; sbit K3 = P3^5; sbit K4 = P3^4;
enum{
KS_GET, KS_ASSIGN, KS_WAITDEAL}KeyState = KS_GET;
uchar TempKey = 0,Key = 0, KeyCnt = 0;
uint HoldCnt = 500;
uchar i = 0;
uchar GetKey()
{
uchar i = 0;
uchar KeyValue = 0;
for(i=0; i < 4; i++)
{
P3 = r[i];
if(K1 == 0) {
KeyValue = 4*i+1; break;}
else if(K2 == 0){
KeyValue = 4*i+2; break;}
else if(K3 == 0){
KeyValue = 4*i+3; break;}
else if(K4 == 0){
KeyValue = 4*i+4; break;}
}
return KeyValue;
}
void Init()
{
P0FF;
SEL(LED);
BP = 0;RY = 0;
SEL(EXT);
}
void Timer1Init(void) //2毫秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x9A; //设置定时初值
TH1 = 0xA9; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
//加上
ET1 = 1; //允许定时器1中断
EA = 1; //全局允许中断开启
}
void Timer1Handle() interrupt 3
{
switch(KeyState)
{
case KS_GET:
TempKey = GetKey();
KeyState = KS_ASSIGN;
KeyCnt = 10;
break;
case KS_ASSIGN:
if(KeyCnt != 0)
{
KeyCnt--;
}
else if(TempKey == GetKey())
{
if(TempKey != Key)
{
Key = TempKey;
KeyState = KS_WAITDEAL;
}
else if(HoldCnt-- != 0);
else
{
Key = TempKey;
KeyState = KS_WAITDEAL;
HoldCnt = 500;
}
}
else
{
KeyState = KS_GET;
}
break;
}
}
void main()
{
Init();
Timer1Init();
while(1)
{
if(KeyState == KS_WAITDEAL)
{
switch(Key)
{
case 1:
P0 = 0xfe;
SEL(LED);
break;
case 2:
P0 = 0xfd;
SEL(LED);
break;
case 7:
P0 = 0xfb;
SEL(LED);
break;
case 11:
P0 = 0xf7;
SEL(LED);
break;
}
KeyState = KS_GET;
}
}
}
重要部分
uchar code r[] = {
0xfe, 0xfd, 0xfb, 0xf7};
uchar GetKey()
{
uchar i = 0;
uchar KeyValue = 0;
for(i=0; i < 4; i++)
{
P3 = r[i];
if(K1 == 0) {
KeyValue = 4*i+1; break;}
else if(K2 == 0){
KeyValue = 4*i+2; break;}
else if(K3 == 0){
KeyValue = 4*i+3; break;}
else if(K4 == 0){
KeyValue = 4*i+4; break;}
}
return KeyValue;
}
r数组的含义就是行的意思(row),其余的地方和独立按键都是一样的,只有这里不同。这里遵循的规则就是,每次在一次按键扫描中,分为四次扫,每次扫一行。
比如扫第一行P3 = 0xfe,这个时候P30为0,其余全部为高。然后这个时候去判断K1-K4就是在判断第一行从左到右四个按键的情况。当第一个键返回的时候,返回的值就是4*0+1=1.其余情况以此类推!
注意事项
有个需要注意的就是P34引脚用作NE555检测的时候,这根线是不能用做按键检测的。因此比赛方为了既考矩阵键盘又要考NE555的话,就会让矩阵键盘不是4*4的,比如在这个4*4的键盘上面进行裁剪,让你做2*2或者3*3的矩阵键盘。这个时候只要你掌握了原理,随便它怎么靠,你都能够很快写出来的。
希望读者能自行完成一个3*3的键盘。