以STM32为例,实现按键的短按和长按
1 实现原理
简单来说就是通过设置一个定时器来定时扫描几个按键的状态,并分别记录按键按下的持续时间,通过时间的长短就可以判断出是长按还是短按。
本文硬件接线图如下:
2 实现代码
1、key.h
主要是一些按键引脚以及后面需要使用的变量定义。
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY1_PORT GPIOE
#define KEY1_PIN GPIO_Pin_4
#define KEY2_PORT GPIOE
#define KEY2_PIN GPIO_Pin_3
#define KEY3_PORT GPIOE
#define KEY3_PIN GPIO_Pin_2
#define KEY4_PORT GPIOA
#define KEY4_PIN GPIO_Pin_0
// 按键引脚定义
typedef struct
{
GPIO_TypeDef* port; // GPIOx
uint16_t pin; // GPIO PINx
uint16_t pressed_state; // 按键按下时的状态,0:按下时为低电平,1:按下时为高电平
}key_gpio_t;
// 按键状态
typedef enum
{
KEY_RELEASE, // 释放松开
KEY_CONFIRM, // 消抖确认
KEY_SHORT_PRESSED, // 短按
KEY_LONG_PRESSED, // 长按
}key_status_t;
// 按键事件
typedef enum
{
EVENT_NULL,
EVENT_SHORT_PRESSED,
EVENT_LONG_PRESSED,
}key_event_t;
typedef struct
{
key_status_t current_state; // 按键当前状态
uint32_t pressed_time; // 按下时间
key_event_t key_event; // 按键事件
}key_param_t;
uint8_t read_key_state(uint8_t index);
uint8_t key_scan(void);
void key_handle(void);
void key_timer_init(void);
void key_gpio_init(void);
void key_init(void);
#endif
2、key.c
按键的实现代码,包括定时器和引脚的初始化,按键的扫描和处理函数,等等。
/**
********************************************************************************************************
* @file key.c
* @author qiyiqi
* @brief 按键驱动代码
* MCU: STM32F103ZE开发板
* 按键原理: 设置一个1ms定时器定时扫描几个按键的状态,并分别记录按下的持续时间,通过时间可以判断是长按还是
* 短按。
* 注意事项: 此代码只是作为一个参考例程,如果不使用STM32的标准库,移植到其他MCU或者HAL库之类的,主要修改的
* 地方在初始化函数key_init(),按键读取函数read_key_state(),定时器初始化以及中断服务函数等。
********************************************************************************************************
*/
#include "key.h"
#include "stdio.h"
// 按键列表
key_gpio_t key_list[] =
{
// 端口号,引脚号,有效电平
{
KEY1_PORT, KEY1_PIN, 0}, // 按下为0,松开为1
{
KEY2_PORT, KEY2_PIN, 0},
{
KEY3_PORT, KEY3_PIN, 0}, // 按下为1,松开为0
{
KEY4_PORT