1. 程式人生 > >獨立按鍵消抖與鬆手檢測

獨立按鍵消抖與鬆手檢測

記錄下最近獨立按鍵消抖和鬆手檢測

我對獨立按鍵的處理思路是

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