ESP32 芯片具有 40 个物理 GPIO pads (焊盘).某些 GPIO pad 既不能使用,在芯片封装上也没有相应的引脚(请参阅技术参考手册).所以只有 34 个物理 GPIO pads 可供使用.每个 pad 都可用作一个通用 IO,或连接一个内部的外设信号.IO_MUX、RTC IO_MUX 和 GPIO 交换矩阵用于将信号从外设传输至 GPIO pad.这些模块共同组成了芯片的 IO 控制.
注意:
当 GPIO 被连接到 “RTC” 低功耗和模拟子系统时,还有独立的 “RTC GPIO” 支持. 这些引脚功能可在深度睡眠,超低功耗协处理器运行时或使用 ADC/DAC/等 模拟功能时使用.
下图描述了数字 pad(控制信号:FUNC_SEL、IE、OE、WPU、WDU 等)和 162 个外设输入以及 176 个外设输出信号(控制信号:SIG_IN_SEL、SIG_OUT_SEL、IE、OE 等)和快速外设输入/输出信号(控制信号:IE、OE 等)以及 RTC IO_MUX 之间的信号选择和连接关系.
为实现通过 GPIO 交换矩阵接收外设输入信号,需要配置 GPIO 交换矩阵从 34 个 GPIO(0-19,21-23,25-27,32-39)中获取外设输入信号的索引号(0-18,23-36,39-58,61-90,95-124,140-155,164-181,190-195,198-206).
输入信号通过 IO_MUX 从 GPIO pad 中读取.IO_MUX 必须设置相应 pad 为 GPIO 功能.这样 GPIO pad 的输入信号就可进入 GPIO 交换矩阵然后通过 GPIO 交换矩阵进入选择的外设输入.
为实现通过 GPIO 交换矩阵输出外设信号,需要配置 GPIO 交换矩阵将输出索引号为 0-18,23-37,61-121,140-215,224-228 的外设信号输出到 28 个 GPIO (0-19, 21-23, 25-27, 32-33).
输出信号从外设输出到 GPIO 交换矩阵,然后到达 IO_MUX.IO_MUX 必须设置相应 pad 为 GPIO 功能.这样输出 GPIO 信号就能连接到相应 pad.
图3 所示为 176 个输出信号中的某一个信号通过 GPIO 交换矩阵到达 IO_MUX 然后连接到某个 pad.
快速信号如以太网、SDIO、SPI、JTAG、UART 等会使用直连功能(旁路 GPIO 交换矩阵)以实现更好的高频数字特性.所以高速信号会直接通过 IO_MUX 输入和输出.
这样比使用 GPIO 交换矩阵的灵活度要低,即每个 GPIO pad 的 IO_MUX 寄存器只有较少的功能选择,但可以实现更好的高频数字特性.
为实现外设 I/O 旁路 GPIO 交换矩阵必须配置两个寄存器:
18 个 GPIO 管脚具有低功耗(低功耗 RTC)性能和模拟功能,由 ESP32 的 RTC 子系统控制.这些功能不使用 IO_MUX 和 GPIO 交换矩阵,而是使用 RTC_MUX 将 I/O 指向 RTC 子系统.
当这些管脚被配置为 RTC GPIO 管脚,作为输出管脚时仍然能够在芯片处于 Deep-sleep 睡眠模式下保持输出电平值或者作为输入管脚使用时可以将芯片从 Deep-sleep 中唤醒.
每个 pad 的模拟和 RTC 功能是由 RTC_GPIO_PINx 寄存器中的 RTC_IO_TOUCH_PADx_TO_GPIO 位控制的.此位默认置为 1,通过 IO_MUX 子系统输入输出信号,如前文所述.
如果清零 RTC_IO_TOUCH_PADx_TO_GPIO 位,则输入输出信号会经过 RTC 子系统.在这种模式下,RTC_GPIO_PINx 寄存器用于数字 I/O,pad 的模拟功能也可以实现.
当 ESP32 处于 Light-sleep 模式时管脚可以有不同的功能.如果某一 GPIO pad 的 IO_MUX 寄存器中 GPIOxx_SLP_SEL 位置为 1,芯片处于 Light-sleep 模式下将由另一组不同的寄存器控制 pad.
如果 GPIOxx_SLP_SEL 置为 0,则芯片在正常工作和 Light-sleep 模式下,管脚的功能一样.
每个 IO pad(包括 RTC pad)都有单独的 hold 功能,由 RTC 寄存器控制.pad 的 hold 功能被置上后,pad 在置上 hold 那一刻的状态被强制保持,无论内部信号如何变化,修改 IO_MUX 配置或者 GPIO 配置,都不会改变 pad 的状态.应用如果希望在看门狗超时触发内核复位和系统复位时或者 Deep-sleep 时 pad 的状态不被改变,就需要提前把 hold 置上.
示例:
RTC GPIO (deep sleep):
rtc_gpio_init(27);
rtc_gpio_set_direction(27, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level(27, 1);
rtc_gpio_pullup_en(27);
rtc_gpio_hold_en(27);
Digital GPIO:
/**
* The state of digital gpio cannot be held during Deep-sleep, and it will resume the hold function
* when the chip wakes up from Deep-sleep. If the digital gpio also needs to be held during Deep-sleep,
* `gpio_deep_sleep_hold_en` should also be called.
*
* Power down or call gpio_hold_dis will disable this function.
*/
gpio_pad_select_gpio(26);
gpio_set_direction(26, GPIO_MODE_OUTPUT);
gpio_set_level(26, 1);
gpio_hold_en(26);
gpio_deep_sleep_hold_en();
GPIO 输出/输入中断示例:peripherals/gpio.
GPIO & RTC GPIO