一.介绍
假如我们有30个按键,要实现识别所有按键的组合短按,组合长按,组合连续按,等等,按规则写出来非常麻烦,我们使用宏定义,整型变量按位检测就很方便。
二.按键基本功能
首先需要基本的按键事件输入。
然后通过对按下按键开始计时,后续按下重置计时。循环检测长按事件。
松开按键触发短按判断。
任意时刻松开触发按键后,后续按下会无效,直到所有按键松开。
三.上程序源码:
key.c:
#include "key.h"
void key_init(void){ //初始化按键
GPIO_InitType GPIO_InitStructure;
SysCtrl_PeripheralClockCmd(CLOCK_PERIPH_GPIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = KEY_IO_MASK;
GPIO_InitStructure.GPIO_Mode = GPIO_Input;
GPIO_InitStructure.GPIO_Pull = DISABLE;
GPIO_InitStructure.GPIO_HighPwr = DISABLE;
GPIO_Init(&GPIO_InitStructure);
}
static void key_send(uint32_t key){
uint8_t * p = (uint8_t *)&key;
uint8_t temp[7] = {0};
temp[0] = 0xAA;
temp[1] = p[0];
temp[2] = p[1];
temp[3] = p[2];
temp[4] = p[3];
temp[5] = p[0]+p[1]+p[2]+p[3];
temp[6] = 0xAA;
ble_trans_data(7,temp);
printf(" [key]:%d \r\n",key);
}
static uint32_t key_all = 0,key_now = 0,clean = 0,count = 0,long_cnt = 0;
static uint32_t key_Always = 0,Alcount = 0;
void key_process(void){
static uint8_t key[5] = {0};
key[0] = !GPIO_ReadBit(GPIO_Pin_8); //电源
//key[1] = !GPIO_ReadBit(GPIO_Pin_0); //上
key[1] = !GPIO_ReadBit(GPIO_Pin_6); //测试
key[2] = !GPIO_ReadBit(GPIO_Pin_1); //下
key[3] = !GPIO_ReadBit(GPIO_Pin_2); //左
key[4] = !GPIO_ReadBit(GPIO_Pin_3); //右
//=====================================================================按键长短按
key_now = ((key[0]<<yr_key_power)|(key[1]<<yr_key_up)|(key[2]<<yr_key_down)|(key[3]<<yr_key_left)|(key[4]<<yr_key_right));
if(key_now != key_all){
if(count++ > delay_t){ //消抖
count = 0; //消抖
if(((key_all&key_now)<key_all)&&clean == 0){//短按松开
key_send(key_all); //短按发送
clean = 1; //松开清除
long_cnt = 0;
}
key_all = key_now;
}
}else if(key_all > 0&&clean == 0){ //长按计时
if(long_cnt++ > delay_long){ //长按触发
key_send(key_all|(1<<yr_L)); //长按松开发送
clean = 1; //长按松开清除
key_Always = key_all; //
long_cnt = 0;
}
}
if(key_now == key_all) count = 0; //消抖
if(key_all == 0) clean = 0;
//===================================================================长按保持
if(key_Always == key_all&&key_Always > 0){
if(Alcount++ > delay_long/10){
Alcount = 0;
key_send(key_all|(1<<yr_AL));
}
}else {
Alcount = 0;
key_Always = 0;
}
//printf(" [%d %d %d %d %d] [key_all %d,key_now %d,clean %d,long_cnt %d]\r\n ",key[0],key[1],key[2],key[3],key[4],key_all,key_now,clean,long_cnt);
}
key.h:
#ifndef __KEY_H_
#define __KEY_H_
#include <stdio.h>
#include "SDK_EVAL_Led.h"
#define WEEKUP_SOURCE (WAKEUP_IO13)
//#define KEY_IO_MASK (GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_8)
#define KEY_IO_MASK (GPIO_Pin_6|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_8) //ps3测试
#define delay_long (3*15*400)
#define delay_t (400)
/************************* KEY VALUE DEFINE *********************/
#define yr_L (0)//长按
#define yr_AL (16)//连续按
#define yr_key_power (1)//电源
#define yr_key_up (2)//上
#define yr_key_down (3)//下
#define yr_key_left (4)//左
#define yr_key_right (5)//右
void key_init(void);
void key_process(void);
#endif
四.如何使用
使用时自定义出需要的按键名称,然后通过按位组合,解析出来。
#define yr_L (0)//长按
#define yr_AL (16)//连续按
#define yr_key_1 (1)//电源
#define yr_key_2 (2)//上
#define yr_key_3 (3)//下
#define yr_key_4 (4)//左
#define yr_key_5 (5)//右
uint8_t key_get_Value(u_int32_t param){
switch(param){
case (1<<yr_key_1): printf("KEY_MENU_S\n"); return KEY_MENU_S;
case (1<<yr_key_2): printf("KEY_POWER_S\n"); return KEY_POWER_S;
case (1<<yr_key_3): printf("KEY_CAMERA_S\n"); return KEY_CAMERA_S;
case (1<<yr_key_4): printf("KEY_OBSERVATION_S\n"); return KEY_OBSERVATION_S;
case (1<<yr_key_5): printf("KEY_RANGING_S\n"); return KEY_RANGING_S;
case ((1<<yr_key_1)|(1<<yr_L)): printf("KEY_MENU_L\n"); return KEY_MENU_L;
case ((1<<yr_key_2)|(1<<yr_L)): printf("KEY_POWER_L\n"); return KEY_POWER_L;
case ((1<<yr_key_3)|(1<<yr_L)): printf("KEY_CAMERA_L\n"); return KEY_CAMERA_L;
case ((1<<yr_key_4)|(1<<yr_L)): printf("KEY_OBSERVATION_L\n"); return KEY_OBSERVATION_L;
case ((1<<yr_key_5)|(1<<yr_L)): printf("KEY_RANGING_L\n"); return KEY_RANGING_L;
case ((1<<yr_key_1)|(1<<yr_key_4)|(1<<yr_L)): printf("KEY_MENU_L_AND_KEY_OBSERVATION_L\n"); return KEY_MENU_L_AND_KEY_OBSERVATION_L;
case ((1<<yr_key_3)|(1<<yr_key_4)|(1<<yr_L)): printf("KEY_CAMERA_L_AND_KEY_OBSERVATION_L\n"); return KEY_CAMERA_L_AND_KEY_OBSERVATION_L;
case ((1<<yr_key_1)|(1<<yr_key_5)|(1<<yr_L)): printf("KEY_MENU_L_AND_KEY_RANGING_L\n"); return KEY_MENU_L_AND_KEY_RANGING_L;
case ((1<<yr_key_2)|(1<<yr_AL)): printf("KEY_POWER_ALWAYS_L\n"); return KEY_POWER_ALWAYS_L;
case ((1<<yr_key_4)|(1<<yr_AL)): printf("KEY_OBSERVATION_ALWAYS_L\n"); return KEY_OBSERVATION_ALWAYS_L;
case ((1<<yr_key_3)|(1<<yr_AL)): printf("KEY_CAMERA_ALWAYS_L\n"); return KEY_CAMERA_ALWAYS_L;
case ((1<<yr_key_5)|(1<<yr_AL)): printf("KEY_RANGING_ALWAYS_L\n"); return KEY_RANGING_ALWAYS_L;
}
return 0;
}