1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

#include <stdio.h>
#include "driver/gpio.h" // GPIO 控制头文件
#include "freertos/FreeRTOS.h" // FreeRTOS 相关头文件(虽然本代码没用到任务)
#include "esp_log.h" // 用于日志打印(此代码中未使用)

/**
* @brief GPIO 中断服务函数,当 GPIO 口电平发生变化时触发
* @param args 传入的参数,是中断来源的 GPIO 编号(通过强转传入)
*/
static void gpio_isr_handle(void *args){
int io_num = (int)args; // 获取产生中断的 GPIO 编号
int level = gpio_get_level(GPIO_NUM_9); // 读取 LED 当前电平
gpio_set_level(GPIO_NUM_9, !level); // LED 状态取反,实现按键切换灯状态

// 下面是原计划对不同按键做不同处理的代码(已注释)
// if(io_num == 0){
// // 按键0按下 -> 开灯(低电平)
// gpio_set_level(GPIO_NUM_9, 0);
// }
// else if(io_num == 1){
// // 按键1按下 -> 关灯(高电平)
// gpio_set_level(GPIO_NUM_9, 1);
// }
}

void app_main(void)
{
// === 1. 配置按键 GPIO ===
gpio_config_t key_cfg = {
.pin_bit_mask = 1ULL << 1, // 配置 GPIO1(按键)对应的位掩码
.mode = GPIO_MODE_INPUT, // 设置为输入模式
.pull_up_en = GPIO_PULLUP_ENABLE, // 使能内部上拉电阻(适用于按键接 GND 的方式)
.intr_type = GPIO_INTR_NEGEDGE, // 设置为下降沿中断(按键按下)
// 可选:上升沿 / 电平触发 / 双边沿触发等
};
ESP_ERROR_CHECK(gpio_config(&key_cfg)); // 应用按键 GPIO 配置

// === 2. 安装 GPIO 中断服务 ===
// 中断服务需要加载到 IRAM(快速内存区域),这样中断时可立即响应
gpio_install_isr_service(ESP_INTR_FLAG_IRAM);

// === 3. 绑定中断服务函数到指定引脚 ===
// 当 GPIO1 产生中断时,调用 gpio_isr_handle 函数,并传入 GPIO 编号
gpio_isr_handler_add(GPIO_NUM_1, // GPIO1:按键1
gpio_isr_handle, // 中断服务函数
(void *)GPIO_NUM_1); // 参数,转为 void* 传入

gpio_isr_handler_add(GPIO_NUM_0, // GPIO0:按键0
gpio_isr_handle, // 中断服务函数
(void *)GPIO_NUM_0); // 参数

// === 4. 配置 LED 输出引脚 ===
gpio_config_t led_cfg = {
.pin_bit_mask = 1ULL << 9, // GPIO9 作为输出口(控制 LED)
.mode = GPIO_MODE_OUTPUT, // 输出模式
};
gpio_config(&led_cfg); // 应用 LED GPIO 配置

gpio_set_level(GPIO_NUM_9, 1); // 初始化 LED 关闭(高电平熄灭)
}

🧠 补充说明

  • gpio_isr_handle() 中使用 gpio_get_level(GPIO_NUM_9) 来读取当前 LED 状态,再用 !level 取反,实现“按一次换一次状态”的 切换功能

  • gpio_isr_handler_add() 可绑定多个引脚到同一个中断函数(通过参数区分来源)。

  • gpio_install_isr_service() 只能调用一次,否则会报错。

  • ESP_INTR_FLAG_IRAM 是推荐的中断标志,确保中断服务函数在 RAM 中,执行更快更安全。