乐鑫Esp32学习之旅⑦ esp32上利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。(附带Demo)



一. 前言;


  • 说到按键的短按和长按,很多人都是直接用while(1)死循环不断去读取按键和消抖,通过读取时间的间隔来确定是长按还是短按!这种方法比较常用,今天的话,小徐给大家带来的是:esp32上利用GPIO中断做一个按键的短按和长按的回调事件!更高级,更深入去了解esp32

这里写图片描述


二.代码思维图;


这里写图片描述


上图看的逻辑也是比较清晰了,那么我这里用的是中断和freeRtos任务切换来实现:

扫描二维码关注公众号,回复: 1373386 查看本文章

二.代码;


  • 第一步:先初始化GPIO,注意配置为下降沿和上升沿触发中断,这样就可以在按下和抬起之间来发送消息给消息队列了!
    //配置GPIO,下降沿和上升沿触发中断
    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_INTR_ANYEDGE;
    io_conf.pin_bit_mask = 1 << key_gpio_pin;
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

    gpio_set_intr_type(key_gpio_pin, GPIO_INTR_ANYEDGE);
    gpio_evt_queue = xQueueCreate(2, sizeof(uint32_t));
    //注册中断服务
    gpio_install_isr_service(0);
    gpio_isr_handler_add(key_gpio_pin, gpio_isr_handler, (void *) key_gpio_pin);

  • 第二步:新建一个任务不断去接收任务送来的中断回调信息,其代码如下!

    uint32_t io_num;
    BaseType_t press_key = pdFALSE;
    BaseType_t lift_key = pdFALSE;
    int backup_time = 0;

    while (1) {

        //接收从消息队列发来的消息
        xQueueReceive(gpio_evt_queue, &io_num, ticks_to_wait);

        //记录下用户按下按键的时间点
        if (gpio_get_level(io_num) == 0) {
            press_key = pdTRUE;
            backup_time = system_get_time();
            //如果当前GPIO口的电平已经记录为按下,则开始减去上次按下按键的时间点
        } else if (press_key) {
            //记录抬升时间点
            lift_key = pdTRUE;
            backup_time = system_get_time() - backup_time;
        }

        //仅仅当按下标志位和按键弹起标志位都为1时候,才执行回调
        if (press_key & lift_key) {
            press_key = pdFALSE;
            lift_key = pdFALSE;

            //如果大于1s则回调长按,否则就短按回调
            if (backup_time > 1000000) {
                return KEY_LONG_PRESS;
            } else {
                return KEY_SHORT_PRESS;
            }
        }
    }

  • 第三步:看看我们的回调事件,其代码如下!
    esp_err_t ret = 0;
    KeyInit(KEY_GPIO);

    while (1) {
        ret = alink_key_scan(portMAX_DELAY);
        //如果错误则跳出任务
        if (ret == -1)
            vTaskDelete(NULL);

        switch (ret) {
        case KEY_SHORT_PRESS:
            printf("短按触发回调 ... \r\n");
            break;

        case KEY_LONG_PRESS:
            printf("长按触发回调 ... \r\n");
            break;

        default:
            break;
        }
    }

三.其他;


上面代码的1000000是指1s,如果您要改变长按2秒以上才算长按,那么可以修改这个数值!


串口打印:

这里写图片描述


本硬件的代码下载:https://download.csdn.net/download/xh870189248/10450163

esp32汇总工程,欢迎star,收到第一更新信息:https://github.com/xuhongv/StudyInEsp32

猜你喜欢

转载自blog.csdn.net/xh870189248/article/details/80524714