电路原理图:
编程原理:
1.矩阵键盘是低电平接通
2.先给高四位(P44,P42,P35,P34)赋值为0 ,采用字节赋值,检测低四位哪一位是0,确定按键所在的行
3.再给低四位(P30,P31,P32,P33)赋值为0 ,采用字节赋值,检测高四位哪一位是0,确定按键所在的列
4.根据行和列,确定按键的位置
编程注意事项:
- 需要有松手检测
- 每次按下要能单次触发
- 不要有delay()函数,会阻塞程序
程序源码:
1.获取键值函数
unsigned char KBD_KeyIO()
{
unsigned char key_number=0;
//列扫描,低四位输出0,读取高四位的值
P3=0xf0;P4=0xff;
if(P44==0) key_number=4;
if(P42==0) key_number=8;
if(P35==0) key_number=12;
if(P34==0) key_number=16;
//行扫描,高四位输出0,读取低四位的值
P3=0x0f;P4=0x00;
if(P33==0) key_number= key_number+0;
if(P32==0) key_number= key_number+1;
if(P31==0) key_number= key_number+2;
if(P30==0) key_number= key_number+3;
return key_number; //返回键值
}
2.矩阵键盘(状态机法)
与独立按键同理,KBD_Read_State()函数也需要放在中断函数里执行
#define KEY_NO 0; //无按键状态,判断是否按下
#define KEY_DOWN 1; //有按键按下状态,判断是否为抖动
#define KEY_UP 2; //等待松手状态,判断是否弹起
unsigned char KBD_Read_State()
{
static unsigned char key_state=0; //用于保存每次按键的状态
unsigned char key_return=0; //返回的键值
unsigned char key_io=0; //读取的IO状态
key_io=KBD_KeyIO(); //上面的获取键值函数
switch(key_state)
{
case 0:
if(key_io) //无按键状态,用于判断是否按下
key_state=KEY_DOWN;
break;
case 1:
if(key_io) //有按键按下状态,判断是否为抖动
{
key_state=KEY_UP;
key_return=key_io;
}
else
key_state=KEY_NO;
break;
case 2:
if(key_io==0) //等待松手状态,判断是否弹起
{
key_state=KEY_NO;
}
}
return key_return;
}
3.简单程序示例
unsigned char cnt_kbd;
unsigned char kbd_val;//保存得到的键值
void KBD_Process()
{
if(cnt_kbd>=10)
{
cnt_kbd=0;
kbd_val=KBD_Read_State();//也就是每10ms读取一次键值
//可以利用得到的键值,执行各种操作
}
}
void vTimer2_ISR(void) interrupt 12
{
cnt_kbd++;
}
最后,用状态机法写矩阵键盘还是有点繁琐的。同样的,三行按键法也可以用来写矩阵键盘,只需要三行,可以大大减少代码量。