1 背景介紹
GPIO(General Purpose Input/Output) ——通用輸入輸出口,就是能由軟件自由控制輸入(接收外界信號)或輸出(發出電平信號)的引腳。
ESP32 最核心的功能之一,能被用來控制、連接、讀取各種外設,比如按鍵、LED、傳感器、繼電器、屏幕等。
ESP32 有多達 39 個 GPIO 引腳,編號為 GPIO0 ~ GPIO39,不過并不是每一個都可以任意使用。
1.1 基本特性
1.2 不建議使用GPIO口
1.3 常用設置
1.3 IO Matrix(IOMUX)
ESP32每個引腳都可以通過IO Matrix(IOMUX)將其映射為某種外設功能,比如 UART、PWM、SPI等。這意味著你可以自由地分配功能到引腳,非常靈活!你可以把 I2C 的 SDA/SCL 分別映射到 GPIO21 和 GPIO22,也可以換成 GPIO18 和 GPIO19,只要代碼里配置對應即可。
1.4 總結
ESP32 的 GPIO 功能非常強大、靈活。
要注意某些 GPIO 的啟動限制或輸入輸出限制。
使用前建議查 ESP32 的 datasheet 或 IO 使用圖。
可以結合中斷、PWM、ADC、DAC、外設等,組成豐富的控制/采集系
2 案例展示
ESP-IDF里操作 GPIO,一般按這幾個步驟:
-
配置 GPIO(方向/上拉/下拉/中斷觸發條件)
-
讀輸入 / 寫輸出
-
(可選)注冊中斷回調
2.1 輸出模式-控制led燈
#include "driver/gpio.h"#define LED_GPIO_PIN 2 // GPIO2接LEDvoid app_main(void)
{gpio_reset_pin(LED_GPIO_PIN);gpio_set_direction(LED_GPIO_PIN, GPIO_MODE_OUTPUT);while (1) {gpio_set_level(LED_GPIO_PIN, 1); // 點亮LEDvTaskDelay(pdMS_TO_TICKS(500));gpio_set_level(LED_GPIO_PIN, 0); // 熄滅LEDvTaskDelay(pdMS_TO_TICKS(500));}
}
2.2 讀入按鍵
#include "driver/gpio.h"#define BUTTON_GPIO_PIN 0 // GPIO0接按鈕void app_main(void)
{gpio_reset_pin(BUTTON_GPIO_PIN);gpio_set_direction(BUTTON_GPIO_PIN, GPIO_MODE_INPUT);gpio_pullup_en(BUTTON_GPIO_PIN); // 開啟上拉,避免懸空抖動while (1) {int button_level = gpio_get_level(BUTTON_GPIO_PIN);if (button_level == 0) {printf("Button Pressed!\n");}vTaskDelay(pdMS_TO_TICKS(100));}
}
3 總結
正常開發推薦使用 GPIO 2, 4, 5, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33 這些口,比較安全
4 中斷
4.1 工作模式
ESP32支持在GPIO上檢測:
-
上升沿觸發(低 → 高)
-
下降沿觸發(高 → 低)
-
任意電平觸發(高電平/低電平)
-
雙邊沿觸發(上升+下降)
? 觸發時,會調用一個中斷回調函數(ISR Handler),可以馬上做反應,比如讀取按鍵狀態!
4.2 設置流程
4.3 案例
用 GPIO0 按鈕觸發中斷,點亮/熄滅LED(GPIO2)
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"#define BUTTON_GPIO GPIO_NUM_0
#define LED_GPIO GPIO_NUM_2static const char *TAG = "GPIO_ISR";volatile int led_state = 0; // 注意 volatile,ISR中會修改!// 中斷回調函數(一定要短小!)
static void IRAM_ATTR gpio_isr_handler(void* arg)
{led_state = !led_state; // 翻轉LED狀態gpio_set_level(LED_GPIO, led_state);
}void app_main(void)
{// 配置LED引腳gpio_reset_pin(LED_GPIO);gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);// 配置按鈕引腳gpio_reset_pin(BUTTON_GPIO);gpio_set_direction(BUTTON_GPIO, GPIO_MODE_INPUT);gpio_pullup_en(BUTTON_GPIO); // 開啟上拉,避免懸空gpio_set_intr_type(BUTTON_GPIO, GPIO_INTR_NEGEDGE); // 配置下降沿中斷(按下)// 安裝中斷服務gpio_install_isr_service(0); // 參數是flag,一般填0gpio_isr_handler_add(BUTTON_GPIO, gpio_isr_handler, NULL); // 綁定回調函數ESP_LOGI(TAG, "Setup complete, waiting for button interrupt...");// 主循環啥也不用做while (1) {vTaskDelay(pdMS_TO_TICKS(1000));}
}
4.4 總結
按鍵中斷常用下降沿(NEGEDGE)。
中斷回調要短小、快速,不能長時間占用CPU。
可以通過信號量或消息隊列,把中斷事件傳給主任務中慢慢處理