超屌的按键处理方式(类思想,状态机,高移植性)超屌的按键处理方式(类思想,状态机,高移植性)
怎么能把按键处理玩出花?按键处理作为一个基础入门实验,大部分人在刚接触单片机的时候都会自己写一份,开始我们利用延时消抖,后来发现在大的工程
当中,延时消抖在没有加入操作系统来调度的情况下,无疑是一种很浪费资源的做法。再后来我们开了定时器去扫描,确实比较靠谱,但是一但设计到复杂的
组合按键,长按短按双击等,就需要我们去费很大的功夫去进行逻辑判断。
在网上看到了很多很棒的方法,即把底层寄存器的配置抽离出来,采用状态机思想去进行逻辑判断,可以有效地实现各种复杂的按键处理。借鉴这种思想,完
成了自己的按键处理函数。这里直接上代码,再讲解。
.h 头文件:头文件:
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
/**********************************************************************/
#define KEY0_RCCclock RCC_AHB1Periph_GPIOE
#define KEY0_PinPort GPIOE
#define KEY0_WhichPin GPIO_Pin_2
#define KEY0_PinStatus GPIO_PuPd_UP //上拉
#define KEY0_shortPress Key0_ShortCallback
#define KEY0_longPress Key0_LongCallback
#define KEY1_RCCclock RCC_AHB1Periph_GPIOE
#define KEY1_PinPort GPIOE
#define KEY1_WhichPin GPIO_Pin_3
#define KEY1_PinStatus GPIO_PuPd_UP //上拉
#define KEY1_shortPress Key1_ShortCallback
#define KEY1_longPress Key1_LongCallback
/**********************************************************************/
#define KEY_MAXNUM 4 //最大按键数
#define KEY_TIMER_MS 2 //扫描时间间隔
#define KEY_DELAY_MS 10 //消抖完成标志位
#define KEY_PRESS_STATUS 0 //即按下标志位
#define KEY_LONG_STATUS (1000/KEY_DELAY_MS*3) //即按下3s及判定为长按
#define KEY_DOUBLE_HIT_MAX (100/KEY_DELAY_MS*3) //连击判定时间最大值为300ms
//#define KEY_DOUBLE_HIT_MIN (100/KEY_DELAY_MS*1) //连击判定事件最小值为100ms
/**********************************************************************/
#define KEY_NODOWN 0x0000 //无按键按下
#define KEY_DOWN 0x1000 //有按键按下
#define KEY_UP 0x2000 //按键短按标志位
#define KEY_LIAN 0x4000 //按键连按标志位
#define KEY_LONG 0x8000 //按键长按标志位
/**********************************************************************/
/*
这三个函数的作用分别是:
1、设置a某一位的值 G_SET_BIT
2、清楚a某一位的值 G_CLEAR_BIT
3、获得a某一位的值 G_IS_BIT_SET
*/
#define G_SET_BIT(a,b) (a |= (1 << b))
#define G_CLEAR_BIT(a,b) (a &= ~(1 << b))
#define G_IS_BIT_SET(a,b) (a & (1 << b))
/**********************************************************************/
//定义了一个回调指针,即根据发生的事件,
typedef void (*KeyCallback_Pointer) (void);
/**********************************************************************/
//单个按键对象结构体
__packed typedef struct
{
uint8_t Key_Num;//共有多少个按键对象
uint32_t Key_RccPeriphConfig;//按键对象时钟
GPIO_TypeDef* KeyPort;//按键所在IO口组
uint32_t Key_WhichPin;//第几个IO引脚
GPIOPuPd_TypeDef Key_PinStatus;//IO引脚的状态
KeyCallback_Pointer shortPress;//定义一个函数指针指向短按回调函数
KeyCallback_Pointer longPress;//定义一个函数指针指向长按回调函数
}keyTypeDef_t;//单个按键对象结构体!
/**********************************************************************/
//多个按键对象结构体(总)
__packed typedef struct
{
u8 KeyTotolNum; //按键总数累计
keyTypeDef_t* singleKey;//按键对象的指针!
}keysTypeDef_t;//多个按键对象结构体!
/**********************************************************************/
//双击枚举!
typedef enum {Keyd_Wait_Flag = 0,Keyd_End_Flag = 1,Keyd_IDLE_Flag = 2}keyd_Status;
//双击结构体!
typedef struct
{
评论0