按键实现短按、长按、双击、长按抬起
按键这是我早就想尽可能完善下各种不同的事件,以达到更少的按键实现更多的功能的目的。项目需要用到四个独立按键+LCD屏幕做各种界面的显示、切换、上下选择等操作。
采用MCU内部的上拉输入,没有按键按下的时候全是1,按键按下变成0。
这个项目是使用32去做的,因此是基于32去开发的,移植到C51上也是一样适用的,逻辑都是一样的。
引脚的定义:
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_PIN GPIO_PIN_0
#define KEY1_GPIO_MODE GPIO_Mode_IPU
#define KEY1_READ GPIO_ReadInputDataBit(KEY1_GPIO_PORT, KEY1_GPIO_PIN)#define KEY2_GPIO_PORT GPIOA
#define KEY2_GPIO_PIN GPIO_PIN_1
#define KEY2_GPIO_MODE GPIO_Mode_IPU
#define KEY2_READ GPIO_ReadInputDataBit(KEY2_GPIO_PORT, KEY2_GPIO_PIN)#define KEY3_GPIO_PORT GPIOA
#define KEY3_GPIO_PIN GPIO_PIN_2
#define KEY3_GPIO_MODE GPIO_Mode_IPU
#define KEY3_READ GPIO_ReadInputDataBit(KEY3_GPIO_PORT, KEY3_GPIO_PIN)#define KEY4_GPIO_PORT GPIOA
#define KEY4_GPIO_PIN GPIO_PIN_3
#define KEY4_GPIO_MODE GPIO_Mode_IPU
#define KEY4_READ GPIO_ReadInputDataBit(KEY4_GPIO_PORT, KEY4_GPIO_PIN)
GPIO的初始化
void Key_GPIOConfig(void){
GPIO_InitType Key_GPIOType;
Key_GPIOType.Pin = KEY1_GPIO_PIN;
Key_GPIOType.GPIO_Mode = KEY1_GPIO_MODE;
GPIO_InitPeripheral(KEY1_GPIO_PORT, &Key_GPIOType);
Key_GPIOType.Pin = KEY2_GPIO_PIN;
Key_GPIOType.GPIO_Mode = KEY2_GPIO_MODE;
GPIO_InitPeripheral(KEY2_GPIO_PORT, &Key_GPIOType);
Key_GPIOType.Pin = KEY3_GPIO_PIN;
Key_GPIOType.GPIO_Mode = KEY3_GPIO_MODE;
GPIO_InitPeripheral(KEY3_GPIO_PORT, &Key_GPIOType);
Key_GPIOType.Pin = KEY4_GPIO_PIN;
Key_GPIOType.GPIO_Mode = KEY4_GPIO_MODE;
GPIO_InitPeripheral(KEY4_GPIO_PORT, &Key_GPIOType);
log_i("Key gpio config complete.\r\n");
}
四个按键为了好区分分别是哪个按键被按下或者同时被按下,定义一个KeyVal保存键值做如下拼装:
KeyVal = (KEY4_READ << 3) | (KEY3_READ << 2) | (KEY2_READ << 1) | KEY1_READ;
这样一来KeyVal的低四位每一位可以表示一个按键的状态,即便四个同时按下也能区分出来。也能更加简单的实现组合按键。
头文件
typedef enum {KEY_NONE = 0, KEY1 = 1, KEY2 = 2, KEY3 = 3, KEY4 = 4,
}
eKeyList;
typedef enum {KEY_TYPE_NULL = 0, KEY_TYPE_DOUBLE_CLICK = 1, KEY_TYPE_DOWN = 2,