zoukankan      html  css  js  c++  java
  • 长按短按控制LED灯-ESP32中断处理

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "freertos/queue.h"
    #include "driver/gpio.h"
    #include <sys/time.h>
    
    typedef enum {
      KEY_SHORT_PRESS = 1, 
      KEY_LONG_PRESS =2,
    } alink_key_t;
    
    #define GPIO_LED_IO       13
    #define GPIO_LED_PIN_SEL  1ULL<<GPIO_LED_IO
    #define GPIO_KEY_IO        14
    #define GPIO_KEY_PIN_SEL  1ULL<<GPIO_KEY_IO
    
    static xQueueHandle gpio_evt_queue = NULL;
    
    //获取系统时间
    static int64_t get_time(){
      struct timeval tv_now;
      gettimeofday(&tv_now, NULL);
      int64_t time_us = (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
      return time_us;
    }
    
    //按键中断处理函数
    static void IRAM_ATTR gpio_isr_handler(void* arg)
    {
        uint32_t gpio_num = (uint32_t) arg;
        xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
    }
    
    //任务处理
    static void led_task(void* arg)
    {
        uint32_t io_num;
        BaseType_t press_key = pdFALSE;
          BaseType_t lift_key = pdFALSE;
          int backup_time = 0;
    
        for(;;) {
            if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
              printf("GPIO[%d] intr, val: %d
    ", io_num, gpio_get_level(io_num));
    
              //记录下用户按下按键的时间点
              if (gpio_get_level(io_num) == 0) {
                press_key = pdTRUE;
                backup_time = get_time();
                //如果当前GPIO口的电平已经记录为按下,则开始减去上次按下按键的时间点
              } else if (press_key) {
                //记录抬升时间点
                lift_key = pdTRUE;
                backup_time = get_time() - backup_time;
              }
    
              //按下标志位和按键弹起标志位都为1时候
              if (press_key & lift_key) {
                press_key = pdFALSE;
                lift_key = pdFALSE;
    
                //大于1秒为长按
                if (backup_time > 1000000) {
                  printf("长按 ... 
    ");
                  //关闭LED灯
                  gpio_set_level(GPIO_LED_IO, 0);
                } else {
                  printf("短按 ... 
    ");
                  //打开LED灯
                  gpio_set_level(GPIO_LED_IO, 1);
                }
              }
            }
        }
    }
    
    void app_main(void)
    {
        //LED引脚配置
        gpio_config_t io_conf;
        io_conf.intr_type = GPIO_INTR_DISABLE;
        io_conf.mode = GPIO_MODE_OUTPUT;
        io_conf.pin_bit_mask = GPIO_LED_PIN_SEL;
        io_conf.pull_down_en = 0;
        io_conf.pull_up_en = 0;
        gpio_config(&io_conf);
    
        //按键中断配置
        io_conf.intr_type = GPIO_INTR_ANYEDGE;
        io_conf.pin_bit_mask = GPIO_KEY_PIN_SEL;
        io_conf.mode = GPIO_MODE_INPUT;
        io_conf.pull_up_en = 1;
        gpio_config(&io_conf);
    
        //创建消息队列处理引脚中断事件
        gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
        //创建任务
        xTaskCreate(led_task, "led_task", 2048, NULL, 10, NULL);
    
        //第一个处理器核安装中断处理程序
        gpio_install_isr_service(0);
        //添加中断处理函数
        gpio_isr_handler_add(GPIO_KEY_IO, gpio_isr_handler, (void*) GPIO_KEY_IO);
    
        printf("Minimum free heap size: %d bytes
    ", esp_get_minimum_free_heap_size());
    
    }

    参考:https://gitee.com/EspressifSystems/esp-idf

  • 相关阅读:
    奶酪工厂
    P1080 国王游戏(非高精版)
    【洛谷P2150】[NOI2015] 寿司晚宴
    【洛谷P3349】[ZJOI2016]小星星
    【洛谷P5785】[SDOI2012]任务安排
    【模板】严格次短路
    【洛谷P3647】[APIO2014]连珠线
    2021.10.27NOIP模拟总结
    【树形DP】CF1016F Road Projects
    2021CSP-S 总结
  • 原文地址:https://www.cnblogs.com/kerwincui/p/13946320.html
Copyright © 2011-2022 走看看