通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,电压信号如下图所示:
由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开,因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间的长短由按键的机械特性决定的,一般为 5ms 到 10ms。按键稳定闭合时间的长短则由操作人员的按键动作决定的,一般为零点几秒至数秒。按键抖动会引起按键被误读多次。为了确保 CPU 对按键的一次闭合仅作一次处理,必须进行消抖。
按键消抖有两种方式,一种是硬件消抖,另一种是软件消抖。
通过开发板上的独立按键 K1 控制 D1 指示灯亮灭。
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit KEY1 = P3^1;
sbit KEY2 = P3^0;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;
sbit LED1 = P2^0;
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 1
void delay(u16 us)
{
while(us--);
}
//低电平代表按下 高电平代表没有按下
u8 key_scan(u8 mode)
{
static u8 key = 1; // key用来标志 单次扫描0 还是 连续扫描1
if(mode) key = 1;
if(key == 1 && (KEY1 == 0 || KEY2 == 0 || KEY3 == 0 || KEY4 == 0))
{
delay(1000); //消抖
key = 0;
if(KEY1 == 0)
{
delay(1000);
return KEY1_PRESS;
}
else if(KEY2 == 0)
return KEY2_PRESS;
else if(KEY3 == 0)
return KEY3_PRESS;
else if(KEY4 == 0)
return KEY4_PRESS;
}
else if(KEY1 == 1 && KEY2 == 1 && KEY3 == 1 && KEY4 == 1)
{
key = 1;
return KEY_UNPRESS;
}
}
void main()
{
u8 key = 0;
while(1)
{
key = key_scan(0);
if(key == KEY1_PRESS)
LED1 = !LED1;
}
}