ESP32 按键程序笔记
临时代码1
该代码是半成品的按键程序,实现了按键的长按和按键的点击功能,在此记录以备往后查看。
/**
* 按键扫描,放在 Tick 钩子函数(滴答定时器函数)
*/
btn_result_enum_t key_scan(void)
{
static uint16_t btn_buff = 0xffff;
static btn_result_enum_t result;
uint8_t btn_state = EC11_BTN_GET();
static uint8_t first_flag = 0; /* 第一次 按下标志 */
static uint32_t total_time_count = 0; /* 总时间, 如果 total_time_count 超过2s无按键按下则代表没有任何动作(双击/3击) */
static uint32_t time_count = 0; /* 时间计时 */
static uint8_t press_time_num = 0; /* 长按时用于设定多少ms执行一次+1 */
btn_buff = (btn_buff << 1) | btn_state;
/* 消抖成功 */
if (btn_buff == (uint16_t)0x0000) {
time_count++;
first_flag = 1;
total_time_count = 0;
}
/* 按键松开 */
if (btn_buff == (uint16_t)0xffff) {
if (first_flag == 1) {
xtp_system.test_num++;
total_time_count++;
first_flag = 0;
time_count = 0;
xTaskNotifyGive(show_task_handle);
}
}
/**
* 按下时间大于 1.5s 代表长按
*/
if ((first_flag ==1) && (time_count > 1500)) {
press_time_num++;
/* 每 100ms 执行一次 test_num++ */
if(press_time_num >=100) {
xtp_system.test_num++;
press_time_num = 0;
}
xTaskNotifyGive(show_task_handle);
}
return result;
}
代码2,实现了单击、双击、3连击和长按
/**
* 按键扫描,放在 Tick 钩子函数(滴答定时器函数)
*/
btn_result_enum_t key_scan(void)
{
static uint16_t btn_buff = 0xffff;
static btn_result_enum_t result;
uint8_t btn_state = EC11_BTN_GET();
static uint8_t first_flag = 0; /* 第一次 按下标志 */
static uint32_t total_time_count = 0; /* 总时间, 如果 total_time_count 超过2s无按键按下则代表没有任何动作(双击/3击) */
static uint8_t total_flag = 0; /* 总标志位,用来判断整个按键过程的标志 */
static uint32_t time_count = 0; /* 长按时间计时 */
static uint8_t press_time_num = 0; /* 长按时用于设定多少ms执行一次+1 */
static uint8_t click_count = 0; /* 按键单击次数变量 */
btn_buff = (btn_buff << 1) | btn_state;
/* 消抖成功 */
if (btn_buff == (uint16_t)0x0000)
{
time_count++;
first_flag = 1;
total_flag = 1;
}
/* 总时间++ */
if (total_flag == 1)
{
total_time_count++; /* 总时间++ */
}
/* 按下时间大于 1.5s 代表长按 */
if ((first_flag == 1) && (time_count > 1500))
{
press_time_num++;
/* 每 100ms 执行一次 test_num++ */
if (press_time_num >= 100)
{
xtp_system.test_num++;
press_time_num = 0;
}
xTaskNotifyGive(show_task_handle);
result = LOOP_PRESS;
}
/* 按键松开状态 */
if (btn_buff == (uint16_t)0xffff)
{
if (first_flag == 1) {
first_flag = 0;
time_count = 0;
click_count++;
}
}
/* 总时间大于 0.5s 后,判断按键按下的次数 */
if (total_time_count > 500)
{
if (click_count == 1)
{
xtp_system.test_num++;
xTaskNotifyGive(show_task_handle);
}
if (click_count == 2)
{
xtp_system.test_num+=2;
xTaskNotifyGive(show_task_handle);
}
if (click_count >= 3)
{
xtp_system.test_num+=3;
xTaskNotifyGive(show_task_handle);
}
click_count = 0;
total_time_count = 0; /* 清除总时间标志 */
total_flag = 0; /* 清除总标志 */
}
return result;
}
改进后的程序,把 key_scan() 中的静态变量封装到一个 struct 中
xtp_btn.h
/**
* 按键程序头文件
*/
#ifndef __XTP_BTN_H
#define __XTP_BTN_H
#include <stdio.h>
#include "driver/gpio.h"
#define EC11_BTN_GPIO GPIO_NUM_5
#define EC11_BTN_GET() gpio_get_level(EC11_BTN_GPIO)
typedef enum
{
CLICK = 0, /* 单击 */
DOUBLE_CLICK, /* 双击 */
THREE_CLICK, /* 三连击 */
LOOP_PRESS, /* 按键一直按下 */
NO_CLICK
} btn_result_enum_t;
typedef struct
{
btn_result_enum_t result;
uint16_t btn_buff;
uint8_t first_flag: 1; /* 第一次 按下标志 */
uint8_t total_flag: 1; /* 总标志位,用来判断整个按键过程的标志 */
uint32_t time_count; /* 长按时间计时 */
uint32_t total_time_count; /* 总时间, 如果 total_time_count 超过2s无按键按下则代表没有任何动作(双击/3击) */
uint8_t press_time_num; /* 长按时用于设定多少ms执行一次+1 */
uint8_t click_count; /* 按键单击次数变量 */
} xtp_btn_t;
void key_scan(void);
extern xtp_btn_t btn;
#endif /* __XTP_BTN_H */
xtp_btn.c
#include "xtp_btn.h"
#include "system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
extern TaskHandle_t show_task_handle;
xtp_btn_t btn = {
.result = NO_CLICK,
.btn_buff = 0xffff,
.first_flag = 0,
.total_flag = 0,
.time_count = 0,
.total_time_count = 0,
.press_time_num = 0,
.click_count = 0,
};
/**
* 按键扫描,放在 Tick 钩子函数(滴答定时器函数)
*/
void key_scan(void)
{
uint8_t btn_state = EC11_BTN_GET();
btn.btn_buff = (btn.btn_buff << 1) | btn_state;
/* 消抖成功 */
if (btn.btn_buff == (uint16_t)0x0000)
{
btn.time_count++;
btn.first_flag = 1;
btn.total_flag = 1;
}
/* 总时间++ */
if (btn.total_flag == 1)
{
btn.total_time_count++; /* 总时间++ */
}
/* 按下时间大于 1.5s 代表长按 */
if ((btn.first_flag == 1) && (btn.time_count > 1500))
{
btn.press_time_num++;
/* 每 100ms 执行一次 test_num++ */
if(btn.press_time_num >=100) {
xtp_system.test_num++;
btn.press_time_num = 0;
}
xTaskNotifyGive(show_task_handle);
}
/* 按键松开状态 */
if (btn.btn_buff == (uint16_t)0xffff)
{
if (btn.first_flag == 1) {
btn.first_flag = 0;
btn.time_count = 0;
btn.click_count++;
}
}
/* 总时间大于 0.5s 后,判断按键按下的次数 */
if (btn.total_time_count > 500)
{
if (btn.click_count == 1)
{
xtp_system.test_num++;
btn.result = CLICK;
}
if (btn.click_count == 2)
{
xtp_system.test_num+=2;
btn.result = DOUBLE_CLICK;
}
if (btn.click_count >= 3)
{
xtp_system.test_num = 0;
btn.result = THREE_CLICK;
}
if (btn.click_count == 0)
{
btn.result = NO_CLICK;
}
btn.click_count = 0;
btn.total_time_count = 0; /* 清除总时间标志 */
btn.total_flag = 0; /* 清除总标志 */
xTaskNotifyGive(show_task_handle);
}
// xTaskNotify(show_task_handle, 1<<result, eSetBits);
}

浙公网安备 33010602011771号