按鍵控制LED燈-ESP32中斷處理


#include <driver/gpio.h>
#include <esp_task_wdt.h>
#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
#include <math.h>
#include "sdkconfig.h"

#define MIN_DELAY 500
#define BUTTON_GPIO GPIO_NUM_14
#define BLINK_GPIO GPIO_NUM_13


static char *TAG = "SMART-WATER";
//二值信號量可以在某個特殊的中斷發送時,讓任務解除阻塞,相當於讓任務與中斷同步。
//這樣,可以讓中斷事件處理量大的工作在同步任務中完成,中斷服務例程(ISR)中只是快速處理少部分工作。
static xSemaphoreHandle semaphore_handle = NULL;

//任務處理函數
void led_task(void* arg) {
  bool x = false;
  while (true) {
    //獲取信號量,portMAX_DELAY標識一直等待,可以設置具體的時鍾滴答次數
    xSemaphoreTake(semaphore_handle, portMAX_DELAY);
    x = !x;
    gpio_set_level(BLINK_GPIO, x);
  }
}

//按鈕中斷處理
void IRAM_ATTR button_isr_handler(void* arg) {
  int last_time = 0;
  //獲取系統當前運行的時鍾節拍數,此函數用於在中斷服務程序里面調用, 如果在任務里面調用的話, 
  //需要使用函數 xTaskGetTickCount,這兩個函數切不可混用
  int now = xTaskGetTickCountFromISR();
  if (now - last_time > MIN_DELAY) {
    int ignored = pdFALSE;
    //通過釋放信號量來使任務解除阻塞
    xSemaphoreGiveFromISR(semaphore_handle, &ignored);
    last_time = now;
  }
}


void app_main(void)
{
    gpio_pad_select_gpio(BLINK_GPIO);
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);

    gpio_pad_select_gpio(BUTTON_GPIO);
    gpio_set_direction(BUTTON_GPIO, GPIO_MODE_INPUT);
    //上拉
    gpio_set_pull_mode(BUTTON_GPIO, GPIO_PULLUP_ONLY);
    //設置電平下降沿觸發中斷
    gpio_set_intr_type(BUTTON_GPIO, GPIO_INTR_NEGEDGE);

    //創建一個二進制信號量
    semaphore_handle = xSemaphoreCreateBinary();
    //創建任務,param1:任務入口函數,無限循環 param2:任務名稱  
    //param3:指定任務堆棧的大小 ,堆棧能保護變量的數目,不是字節數。棧空間 大小為usStackDepth*4(bytes)。
    //param4:指針用於作為一個參數傳向創建的任務  param5:任務運行時的優先級  param6:用於傳遞一個處理——引用創建的任務
    xTaskCreate(led_task, "led_task", 2048, NULL, 10, NULL);
    //第一個處理器核安裝中斷處理程序
    gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1);
    //添加中斷處理函數
    gpio_isr_handler_add(BUTTON_GPIO, button_isr_handler, NULL);

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM