发帖
0 0 0

M61-32S 基于FreeRTOS按钮点击事件检测

WT_0213
论坛元老

127

主题

1798

回帖

1万

积分

论坛元老

勤劳的打工人

积分
16857
技术杂谈 14 0 昨天 23:12
[i=s] 本帖最后由 WT_0213 于 2025-9-10 00:02 编辑 [/i]

更新了一下:

【电子DIY作品】甲醛颗粒物温湿度等多合一检测设备(更新)

粉尘PM2.5检测、甲醛检测、二氧化碳浓度检测

增加了 数值单位,如PM2.5与甲醛浓度都是ug/m³,二氧化碳浓度为ppm。

操作优化:

单击 显示下一个功能页面,双击显示上一个功能页面。


以下代码是:单击双击长按操作。

按钮操作代码优化,自测目前可稳定执行以上操作。

先创建 xTaskCreate(key_scan_task, "btn_event", 1024, NULL, 6, NULL); 任务

int main(void)
{
    ……
    // 创建任务
    xTaskCreate(key_scan_task, "btn_event", 1024, NULL, 6, NULL);
    ……
    vTaskStartScheduler();

}

然后任务实现

void key_scan_task() {
    typedef enum {
        BUTTON_STATE_IDLE,      // 空闲状态
        BUTTON_STATE_PRESSED,   // 按下状态
        BUTTON_STATE_RELEASED,  // 释放状态
        BUTTON_STATE_DOUBLE,    // 双击检测状态
    } button_state_t;

    static button_state_t state = BUTTON_STATE_IDLE;
    static uint32_t press_time = 0;
    static uint32_t release_time = 0;

    #define DEBOUNCE_TIME_MS    50   // 去抖动时间
    #define LONG_PRESS_TIME_MS  1000 // 长按时间阈值
    #define DOUBLE_CLICK_TIME_MS 300 // 双击时间阈值

    struct bflb_device_s* btn_gpio = bflb_device_get_by_name("gpio");
    bflb_gpio_init(btn_gpio, GPIO_PIN_18, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);

    while (1) {
        bool is_pressed = !bflb_gpio_read(btn_gpio, GPIO_PIN_18); // 低电平表示按下

        switch (state) {
            case BUTTON_STATE_IDLE:
                if (is_pressed) {
                    press_time = xTaskGetTickCount();
                    state = BUTTON_STATE_PRESSED;
                }
                break;

            case BUTTON_STATE_PRESSED:
                if (!is_pressed) {
                    release_time = xTaskGetTickCount();
                    state = BUTTON_STATE_RELEASED;
                } else if (xTaskGetTickCount() - press_time >= LONG_PRESS_TIME_MS) {
                    printf("长按\n");
                    // ……
                    state = BUTTON_STATE_IDLE;
                }
                break;

            case BUTTON_STATE_RELEASED:
                if (is_pressed) {
                    if (xTaskGetTickCount() - release_time <= DOUBLE_CLICK_TIME_MS) {
                        state = BUTTON_STATE_DOUBLE;
                    } else {
                        state = BUTTON_STATE_PRESSED;
                    }
                } else if (xTaskGetTickCount() - release_time > DOUBLE_CLICK_TIME_MS) {
                    printf("单击\n");
                    // ……
                    state = BUTTON_STATE_IDLE;
                }
                break;

            case BUTTON_STATE_DOUBLE:
                if (!is_pressed) {
                    printf("双击\n");
                    // ……
                    state = BUTTON_STATE_IDLE;
                }
                break;
        }

        vTaskDelay(10); // 10ms 扫描周期
    }
}
──── 0人觉得很赞 ────

使用道具 举报

您需要登录后才可以回帖 立即登录
高级模式
返回
统计信息
  • 会员数: 29703 个
  • 话题数: 43198 篇