独立按键消抖与松手检测

记录下最近独立按键消抖和松手检测
我对独立按键的处理思路是

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
  • 11
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一个用定时器实现按键检测的程序,包含消抖和松手检测功能: ```c #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> #define KEY_UP 72 #define KEY_DOWN 80 #define KEY_LEFT 75 #define KEY_RIGHT 77 #define KEY_ENTER 13 // 定时器回调函数 VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { // 检测按键松手 if(GetAsyncKeyState(VK_UP) & 0x8000) { Sleep(10); if(!(GetAsyncKeyState(VK_UP) & 0x8000)) PostQuitMessage(0); } } // 按键消抖 int key_debounce(void) { int key; do { key = _getch(); Sleep(10); } while(_kbhit()); return key; } int main() { UINT_PTR timer_id; MSG msg; int key; // 创建定时器 timer_id = SetTimer(NULL, 0, 10, TimerProc); while(GetMessage(&msg, NULL, 0, 0)) { if(msg.message == WM_TIMER) { TranslateMessage(&msg); DispatchMessage(&msg); } else if(msg.message == WM_QUIT) { key = key_debounce(); switch(key) { case KEY_UP: printf("Up key released.\n"); break; case KEY_DOWN: printf("Down key released.\n"); break; case KEY_LEFT: printf("Left key released.\n"); break; case KEY_RIGHT: printf("Right key released.\n"); break; case KEY_ENTER: printf("Enter key released.\n"); break; default: printf("Unknown key released.\n"); break; } break; } } // 销毁定时器 KillTimer(NULL, timer_id); return 0; } ``` 在上面的程序中,我们使用了Windows API中的SetTimer函数创建定时器,并在定时器回调函数中检测按键是否松开。我们还使用了消息循环来获取消息,并在用户松开按键时输出相应的消息。程序运行时,可以检测用户是否按下了方向键或回车键,并在用户松开按键时输出相应的消息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值