独立按键消抖与松手检测

版权声明:本文为博主原创文章,未经博主允许不得转载。 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

猜你喜欢

转载自blog.csdn.net/weixin_41572450/article/details/78966505