版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41572450/article/details/78966505
记录下最近独立按键消抖和松手检测
我对独立按键的处理思路是
1.获得键值
2.消抖处理
3.松手检测
4.键值解析
1.获得键值
这里把独立按键做个编号,例如有两个按键记为KEY0、KEY1,用一个变量来记录当前按键标记值(比如Cur_Keyval),当KEY0按下,就把Cur_Keyval的bit0置为1,否则清0,当KEY1按下,就把Cur_Keyval的bit1置为1,否则清0.
2.消抖处理
想法是比较当前标记值(Cur_Keyval)和上次标记值(Pre_Keyval),如果相等并且当前标记值不等于无按键按下的标记值时,认为是真的按下,否则认为是抖动。
3.松手检测
4.键值解析
这里写到一起了,松手检测是参考原子stm32教程里面的例程,定义一个static变量来记录上一次按键状态(key_up),只有上一次按键状态是抬起的(key_up=1)才响应键值解析并把key_up清0 ,(这里有个mode,是当mode=1时,每次进去都是key_up=1,相当于上一次都是抬起的,就会一直响应,当mode=0,只有真正抬起后,key_up才=1,达到松手检测效果)
上代码
key.c
#include "key.h"
uint8_t Cur_Keyval=0; //当前按键标记值
uint8_t Pre_Keyval=0; //上次按键标记值
uint8_t key_on=0; //抖动变量 1表示已经抖动
void key_init(void)
{
//初始化GPIO,上拉输入
}
//获得按键标记值
void Get_Keyval(void)
{
if(KEY0==ON_LEVEL)
Cur_Keyval|= KEY0ON_VAL;
else
Cur_Keyval&=~KEY0ON_VAL;
if(KEY1==ON_LEVEL)
Cur_Keyval|= KEY1ON_VAL;
else
Cur_Keyval&=~KEY1ON_VAL;
}
//按键抖动
void Key_filter(void)
{
if(Cur_Keyval == Pre_Keyval && Cur_Keyval != KEYOFF_VAL)
{key_on=1;}
else
{key_on=0;}
Pre_Keyval=Cur_Keyval;
}
//mode=0 有松手检测效果 mode=1无
uint8_t Key_Scan(uint8_t mode)
{
static uint8_t key_up=1; //按键松开标志
if(mode)key_up=1; //1 支持连按
Get_Keyval(); //获得按键标记值
Key_filter(); //按键抖动
if(key_up && key_on)
{
key_up=0;
if(Cur_Keyval==KEY0ON_VAL) return KEY0_PRES;//解析按键
else if(Cur_Keyval==KEY1ON_VAL) return KEY1_PRES;
}
else if(Cur_Keyval == KEYOFF_VAL)
{
key_up=1;
}
return NONE_PRESS;
}
key.h
#ifndef __KEY_H
#define __KEY_H
#include "csa37fx60.h" //
#define KEY_0 GPIO_PA1 //
#define KEY_1 GPIO_PA4 //
#define KEY0 GPIO_ReadInputDataBit(KEY_0)
#define KEY1 GPIO_ReadInputDataBit(KEY_1)
//独立按键按下电平
#define ON_LEVEL 0
//没有按键按下标记值
#define KEYOFF_VAL 0x00
//各个独立按键按下标记值
#define KEY0ON_VAL 0x01
#define KEY1ON_VAL 0x02
#define NONE_PRESS 0 //没有按键按下返回值
#define KEY0_PRES 1 //KEY0按下返回值
#define KEY1_PRES 2 //KEY1按下返回值
void key_init(void);
uint8_t Key_Scan(uint8_t mode);
#endif