按键控制LED灯-ESP32中断处理
阅读原文时间:2023年07月11日阅读:1

#include
#include
#include
#include
#include
#include
#include
#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);

}