文章目錄
一、ESP32引腳資源分配與使用建議
轉到博文:ESP32引腳資源分配與使用建議
二、ESP32需要特別注意的幾個GPIO
1. Strapping引腳
ESP32 共有5 個Strapping 管腳。
MTDI/GPIO12
:內部下拉GPIO0
:內部上拉GPIO2
:內部下拉MTDO/GPIO15
:內部上拉GPIO5:
內部上拉
系統復位時,這些管腳的值被保存到寄存器。軟件可以讀取寄存器“GPIO_STRAPPING”中這5 個位的值。該寄存器值一直保持到掉電。
完成復位後,這些管腳被當做普通GPIO 使用。
因此在系統復位時,要處理好這些引腳,要給一個確定的值
GPIO號 | 引腳號 | 作用 | 處理方法 |
---|---|---|---|
12 | 18 | VDD_SDIO 管腳可配置輸出1.8 V(Boot 啓動時,需GPIO12 的值爲1),或輸出3.3 V(Boot 啓動時,需GPIO12的值爲0,默認狀態),給外部電路使用(flash)。 | |
:–: | :–: | :–: | :–: |
:–: | :–: | :–: | :–: |
:–: | :–: | :–: | :–: |
:–: | :–: | :–: | :–: |
2. 專用spi flash引腳
GPIO6
GPIO7
GPIO8
GPIO9
GPIO10
GPIO11
一般在模組內部用於外接SPI flash。
Note that GPIO6-11 are usually used for SPI flash.
3. 只具有輸入功能的引腳
GPIO34
GPIO35
GPIO36
GPIO37
GPIO38
GPIO39
以上管腳只具有輸入功能,沒有上拉下拉選項
can only be set as input mode and do not have software pullup or pulldown functions.
三、ESP32 API GPIO使用
- 官方文檔release/v3.3版本 ESP_IDF: GPIO & RTC GPIO
1. 輸入輸出模式
GPIO_MODE_INPUT 輸入
GPIO_MODE_OUTPUT 輸出
GPIO_MODE_OUTPUT_OD 開漏輸出
GPIO_MODE_INPUT_OUTPUT_OD 開漏輸入輸出
GPIO_MODE_INPUT_OUTPUT 輸入輸出
2. 中斷類型
GPIO_INTR_DISABLE 禁用GPIO中斷
GPIO_INTR_POSEDGE GPIO中斷類型:上升沿
GPIO_INTR_NEGEDGE 下降沿
GPIO_INTR_ANYEDGE 上升沿和下降沿
GPIO_INTR_LOW_LEVEL 輸入低電平觸發
GPIO_INTR_HIGH_LEVEL 輸入高電平觸發
3. 上下拉使能
GPIO_PULLUP_DISABLE 禁用GPIO上拉電阻
GPIO_PULLUP_ENABLE 啓用GPIO上拉電阻
GPIO_PULLDOWN_DISABLE 禁用GPIO下拉電阻
GPIO_PULLDOWN_ENABLE 啓用GPIO下拉電阻
4. 驅動能力
GPIO_DRIVE_CAP_0 弱 weak
GPIO_DRIVE_CAP_1 強
GPIO_DRIVE_CAP_2 默認值
GPIO_DRIVE_CAP_DEFAULT 默認值
GPIO_DRIVE_CAP_3 最強
四、ESP32 GPIO 中斷使用
示例:打印GPIO4和GPIO5的點平變化
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "driver/gpio.h"
#define GPIO_INPUT_IO_0 4
#define GPIO_INPUT_IO_1 5
#define GPIO_INPUT_PIN_SEL ((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))
#define ESP_INTR_FLAG_DEFAULT 0
static xQueueHandle gpio_evt_queue = NULL;
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 gpio_task_example(void* arg)
{
uint32_t io_num;
for(;;) {
if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
}
}
}
void app_main()
{
gpio_config_t io_conf;
//interrupt of rising edge
io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
//bit mask of the pins, use GPIO4/5 here
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//enable pull-up mode
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
//change gpio intrrupt type for one pin
gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);
//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//start gpio task
xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);
//install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void*) GPIO_INPUT_IO_1);
//remove isr handler for gpio number.
gpio_isr_handler_remove(GPIO_INPUT_IO_0);
//hook isr handler for specific gpio pin again
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
while(1) {
vTaskDelay(1000 / portTICK_RATE_MS);
}
}
注意:
- 請勿在中斷服務函數中使用printf
- 中斷服務函數添加
IRAM_ATTR
使其放在IRAM中