键盘
独立键盘和矩阵键盘示意图
独立键盘:每个按键占用一个IO口,当按键数量较多时,IO口利用效率不高,但程序简单,适用于所需按键较少的场合;
矩阵键盘:电路连接复杂,但提高了IO口利用率,软件编程较复杂。适用于使用大量按键的场合;
独立键盘
准双向IO口
按键一端与IO口连接,另外一端接地。通过控制IO口输出高电平即可检测按键是否按下,当按下时IO口会被拉低,松开后IO口回到高电平。
检测s2按键被按下几次的代码
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管位选
sbit key_s2 = P3^0;//独立按键
uchar num;//数码管显示的值
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void main()
{
WE = 1;//打开位选锁存器
P0 = 0xfe; //1111 1110 对应WE8~WE1 选中第一个数码管
WE = 0;//锁存位选数据 数据已经送过去了 输入输出之间断开
while(1)
{
if(key_s2 == 0)
{
delay(20);//按键消抖
if(key_s2 == 0)
{
num++;
if(num == 10) num = 0;
// DU = 1;//打开段选锁存器
// P0 = table[num];
// DU = 0;//锁存
while(!key_s2);//松手检测,没有松手就一直在这里循环
}
DU = 1;//打开段选锁存器
P0 = table[num];
DU = 0;//锁存
//松手后刷新显示
}
}
}
矩阵键盘
矩阵键盘识别方法
矩阵键盘识别相对于独立键盘要复杂一些。右图矩阵键盘一共有4行和4列一共16个按键组成。
确定矩阵键盘上哪一个按键被按下可以采用列扫描和行扫描。
列扫描时先把接在列上面的所有IO口拉高 “1”,接在行上的所有IO置低 “0”。当其中有一列内任何一个按键按下那么整条列线都会被拉低。
行扫描时反过来。
20按键键盘扫描
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管位选
uchar num;//数码管显示的值
uchar KeyValue=20;//按键初始值
uchar code table[]= {
//0 1 2 3 4 5 6 7 8
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
//9 A B C D E F H L
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x76, 0x38,
//n u - 熄灭
0x37, 0x3E, 0x40, 0x00 };
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void KeyScan()
{
//4*4独立键盘扫描
P3 = 0xf0;//1111 0000
if(P3 != 0xf0)
{
delay(10);//消抖10ms
if(P3 != 0xf0)
{
switch(P3) //判断列
{
case(0xe0): KeyValue = 0; break;//第一列被按下
case(0xd0): KeyValue = 1; break;//第二列被按下
case(0xb0): KeyValue = 2; break;//第三列被按下
case(0x70): KeyValue = 3; break;//第四列被按下
}
P3 = 0x0f;//行扫描
switch(P3) //判断行
{
case(0x0e): KeyValue = KeyValue ; break;//第一行被按下
case(0x0d): KeyValue = KeyValue+4 ; break;//第二行被按下
case(0x0b): KeyValue = KeyValue+8 ; break;//第三行被按下
case(0x07): KeyValue = KeyValue+12 ; break;//第四行被按下
}
while(P3 != 0x0f);//松手检测
}
}
//独立键盘扫描
P3 = 0xff;
if(P3!=0xff)
{
delay(10);
if(P3!=0xff)
{
switch(P3) //判断列
{
case(0xfe): KeyValue = 16; break;//s2被按下
case(0xfd): KeyValue = 17; break;//s3被按下
case(0xfb): KeyValue = 18; break;//s4被按下
case(0xf7): KeyValue = 19; break;//s5被按下
}
while(P3!=0xff);//松手检测
}
}
}
void main()
{
WE = 1;//打开位选锁存器
P0 = 0xfe; //1111 1110 对应WE8~WE1 选中第一个数码管
WE = 0;//锁存位选数据 数据已经送过去了 输入输出之间断开
while(1)
{
KeyScan();//20按键键盘扫描
DU = 1;//打开段选锁存器
P0 = table[KeyValue];
DU = 0;//锁存
}
}