下面主要讲一下按键的原理:
1.独立键盘

对其来说,如果你检验KeyIn口为高电平,说明按键弹起,相反的,KeyIn口为低电平,则说明按键按下。
2.矩阵键盘

KeyOut1引脚输出高电平,其余KeyOut引脚输出低电平,这时候,我们按下Key1。检测4个KeyIn引脚时,只有KeyIn1引脚为低电平,其余为高电平,这时我们就可以检测是哪一个按键按下。
由于机械键盘的特性,我们需要对按键扫描的时候实行消抖处理。
这是一个不消抖的程序,目的是实现按键按一下,数字加1
#include <reg52.h>
sbit KeyS2=P3^4;
sbit KeyS3=P3^5;
sbit KeyS4=P3^6;
sbit KeyS5=P3^7;
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code LedChar[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,};
unsigned char num=0;
void main()
{
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=LedChar[num];
dula=0;
P3=0xff;
while(1);
{
if(KeyS2==0)
{
num++;
if(num>=10)
num=0;
dula=1;
P0=LedChar[num];
dula=0;
while(!KeyS2);
}
}
在下载到单片机的时候,我们会发现,有时你按一下,数码管跳动的数字并非一个,有时会有多个。我们在按下的时候,KeyIn引脚接收到的信号是这样的111111100101000000000010010111111,我们发现其实在高低电平转化的时候会有高低电平的跳动,这就是抖动。那么如何消抖呢?
我们有两种方式消抖
①延时函数
当我们判断KeyS2==0之后,延时10ms,再次判断KeyS2是否为0。消除按下时的抖动,当弹起时,会有10010111的抖动,当再次进入if(KeyS2==0)判断后,延时后,KeyS2=1;这时消除了弹开时的抖动。
程序如下:
#include <reg52.h>
sbit KeyS2=P3^4;
sbit KeyS3=P3^5;
sbit KeyS4=P3^6;
sbit KeyS5=P3^7;
sbit d1=P1^0;
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code LedChar[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};
unsigned char num=0;
void delay();
void main()
{
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=LedChar[num];
dula=0;
P3=0xff;
while(1)
{
if(KeyS2==0)
{
delay();
if(KeyS2==0)
{
num++;
if(num>=10)
num=0;
dula=1;
P0=LedChar[num];
dula=0;
while(!KeyS2);
}
}
}
}
void delay()
{
unsigned int i=1000;
while(i--);
}
但是,延时消抖也给我们了麻烦,例如在程序执行的过程中反复的延时,会对程序执行的过程有很大的难读性。
这时我们选用定时器消抖:
2.定时器消抖
我们只需要给主函数一个确定按键按下的标志,检验按键按下在定时器函数中完成。
程序如下:
#include <reg52.h>
sbit KeyS2=P3^4;
sbit KeyS3=P3^5;
sbit KeyS4=P3^6;
sbit KeyS5=P3^7;
sbit d1=P1^0;
sbit dula=P2^6;
sbit wela=P2^7;
bit flag=0;
unsigned char code LedChar[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};
unsigned char num=0;
void delay();
void main()
{
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=LedChar[num];
dula=0;
P3=0xff;
TMOD=0x01;
TH0=0xb8;
TL0=0x00;
TR0=1;
EA=1;
ET0=1;
while(1)
{
if(flag==1)
{
flag=0;
num++;
if(num>=10)
{
num=0;
}
dula=1;
P0=LedChar[num];
dula=0;
}
}
}
void Key_Test() interrupt 1
{
static unsigned char cnt;
TH0=0xb8;
TL0=0x00;
cnt++;
if(KeyS2==0)
{
if(cnt>=10)
{
cnt=0;
if(KeyS2==0)
{
flag=1;
}
}
}
}