ESP32系列,IDF官方实例——外设:通用GPIO

示例位于 \examples\peripherals\gpio\generic_gpio 文件夹内

GPIO示例逻辑简单,直接看代码理解。

复制代码
/* GPIO示例

   此示例代码位于公共域(或CC0许可,由您选择。)

   除非适用法律要求或书面同意,否则本软件按"原样"分发,不作任何保证或
   任何形式的条件,无论是明示的还是暗示的。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"

/**
 * 简介:
 * 此测试代码显示了如何配置gpio以及如何使用gpio中断。
 *
 * GPIO状态:
 * GPIO18:输出(ESP32C2/ESP32H2使用GPIO8作为第二个输出引脚)
 * GPIO19:输出(ESP32C2/ESP32H2使用GPIO9作为第二个输出引脚)
 * GPIO4:输入,上拉,从上升沿和下降沿中断
 * GPIO5:输入,上拉,从上升沿中断。
 *
 * 注意。这些是示例中使用的默认GPIO引脚。您可以在menuconfig中更改IO引脚。
 *
 * 测试:
 * 将GPIO18(8)与GPIO4连接
 * 将GPIO19(9)与GPIO5连接
 * 在GPIO18(8)/19(9)上产生脉冲,触发GPIO4/5上的中断
 *
 */

#define GPIO_OUTPUT_IO_0 CONFIG_GPIO_OUTPUT_0
#define GPIO_OUTPUT_IO_1 CONFIG_GPIO_OUTPUT_1
#define GPIO_OUTPUT_PIN_SEL ((1ULL << GPIO_OUTPUT_IO_0) | (1ULL << GPIO_OUTPUT_IO_1))
/*
 * 假设GPIO_OUTPUT_IO_0=18,GPIO_OUTBUT_IO_1=19
 * 在二进制表示中,
 * 1ULL<<GPIO_OUTPUT_IO_0 = 0000000000000000000001000000000000000000
 * 1ULL<<GPIO_OUTPUT_IO_1 = 0000000000000000000010000000000000000000
 * GPIO_OUTPUT_PIN_SEL    = 0000000000000000000011000000000000000000
 * */
#define GPIO_INPUT_IO_0 CONFIG_GPIO_INPUT_0
#define GPIO_INPUT_IO_1 CONFIG_GPIO_INPUT_1
#define GPIO_INPUT_PIN_SEL ((1ULL << GPIO_INPUT_IO_0) | (1ULL << GPIO_INPUT_IO_1))
/*
 * 假设GPIO_INPUT_IO_0=4,GPIO_INPUT_IO_1=5
 * 在二进制表示中,
 * 1ULL<<GPIO_INPUT_IO_0 = 0000000000000000000000000000000000010000
 * 1ULL<<GPIO_INPUT_IO_1 = 0000000000000000000000000000000000100000
 * GPIO_INPUT_PIN_SEL    = 0000000000000000000000000000000000110000
 * */
#define ESP_INTR_FLAG_DEFAULT 0

static QueueHandle_t 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[%" PRIu32 "]中断触发,电平: %d\n", io_num, gpio_get_level(io_num));
        }
    }
}

void app_main(void)
{
    // 零初始化配置结构。
    gpio_config_t io_conf = {};
    // 禁用中断
    io_conf.intr_type = GPIO_INTR_DISABLE;
    // 设置为输出模式
    io_conf.mode = GPIO_MODE_OUTPUT;
    // 要设置的引脚的位掩码,例如GPIO18/19
    io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
    // 禁用下拉模式
    io_conf.pull_down_en = 0;
    // 禁用上拉模式
    io_conf.pull_up_en = 0;
    // 使用给定的设置配置GPIO
    gpio_config(&io_conf);

    // 上升沿中断
    io_conf.intr_type = GPIO_INTR_POSEDGE;
    // 引脚的位掩码,此处使用GPIO4/5
    io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
    // 设置为输入模式
    io_conf.mode = GPIO_MODE_INPUT;
    // 启用上拉模式
    io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

    // 更改一个引脚的gpio中断类型
    gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);

    // 创建一个队列来处理来自isr的gpio事件
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
    // 启动gpio任务
    xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);

    // 安装gpio isr服务
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    // 用于特定gpio引脚的挂钩isr处理程序
    gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void *)GPIO_INPUT_IO_0);
    // 用于特定gpio引脚的挂钩isr处理程序
    gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void *)GPIO_INPUT_IO_1);

    // 删除gpio编号的isr处理程序。
    gpio_isr_handler_remove(GPIO_INPUT_IO_0);
    // 再次钩住特定gpio引脚的isr处理程序
    gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void *)GPIO_INPUT_IO_0);

    printf("最小可用堆大小:%" PRIu32 "字节\n", esp_get_minimum_free_heap_size());

    int cnt = 0;
    while (1)
    {
        printf("cnt: %d\n", cnt++);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        gpio_set_level(GPIO_OUTPUT_IO_0, cnt % 2);
        gpio_set_level(GPIO_OUTPUT_IO_1, cnt % 2);
    }
}

附加文件 driver/gpio.h 中文版本,可查看官方提供的API功能,可放进vs code,实现悬浮中文提示


点击查看代码

复制代码
/*
 * SPDX文件版权所有:2015-2024乐鑫系统(上海)有限公司
 *
 * SPDX许可证标识符:Apache-2.0
 */

#pragma once

#include <stdio.h>
#include <stdbool.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_intr_alloc.h"
#include "soc/soc_caps.h"
#include "hal/gpio_types.h"
#include "esp_rom_gpio.h"
#include "driver/gpio_etm.h"

#ifdef __cplusplus
extern "C" {
#endif

#define GPIO_PIN_COUNT                      (SOC_GPIO_PIN_COUNT)
///检查它是否是有效的GPIO编号
#define GPIO_IS_VALID_GPIO(gpio_num)        ((gpio_num >= 0) && \
                                              (((1ULL << (gpio_num)) & SOC_GPIO_VALID_GPIO_MASK) != 0))
///检查它是否可以是输出模式的有效GPIO编号
#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((gpio_num >= 0) && \
                                              (((1ULL << (gpio_num)) & SOC_GPIO_VALID_OUTPUT_GPIO_MASK) != 0))
///检查它是否可以是有效的数字I/O焊盘
#define GPIO_IS_VALID_DIGITAL_IO_PAD(gpio_num) ((gpio_num >= 0) && \
                                                 (((1ULL << (gpio_num)) & SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK) != 0))

typedef intr_handle_t gpio_isr_handle_t;

/**
 * @brief GPIO中断处理程序
 *
 * @param arg 用户注册数据
 */
typedef void (*gpio_isr_t)(void *arg);

/**
 * @brief GPIO_config功能GPIO焊盘配置参数
 */
typedef struct {
    uint64_t pin_bit_mask;          /*!<GPIO引脚:设置位掩码,每个位映射到一个GPIO */
    gpio_mode_t mode;               /*!<GPIO模式:设置输入/输出模式                     */
    gpio_pullup_t pull_up_en;       /*!<GPIO上拉                                         */
    gpio_pulldown_t pull_down_en;   /*!<GPIO下拉菜单                                       */
    gpio_int_type_t intr_type;      /*!<GPIO中断类型                                  */
#if SOC_GPIO_SUPPORT_PIN_HYS_FILTER
    gpio_hys_ctrl_mode_t hys_ctrl_mode;       /*!<GPIO迟滞:斜坡输入迟滞滤波器    */
#endif
} gpio_config_t;

/**
 * @brief GPIO通用配置
 *
 *        配置GPIO的模式、上拉、下拉、IntrType
 *
 * @param  pGPIOConfig 指向GPIO配置结构的指针
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG参数错误
 *
 */
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig);

/**
 * @brief 将gpio重置为默认状态(选择gpio功能,启用上拉并禁用输入和输出)。
 *
 * @param gpio_num GPIO编号。
 *
 * @note 此功能还将此引脚的IOMUX配置为GPIO功能,并断开通过GPIO配置的任何其他外围输出
 *       矩阵。
 *
 * @return 始终返回ESP_OK。
 */
esp_err_t gpio_reset_pin(gpio_num_t gpio_num);

/**
 * @brief  GPIO设置中断触发类型
 *
 * @param  gpio_num GPIO编号。如果要设置触发类型,例如GPIO16,gpio_num应该是gpio_num_16(16);
 * @param  intr_type 中断类型,从gpio_int_type_t中选择
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG参数错误
 *
 */
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type);

/**
 * @brief  启用GPIO模块中断信号
 *
 * @note ESP32:在启用睡眠模式的情况下使用ADC或Wi-Fi和蓝牙时,请不要使用GPIO36和GPIO39的中断。
 *       请参考`adc1_get_raw`的评论。
 *       请参阅<a href="https://espressif.com/sites/default/files/documentation/eco_and_workarounds_for_bugs_in_esp32_en.pdf">ESP32 ECO和Bug解决方法</a>,以了解此问题的描述。

 *
 * @param  gpio_num GPIO编号。如果你想在GPIO16上启用中断,gpio_num应该是gpio_num_16(16);
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG参数错误
 *
 */
esp_err_t gpio_intr_enable(gpio_num_t gpio_num);

/**
 * @brief  禁用GPIO模块中断信号
 *
 * @note 通过启用`CONFIG_GPIO_CTRL_FUNC_IN_IRAM,允许在ISR上下文中禁用缓存时执行此功能`
 *
 * @param  gpio_num GPIO编号。如果要禁用GPIO16等中断,gpio_num应为gpio_num_16(16);
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG参数错误
 *
 */
esp_err_t gpio_intr_disable(gpio_num_t gpio_num);

/**
 * @brief  GPIO设置输出电平
 *
 * @note 通过启用`CONFIG_GPIO_CTRL_FUNC_IN_IRAM,允许在ISR上下文中禁用缓存时执行此功能`
 *
 * @param  gpio_num GPIO编号。如果你想设置GPIO16的输出电平,gpio_num应该是gpio_num_16(16);
 * @param  level 输出水平。0:低;1:高
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG GPIO编号错误
 *
 */
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);

/**
 * @brief  GPIO获取输入电平
 *
 * @warning 如果焊盘未配置为输入(或输入和输出),则返回值始终为0。
 *
 * @param  gpio_num GPIO编号。如果你想得到GPIO16引脚的逻辑电平,gpio_num应该是gpio_num_16(16);
 *
 * @return
 *     -0 GPIO输入电平为0
 *     -GPIO输入电平为1
 *
 */
int gpio_get_level(gpio_num_t gpio_num);

/**
 * @brief    GPIO设置方向
 *
 * 配置GPIO方向,如只输出、只输入、输出和输入
 *
 * @param  gpio_num  配置GPIO引脚号,应该是GPIO号。如果你想设置GPIO16的方向,gpio_num应该是gpio_num_16(16);
 * @param  mode GPIO方向
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG GPIO错误
 *
 */
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);

/**
 * @brief  配置GPIO上拉/下拉电阻器
 *
 * @note ESP32:只有支持输入和输出的引脚集成了上拉和下拉电阻器。仅输入GPIO 34-39不会。
 *
 * @param  gpio_num GPIO编号。如果你想为GPIO16设置上拉或下拉模式,gpio_num应该是gpio_num_16(16);
 * @param  pull GPIO上/下拉模式。
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG:参数错误
 *
 */
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);

/**
 * @brief 启用GPIO唤醒功能。
 *
 * @param gpio_num GPIO编号。
 *
 * @param intr_type GPIO唤醒类型。只能使用GPIO_INTR_LOW_LEVEL或GPIO_INTR_HIGH LEVEL。
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG参数错误
 */
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);

/**
 * @brief 禁用GPIO唤醒功能。
 *
 * @param gpio_num GPIO编号
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG参数错误
 */
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);

/**
 * @brief   注册GPIO中断处理程序,该处理程序是一个ISR。
 *          处理程序将连接到运行此函数的同一CPU核心。
 *
 * 每当发生任何GPIO中断时,都会调用此ISR函数。请参阅替代的gpio_install_isr_service()和gpio_isr_handler_add()API,以获得每个-gpio isr的驱动程序支持。
 *
 * @param  fn  中断处理函数。
 * @param  arg  处理函数参数
 * @param  intr_alloc_flags 用于分配中断的标志。一个或多个(ORred)
 *            ESP_INTR_FLAG_*值。有关更多信息,请参阅esp_intr_alloc.h。
 * @param  handle 返回句柄的指针。如果非NULL,这里将返回中断句柄。
 *
 * \逐字嵌入:rst:前导星号
 * 要禁用或删除ISR,请将返回的句柄传递给:doc:`中断分配函数</api-reference/system/intr_alloc>`。
 * \尾注
 *
 * @return
 *     -ESP_OK成功;
 *     -ESP_ERR_INVALID_ARG GPIO错误
 *     -ESP_ERR_NOT_FOUND未找到具有指定标志的空闲中断
 */
esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, gpio_isr_handle_t *handle);

/**
  * @brief 在GPIO上启用上拉。
  *
  * @param gpio_num GPIO编号
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_INVALID_ARG参数错误
  */
esp_err_t gpio_pullup_en(gpio_num_t gpio_num);

/**
  * @brief 禁用GPIO上的上拉。
  *
  * @param gpio_num GPIO编号
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_INVALID_ARG参数错误
  */
esp_err_t gpio_pullup_dis(gpio_num_t gpio_num);

/**
  * @brief 在GPIO上启用下拉。
  *
  * @param gpio_num GPIO编号
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_INVALID_ARG参数错误
  */
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num);

/**
  * @brief 禁用GPIO上的下拉菜单。
  *
  * @param gpio_num GPIO编号
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_INVALID_ARG参数错误
  */
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);

/**
  * @brief 安装GPIO驱动程序的ETS_GPIO_INTR_SOURCE ISR处理程序服务,该服务允许每引脚GPIO中断处理程序。
  *
  * 此函数与gpio_isr_register()不兼容-如果使用该函数,则会为所有gpio中断注册一个全局isr。如果使用此函数,ISR服务将提供全局GPIO ISR,并通过GPIO_ISR_handler_add()函数注册单个引脚处理程序。
  *
  * @param intr_alloc_flags 用于分配中断的标志。一个或多个(ORred)
  *            ESP_INTR_FLAG_*值。有关更多信息,请参阅esp_intr_alloc.h。
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_NO_MEM没有内存来安装此服务
  *     -ESP_ERR_INVALID_STATE ISR服务已安装。
  *     -ESP_ERR_NOT_FOUND未找到具有指定标志的空闲中断
  *     -ESP_ERR_INVALID_ARG GPIO错误
  */
esp_err_t gpio_install_isr_service(int intr_alloc_flags);

/**
  * @brief 卸载驱动程序的GPIO ISR服务,释放相关资源。
  */
void gpio_uninstall_isr_service(void);

/**
  * @brief 为相应的GPIO引脚添加ISR处理程序。
  *
  * 使用gpio_install_isr_service()安装驱动程序的gpio isr处理程序服务后调用此函数。
  *
  * 不再需要使用IRAM_ATTR声明引脚ISR处理程序,除非在分配时传递ESP_INTR_FLAG_IRAM标志
  * gpio_install_ISR_service()中的ISR。
  *
  * 此ISR处理程序将从ISR调用。因此,有一个堆栈大小限制(在menuconfig中可配置为"ISR堆栈大小")。由于额外的间接级别,与全局GPIO中断处理程序相比,此限制较小。
  *
  * @param gpio_num GPIO编号
  * @param isr_handler 对应GPIO编号的ISR处理函数。
  * @param args ISR处理程序的参数。
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_INVALID_STATE状态错误,ISR服务尚未初始化。
  *     -ESP_ERR_INVALID_ARG参数错误
  */
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void *args);

/**
  * @brief 移除对应GPIO引脚的ISR处理程序。
  *
  * @param gpio_num GPIO编号
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_INVALID_STATE状态错误,ISR服务尚未初始化。
  *     -ESP_ERR_INVALID_ARG参数错误
  */
esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num);

/**
  * @brief 设置GPIO焊盘驱动功能
  *
  * @param gpio_num GPIO编号,仅支持输出GPIO
  * @param strength 衬垫的驱动能力
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_INVALID_ARG参数错误
  */
esp_err_t gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t strength);

/**
  * @brief 获得GPIO焊盘驱动功能
  *
  * @param gpio_num GPIO编号,仅支持输出GPIO
  * @param strength 接受极板驱动能力的指针
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_INVALID_ARG参数错误
  */
esp_err_t gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t *strength);

/**
  * @brief 启用gpio键盘保持功能。
  *
  * 当GPIO设置为保持时,其状态在那一刻被锁定,当内部信号或IO MUX/GPIO配置被修改时(包括输入启用、输出启用、输出值、功能和驱动强度值),其状态不会改变。此功能可用于在GPIO/IOMUX所属的电源域关闭时保留GPIO的状态。例如,芯片或系统被重置(例如,看门狗超时、深度睡眠事件被触发),或在轻度睡眠时外围设备断电。
  *
  * 此功能在输入和输出模式下都有效,仅适用于具有输出功能的GPIO。
  * 如果启用此功能:在输出模式下:GPIO的输出电平将被锁定,无法更改。在输入模式下:输入读取值仍然可以反映输入信号的变化。
  *
  * 但是,在ESP32/S2/C3/S3/C2上,此功能不能用于在深度睡眠期间保持数字GPIO的状态。
  * 即使启用了此功能,当芯片从唤醒时,数字GPIO也将重置为默认状态
  * 深度睡眠。如果您想在深度睡眠期间保持数字GPIO的状态,请调用`GPIO_Deep_sleep_hold_en`。
  *
  * 关闭电源或调用`gpio_hold_dis`将禁用此功能。
  *
  * @param gpio_num GPIO编号,仅支持具有输出功能的GPIO
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_NOT_SUPPORTED不支持键盘保持功能
  */
esp_err_t gpio_hold_en(gpio_num_t gpio_num);

/**
  * @brief 禁用gpio键盘保持功能。
  *
  * 当芯片从外设掉电睡眠中唤醒时,gpio将被设置为默认模式,因此,如果调用此函数,gpio会输出默认级别。如果您不希望更改级别,则应在调用此函数之前将gpio配置为已知状态。例如
  *     如果在深度睡眠期间将gpio18保持为高电平,则在芯片被唤醒并调用"gpio_hold_dis"后,gpio18将输出低电平(因为gpio18默认为输入模式)。如果你不希望出现这种行为,你应该将gpio18配置为输出模式,并在调用`gpio_hold_dis`之前将其设置为高级。
  *
  * @param gpio_num GPIO编号,仅支持具有输出功能的GPIO
  *
  * @return
  *     -ESP_OK成功
  *     -ESP_ERR_NOT_SUPPORTED不支持键盘保持功能
  */
esp_err_t gpio_hold_dis(gpio_num_t gpio_num);

#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
/**
  * @brief 在深度睡眠期间启用所有数字gpio键盘保持功能。
  *
  * 启用此功能会使所有数字gpio板在深度睡眠期间处于保持状态。每个焊盘保持的状态是其活动配置(不是焊盘的睡眠配置!)。
  *
  * 请注意,此焊盘保持功能仅在芯片处于深度睡眠模式时有效。当芯片处于活动模式时,即使您调用了此功能,数字gpio状态也可以自由更改。
  *
  * 在这个API被调用之后,数字gpio深度睡眠保持功能将在每个睡眠过程中工作。您应该调用`gpio_deep_sleep_hold_dis`来禁用此功能。
  */
void gpio_deep_sleep_hold_en(void);

/**
  * @brief 在深度睡眠期间禁用所有数字gpio键盘保持功能。
  */
void gpio_deep_sleep_hold_dis(void);
#endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP

/**
  * @brief 通过IOMUX将焊盘输入设置为外围信号。
  * @param gpio_num 焊盘的GPIO编号。
  * @param signal_idx 要输入的外围信号id。"soc/gpio_sig_map.h"中的"*_IN_IDX"信号之一。
  */
void gpio_iomux_in(uint32_t gpio_num, uint32_t signal_idx);

/**
  * @brief 通过IOMUX将外围输出设置为GPIO焊盘。
  * @param gpio_num 焊盘的gpio_num gpio编号。
  * @param func 外围引脚到输出引脚的功能编号。
  *        "soc/io_mux_reg.h"中指定引脚(X)的"FUNC_X_*"之一。
  * @param out_en_inv 如果输出启用需要反转,则为True,否则为False。
  */
void gpio_iomux_out(uint8_t gpio_num, int func, bool out_en_inv);

#if SOC_GPIO_SUPPORT_FORCE_HOLD
/**
  * @brief 强制保持所有数字和rtc gpio键盘。
  *
  * GPIO强制保持,无论芯片处于活动模式还是睡眠模式。
  *
  * 此功能将立即使所有焊盘锁存输入启用、输出启用、输出值、功能和驱动强度值的当前值。
  *
  * @warning
  *   1.此功能还将保持闪存和UART引脚。因此,此函数和所有代码都在之后运行
  *      (在调用`gpio_force_unhold_all`禁用此功能之前),必须将其放置在内部RAM中,因为按住闪存引脚将停止SPI闪存操作,按住UART引脚将停止任何UART日志记录。
  *   2.ROM引导过程中,所有焊盘的保持状态都将被取消,因此不建议在深度睡眠和重置过程中使用此API来保持焊盘状态。
  * */
esp_err_t gpio_force_hold_all(void);

/**
  * @brief 松开所有数字和rtc gpio键盘。
  *
  * @note  全局保持信号和每个IO的保持信号通过"或"逻辑作用在PAD上,因此如果焊盘已经被配置为通过"gpio_hold_en"保持,则该API不能释放其保持状态。
  * */
esp_err_t gpio_force_unhold_all(void);
#endif

/**
  * @brief 启用SLP_SEL以在浅睡眠状态下自动更改GPIO状态。
  * @param gpio_num 焊盘的GPIO编号。
  *
  * @return
  *     -ESP_OK成功
  *
  */
esp_err_t gpio_sleep_sel_en(gpio_num_t gpio_num);

/**
  * @brief 禁用SLP_SEL以在浅睡眠状态下自动更改GPIO状态。
  * @param gpio_num 焊盘的GPIO编号。
  *
  * @return
  *     -ESP_OK成功
  */
esp_err_t gpio_sleep_sel_dis(gpio_num_t gpio_num);

/**
 * @brief    GPIO在睡眠时设置方向
 *
 * 配置GPIO方向,如只输出、只输入、输出和输入
 *
 * @param  gpio_num  配置GPIO引脚号,应该是GPIO号。如果你想设置GPIO16的方向,gpio_num应该是gpio_num_16(16);
 * @param  mode GPIO方向
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG GPIO错误
 */
esp_err_t gpio_sleep_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);

/**
 * @brief  在睡眠状态下配置GPIO上拉/下拉电阻
 *
 * @note ESP32:只有支持输入和输出的引脚集成了上拉和下拉电阻器。仅输入GPIO 34-39不会。
 *
 * @param  gpio_num GPIO编号。如果你想为GPIO16设置上拉或下拉模式,gpio_num应该是gpio_num_16(16);
 * @param  pull GPIO上/下拉模式。
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG:参数错误
 */
esp_err_t gpio_sleep_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);

#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP

#define GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num)    ((gpio_num >= 0) && \
                                                          (((1ULL << (gpio_num)) & SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK) != 0))

/**
 * @brief 启用GPIO深度睡眠唤醒功能。
 *
 * @param gpio_num GPIO编号。
 *
 * @param intr_type GPIO唤醒类型。只能使用GPIO_INTR_LOW_LEVEL或GPIO_INTR_HIGH LEVEL。
 *
 * @note 由SDK调用。用户不应直接在APP中调用此功能。
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG参数错误
 */
esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);

/**
 * @brief 禁用GPIO深度睡眠唤醒功能。
 *
 * @param gpio_num GPIO编号
 *
 * @return
 *     -ESP_OK成功
 *     -ESP_ERR_INVALID_ARG参数错误
 */
esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num);

#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP

/**
 * @brief 将IO配置信息转储到控制台
 *
 * @param out_stream IO流(例如stdout)
 * @param io_bit_mask IO引脚位掩码,每个位映射到一个IO
 *
 * @return
 *    -ESP_OK成功
 *    -ESP_ERR_INVALID_ARG参数错误
 */
esp_err_t gpio_dump_io_configuration(FILE *out_stream, uint64_t io_bit_mask);

#ifdef __cplusplus
}
#endif
相关推荐
宁子希1 天前
如何将 ESP32 快速接入高德、心知、和风天气API 获取天气信息
android·单片机·嵌入式硬件·esp32
mingupup1 天前
ESP32+Arduino入门(三):连接WIFI获取当前时间
esp32·arduino
余衫马19 天前
从零到一:ESP32与豆包大模型的RTC连续对话实现指南
esp32·实时音视频·智能对话·esp-adf·sparkbot
公子无缘1 个月前
【嵌入式】复刻SQFMI开源的Watchy墨水屏电子表——(2)软件部分
c语言·嵌入式硬件·物联网·开源·esp32
古希腊掌握嵌入式的神1 个月前
ESP32学习 -从STM32工程架构进阶到ESP32架构
stm32·学习·架构·esp32
集大周杰伦1 个月前
深入理解 Xtensa 架构 ESP32 内存架构(SRAM、IRAM、IROM、DRAM、DROM详解)
架构·系统架构·esp32·esp·内存架构·xtensa
茴香豆的茴11 个月前
基于ESP32的桌面小屏幕实战[8]:任务创建
物联网·esp32
深圳启明云端科技1 个月前
ESP32芯片模组方案,设备物联网无线通信,WiFi蓝牙交互控制应用
物联网·esp32·智能家居·芯片·乐鑫·模组·无线方案
赴遥1 个月前
ESP32S3N16R8驱动ST7701S屏幕(vscode+PlatfoemIO)
vscode·单片机·esp32·st7701s