独立按键就是每一个按键链接一个 MCU的引脚,每个按键之间没有任何关系,和LED 的操作类似,不过LED是写高低电平,而独立按键是读高低电平的值。如定义了独立按键为sbit K1=P3^1; 这个K1的值就是独立按键的值,当K1为0时(低电平)标识按键被按下,当K1位1时(高电平)标识按键被释放。
下面是利用前面的LED和数码管实现的独立按键功能,当每次按下K1时,LED1变为相反的状态(亮变灭,灭变亮),数码管1的数字加1;按下K2时,LED2变为相反的状态,数码管2的数字加1;
#include<reg52.h>
typedef unsigned char u8;
typedef unsigned int u16;
#define TUBE P0
sbit LED1=P2^0;
sbit LED2=P2^1;
sbit S1=P2^2;
sbit S2=P2^3;
sbit S3=P2^4;
sbit K1=P3^1;
sbit K2=P3^0;
u8 code digit_table[]={
0x3f/*0*/, 0x06/*1*/, 0x5b/*2*/, 0x4f/*3*/,
0x66/*4*/, 0x6d/*5*/, 0x7d/*6*/, 0x07/*7*/,
0x7f/*8*/, 0x6f/*9*/, 0x77/*A*/, 0x7c/*b*/,
0x39/*C*/, 0x5e/*d*/, 0x79/*E*/, 0x71/*F*/,
0x00
};
void select_tube(u8 n)
{
S1=n%2;
S2=n/2%2;
S3=n/4%2;
}
void delay_ms(u16 n)
{
u8 i;
while(n--)
{
i = 111;
while(i--);
}
}
void display(u8 num)
{
select_tube(0);
TUBE=digit_table[num];
}
void display2(u8 num)
{
select_tube(1);
TUBE=digit_table[num];
}
void key_proc()
{
static u8 num=0;
if(K1==0)
{
delay_ms(10); //消除抖动延时
if(K1==0) //第二次是抖动之后检查,如果是还是按下的,说明确实是按下了
{
LED1=~LED1;
display(num);
num=(num+1)%16;
}
while(!K1); //等待K1变为1,即按键释放
}
}
void key2_proc()
{
static u8 num=0;
if(K2==0)
{
delay_ms(10);
if(K2==0)
{
LED2=~LED2;
display2(num);
num=(num+1)%16;
}
while(!K2);
}
}
void main()
{
while(1)
{
key_proc();
key2_proc();
}
}
从上面的代码可以看出来,获取按键状态的方法就是不停的读取K1的状态,当状态变为0时,说明被按下,然后继续检查,如果按键变为1则表示按键被释放。
上图是理想波形和实际波形的对比,实际波形中在变化的时候存在抖动,这是判断按键的值是可能不准确的,所以需要消除抖动。有两种方式可以消除抖动,一种是 硬件消抖,一种是软件消抖;我们这里只讲软件消抖,消抖的原理就是当检测到按下时,延时一段时间,跳过抖动的这段波形,然后再次检查,这是检查到的值就是抖动之后的了。
上面的代码还有问题,就是两个数码管不能同事显示,每次只能显示按键对应的数码管,你知道如何让两个同事显示吗?