基础知识:
按键电路图:
消抖处理:
程序示意图:
注意事项:
- 一个好的按键程序一定要实现消抖
- 能够判断按键状态,按下和弹起
- 程序不能阻塞程序,不用delay消抖,而是使用定时器
独立按键状态机法(详细解释在注释里):
#define KEY_NO 0 //无按键状态,用于判断是否按下
#define KEY_DOWN 1 //有按键按下状态,判断是否抖动
#define KEY_UP 2 //等待松手状态,判断是否弹起
unsigned char vBTN_Read(void)
{
static unsigned char key_state=0;//定义key_state为静态变量,用于保存每次按键的状态
unsigned char key_io=0,key_val=0; //key_io:读取的IO状态;key_val:返回的键值
key_io=P3&0x0f; //对P3读回来的高四位清零,屏蔽不关心的状态
switch(key_state)
{
case KEY_NO: //无按键状态,用于判断是否按下
if(key_io!=0x0f) key_state = KEY_DOWN;
break;
case KEY_DOWN:
if(key_io!=0x0f)//有按键按下状态,判断是否为抖动
{
if(key_io==0x0e) key_val = 7; //S7
if(key_io==0x0d) key_val = 6; //S6
if(key_io==0x0b) key_val = 5; //S5
if(key_io==0x07) key_val = 4; //S4
key_state = KEY_UP;
}
else
key_state = KEY_NO;
break;
case KEY_UP: //等待松手状态,判断是否弹起
if(key_io==0x0f) key_state = KEY_NO;
break;
}
return key_val; //返回键值
}
注意:要把vBTN_Read函数放在定时器中断里面,每隔10ms执行一次,循环判断
程序案例:(每隔10ms读取一次键值,并把读到的键值赋值给key_val,可以利用读到的键值进行各种操作)
unsigned char cnt_key;
void vBTN_Process(void)
{
unsigned char key_val;
if(cnt_key>=10)
{
cnt_key=0;
key_val=vBTN_Read();
}
}
void vTimer2_ISR(void) interrupt 12
{
cnt_key++;
}
状态机法比较好理解,但是程序过于冗杂,不便于记忆。下一篇将给大家介绍三行按键法,顾名思义,就是只需要写三行程序,解放双手,简单又便于记忆。