键盘中按键数量较多时,为了减少IO口占用,将按键排列成矩阵形式
采用逐行或逐列的“扫描”,就可以读出任何位置的按键状态
- 数码管扫描——输出扫描
- 矩阵键盘扫描——输入扫描
共性:减少IO口占用
使用按列扫描:
P10-P13控制列,P14-P17控制行
unsigned char MatrixKey(){
unsigned char KeyNumber = 0;
P1 = 0xff;
P1_3 = 0; // 扫描第一列
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 1;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 5;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 9;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 13;}
P1 = 0xff;
P1_2 = 0; // 扫描第二列
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 2;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 6;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 10;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 14;}
P1 = 0xff;
P1_1 = 0; // 扫描第三列
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 3;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 7;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 11;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 15;}
P1 = 0xff;
P1_0 = 0; // 扫描第四列
if(P1_7 == 0){Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 4;}
if(P1_6 == 0){Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 8;}
if(P1_5 == 0){Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 12;}
if(P1_4 == 0){Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 16;}
return KeyNumber;
}
但是在我的单片机上这个代码运行延时太高,按下按钮后要等上好几秒才行,所以使用教程自带函数:
#include <REGX52.H>
void delay_10us(unsigned int ten_us)
{
while(ten_us--);
}
unsigned char key_matrix_flip_scan()
{
static unsigned char key_value=0;
P1=0x0f;//给所有行赋值0,列全为1
if(P1!=0x0f)//判断按键是否按下
{
delay_10us(1000);//消抖
if(P1!=0x0f)
{
//测试列
P1=0x0f;
switch(P1)//保存行为0,按键按下后的列值
{
case 0x07: key_value=1;break;
case 0x0b: key_value=2;break;
case 0x0d: key_value=3;break;
case 0x0e: key_value=4;break;
}
//测试行
P1=0xf0;
switch(P1)//保存列为0,按键按下后的键值
{
case 0x70: key_value=key_value;break;
case 0xb0: key_value=key_value+4;break;
case 0xd0: key_value=key_value+8;break;
case 0xe0: key_value=key_value+12;break;
}
while(P1!=0xf0);//等待按键松开
}
}
else
key_value=0;
return key_value;
}