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);
}
posted @ 2023-05-15 00:46  小土坡  阅读(501)  评论(0)    收藏  举报