GPIO 汇总
ESP32-S3 芯片具有 45 个物理 GPIO 管脚(GPIO0 ~ GPIO21 和 GPIO26 ~ GPIO48)。每个管脚都可用作一个通用 IO,或连接一个内部外设信号。通过 GPIO 交换矩阵、IO MUX 和 RTC IO MUX,可配置外设模块的输入信号来源于任何的 GPIO 管脚,并且外设模块的输出信号也可连接到任意 GPIO 管脚。这些模块共同组成了芯片的输入输出控制。
下表提供了各管脚的详细信息,部分 GPIO 具有特殊的使用限制,具体可参考表中的注释列
GPIO | 模拟功能 | RTC GPIO | 注释 |
---|---|---|---|
GPIO0 | RTC_GPIO0 | Strapping 管脚 | |
GPIO1 | ADC1_CH0 | RTC_GPIO1 | |
GPIO2 | ADC1_CH1 | RTC_GPIO2 | |
GPIO3 | ADC1_CH2 | RTC_GPIO3 | Strapping 管脚 |
GPIO4 | ADC1_CH3 | RTC_GPIO4 | |
GPIO5 | ADC1_CH4 | RTC_GPIO5 | |
GPIO6 | ADC1_CH5 | RTC_GPIO6 | |
GPIO7 | ADC1_CH6 | RTC_GPIO7 | |
GPIO8 | ADC1_CH7 | RTC_GPIO8 | |
GPIO9 | ADC1_CH8 | RTC_GPIO9 | |
GPIO10 | ADC1_CH9 | RTC_GPIO10 | |
GPIO11 | ADC2_CH0 | RTC_GPIO11 | |
GPIO12 | ADC2_CH1 | RTC_GPIO12 | |
GPIO13 | ADC2_CH2 | RTC_GPIO13 | |
GPIO14 | ADC2_CH3 | RTC_GPIO14 | |
GPIO15 | ADC2_CH4 | RTC_GPIO15 | |
GPIO16 | ADC2_CH5 | RTC_GPIO16 | |
GPIO17 | ADC2_CH6 | RTC_GPIO17 | |
GPIO18 | ADC2_CH7 | RTC_GPIO18 | |
GPIO19 | ADC2_CH8 | RTC_GPIO19 | USB-JTAG |
GPIO20 | ADC2_CH9 | RTC_GPIO20 | USB-JTAG |
GPIO21 | RTC_GPIO21 | ||
GPIO26 | SPI0/1 | ||
GPIO27 | SPI0/1 | ||
GPIO28 | SPI0/1 | ||
GPIO29 | SPI0/1 | ||
GPIO30 | SPI0/1 | ||
GPIO31 | SPI0/1 | ||
GPIO32 | SPI0/1 | ||
GPIO33 | SPI0/1 | ||
GPIO34 | SPI0/1 | ||
GPIO35 | SPI0/1 | ||
GPIO36 | SPI0/1 | ||
GPIO37 | SPI0/1 | ||
GPIO38 | |||
GPIO39 | |||
GPIO40 | |||
GPIO41 | |||
GPIO42 | |||
GPIO43 | |||
GPIO44 | |||
GPIO45 | Strapping 管脚 | ||
GPIO46 | Strapping 管脚 | ||
GPIO47 | |||
GPIO48 |
备注
- Strapping 管脚:GPIO0、GPIO3、GPIO45 和 GPIO46 是 Strapping 管脚。更多信息请参考 ESP32-S3 技术规格书。
- SPI0/1:GPIO26-32 通常用于 SPI flash 和 PSRAM,不推荐用于其他用途。当使用八线 flash 或八线 PSRAM 或同时使用两者时,GPIO33~37 会连接到 SPIIO4 ~ SPIIO7 和 SPIDQS。因此,对于内嵌 ESP32-S3R8 或 ESP32-S3R8V 芯片的开发板,GPIO33~37 也不推荐用于其他用途。
- USB-JTAG:GPIO19 和 GPIO20 默认用于 USB-JTAG。用做 GPIO 时驱动程序将禁用 USB-JTAG。
GPIO 驱动提供了一个函数 gpio_dump_io_configuration()
用来输出指定管脚的实时配置状态,包括上下拉、输入输出使能、管脚映射等。输出示例如下:
================IO DUMP Start================
IO[4] -
Pullup: 1, Pulldown: 0, DriveCap: 2
InputEn: 1, OutputEn: 0, OpenDrain: 0
FuncSel: 1 (GPIO)
GPIO Matrix SigIn ID: (simple GPIO input)
SleepSelEn: 1
IO[18] -
Pullup: 0, Pulldown: 0, DriveCap: 2
InputEn: 0, OutputEn: 1, OpenDrain: 0
FuncSel: 1 (GPIO)
GPIO Matrix SigOut ID: 256 (simple GPIO output)
SleepSelEn: 1
IO[26] **RESERVED** -
Pullup: 1, Pulldown: 0, DriveCap: 2
InputEn: 1, OutputEn: 0, OpenDrain: 0
FuncSel: 0 (IOMUX)
SleepSelEn: 1
=================IO DUMP End==================
当 IO 管脚是通过 GPIO 交换矩阵连接到内部外设信号,输出信息打印中的外设信号 ID 定义可以在 soc/gpio_sig_map.h
文件中查看。**RESERVED**
字样则表示此 IO 被用于连接 FLASH 或 PSRAM,因此该引脚不应该被其他任何应用场景所征用并进行重新配置。
当 GPIO 连接到 RTC 低功耗和模拟子系统时,ESP32-S3 芯片还单独支持 RTC GPIO。可在以下情况时使用这些管脚功能:
- 处于 Deep-sleep 模式时
- 超低功耗协处理器 (ULP) 运行时
- 使用 ADC/DAC 等模拟功能时
GPIO 毛刺过滤器
ESP32-S3 内置硬件的过滤器可以过滤掉 GPIO 输入端口上的毛刺信号,在一定程度上避免错误触发中断或者是错把噪声当成有效的外设信号。
每个 GPIO 都可以使用独立的毛刺过滤器,该过滤器可以将那些脉冲宽度窄于 2 个采样时钟的信号剔除掉,该宽度无法配置。GPIO 对输入信号的采样时钟通常是 IO_MUX 的时钟源。在驱动中,此类过滤器称为 管脚毛刺过滤器
。可以调用 gpio_new_pin_glitch_filter()
函数创建一个过滤器句柄。过滤器的相关配置保存在 gpio_pin_glitch_filter_config_t
结构体中。
gpio_pin_glitch_filter_config_t::gpio_num
设置启用毛刺过滤器的 GPIO 编号。
毛刺过滤器默认关闭,可调用 gpio_glitch_filter_enable()
使能过滤器。如需回收这个过滤器,可以调用 gpio_del_glitch_filter()
函数。在回收句柄前,请确保过滤器处于关闭状态,否则需调用 gpio_glitch_filter_disable()
。
API 参考 - 普通 GPIO
头文件
#include "driver/gpio.h"
此头文件是驱动组件提供的应用程序编程接口(API)的一部分。若要声明您的组件依赖于驱动,请在您的 CMakeLists.txt 文件中添加以下内容:
REQUIRES driver
或
PRIV_REQUIRES driver
函数
通用输入输出(GPIO)通用配置。
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
参数:pGPIOConfig – 指向GPIO配置结构体的指针
重置GPIO
将一个GPIO重置为默认状态(选择GPIO功能,启用上拉电阻并禁用输入和输出)。
esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
注意:此函数还会将该引脚的IOMUX配置为GPIO功能,并断开通过GPIO矩阵配置的任何其他外设输出。
参数: gpio_num — GPIO序号
GPIO设置中断触发类型
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)
参数
- gpio_num – GPIO编号。例如,若要设置GPIO16的触发类型,gpio_num 应该为GPIO_NUM_16(即16);
- intr_type – 中断类型,从gpio_int_type_t中选择。
返回
- ESP_OK 成功
- ESP_ERR_INVALID_ARG 参数错误
使能GPIO模块中断信号。
esp_err_t gpio_intr_enable(gpio_num_t gpio_num)
参数:
gpio_num – GPIO编号。例如,若要使能GPIO16的中断,gpio_num 应设为GPIO_NUM_16(即16);
返回
ESP_OK 成功
ESP_ERR_INVALID_ARG 参数错误
注意:
ESP32:当启用ADC功能,或在睡眠模式下使用Wi-Fi和蓝牙功能时,请不要使用GPIO36和GPIO39的中断。请参考adc1_get_raw的注释。有关此问题的描述,请参考《ESP32芯片设计缺陷及解
决办法》的3.11节 。
禁止GPIO模块中断信号
esp_err_t gpio_intr_disable(gpio_num_t gpio_num)
参数
gpio_num – GPIO编号。例如,若要禁用GPIO16的中断,gpio_num应设为GPIO_NUM_16(即16);
返回
ESP_OK 成功
ESP_ERR_INVALID_ARG 参数错误
通过启用 CONFIG_GPIO_CTRL_FUNC_IN_IRAM,允许在中断服务程序(ISR)上下文且缓存禁用的情况下执行此函数。
GPIO设置输出电平
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
参数
gpio_num -- GPIO编号。例如,若要设置GPIO16的输出电平,gpio_num应该为GPIO_NUM_16(16);
level -- 输出电平。0:低电平;1:高电平
通过启用CONFIG_GPIO_CTRL_FUNC_IN_IRAM,可在中断服务程序(ISR)上下文且缓存禁用时执行此函数。
GPIO获取输入电平
int gpio_get_level(gpio_num_t gpio_num)
参数
gpio_num – GPIO编号。例如,若要获取GPIO16引脚的逻辑电平,gpio_num应设为GPIO_NUM_16(16);
返回值
0 表示GPIO输入电平为0
1 表示GPIO输入电平为1
注意:如果该引脚未配置为输入(或输入与输出),则返回值始终为0。
GPIO设置方向
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
配置GPIO方向
参数
gpio_num – 配置GPIO引脚编号,它应该是GPIO编号。例如,若要设置GPIO16的方向,gpio_num 应该为GPIO_NUM_16(16);
mode – GPIO方向
返回
ESP_OK 成功
ESP_ERR_INVALID_ARG GPIO错误
枚举 gpio_mode_t
成员 | GPIO模式 |
---|---|
GPIO_MODE_DISABLE | 禁用输入和输出 |
GPIO_MODE_INPUT | 仅输入 |
GPIO_MODE_OUTPUT | 仅输出模式 |
GPIO_MODE_OUTPUT_OD | 仅输出且为开漏模式 |
GPIO_MODE_INPUT_OUTPUT_OD | 开漏模式下的输入和输出 |
GPIO_MODE_INPUT_OUTPUT | 输入和输出模式 |
应用测试代码
#include"freertos/FreeRTOS.h"
#include"freertos/task.h"
#include"driver/gpio.h"
#define OUTPUT_PIN 16
#define INPUT_PIN 39
//GPIO输出配置
void bsp_gpio_output_init()
{
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = (1<<OUTPUT_PIN);
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
}
//GPIO输入配置
void bsp_gpio_input_init()
{
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = (1<<INPUT_PIN);
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
}
//ms延时
void bsp_delay_ms(uint32_t cms)
{
TickType_t xDelay = cms / portTICK_PERIOD_MS;
vTaskDelay( xDelay );
}
void app_main(void)
{
uint32_t count = 0;
bsp_gpio_output_init();
bsp_gpio_input_init();
while(1)
{
if(count == 20){
gpio_set_level(OUTPUT_PIN,1);
count = 0;
}
else if(count == 10){
gpio_set_level(OUTPUT_PIN,0);
}
count++;
if(gpio_get_level(INPUT_PIN)==0){
printf("IO39 按下n");
while(gpio_get_level(INPUT_PIN)==0);
}
bsp_delay_ms(10);
}
}
GPIO_IO16,5HZ的频率电平变化
GPIO_IO39,输入检测