[15]ESP32之GPIO使用備忘錄

一、ESP32引腳資源分配與使用建議

轉到博文:ESP32引腳資源分配與使用建議

二、ESP32需要特別注意的幾個GPIO

1. Strapping引腳

ESP32 共有5 個Strapping 管腳。

  • MTDI/GPIO12:內部下拉
  • GPIO0:內部上拉
  • GPIO2:內部下拉
  • MTDO/GPIO15:內部上拉
  • GPIO5:內部上拉

系統復位時,這些管腳的值被保存到寄存器。軟件可以讀取寄存器“GPIO_STRAPPING”中這5 個位的值。該寄存器值一直保持到掉電。
完成復位後,這些管腳被當做普通GPIO 使用。
因此在系統復位時,要處理好這些引腳,要給一個確定的值
ESP32 Strapping引腳

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使用

  1. 官方文檔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中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章