本教程采用esp-idf-5.3版本,型号为esp32-s3

1.头文件

该头文件可以包含在

#include "driver/gpio.h"

此头文件是 esp_driver_gpio 组件提供的 API 的一部分。要声明您的组件依赖于 esp_driver_gpio ,请将以下内容添加到您的 CMakeLists.txt 中

REQUIRES esp_driver_gpio

或者

PRIV_REQUIRES esp_driver_gpio

2.GPIO 常用配置

以GPIO_NUM_3 举例,配置包括设置中断类型,模式,是否上下拉。

gpio_config_t io_conf =
    {
        /*设置中断类型*/
        .intr_type = GPIO_INTR_DISABLE,
        /*模式调节*/
        .mode = GPIO_MODE_OUTPUT,
        /*配置引脚的掩码*/
        .pin_bit_mask = 1 << GPIO_NUM_3,
        /*下拉使能*/
        .pull_down_en = 0,
        /*上拉使能*/
        .pull_up_en = 0,
    };
gpio_config(&io_conf);

3.相关控制函数

//GPIO 常用配置
//pGPIOConfig—— 指向 GPIO 配置结构的指针
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig);

//将 gpio 重置为默认状态(选择 gpio 功能、启用上拉并禁用输入和输出)
//gpio_num —— GPIO 编号
esp_err_t gpio_reset_pin(gpio_num_t gpio_num);

//GPIO 设置中断触发类型
//intr_type -- 中断类型,从 gpio_int_type_t 中选择
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type);

//启用 GPIO 模块中断信号
esp_err_t gpio_intr_enable(gpio_num_t gpio_num);

//禁用 GPIO 模块中断信号
esp_err_t gpio_intr_disable(gpio_num_t gpio_num);

//GPIO 设置输出电平
//level -- Output level. 0: low ; 1: high
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);

// GPIO 获取输入电平,默认值为 0
int gpio_get_level(gpio_num_t gpio_num);

// GPIO 设置模式
//mode -- GPIO的模式
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);

//配置 GPIO 上拉/下拉电阻
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);

//启用 GPIO 唤醒功能
//当设备处于低功耗模式(如深度睡眠)时,当设备处于低功耗模式(如深度睡眠)时
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);

//禁用GPIO唤醒功能
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);

//注册 GPIO 中断处理程序,该处理程序是一个 ISR。该处理程序将附加到运行此函数的同一 CPU 核心上
//每当发生任何 GPIO 中断时,都会调用此 ISR 函数
//请参阅替代的 gpio_install_isr_service() 和 gpio_isr_handler_add() API,以使驱动程序支持每个 GPIO ISR
esp_err_t gpio_isr_register(void (*fn)(void*), void *arg, int intr_alloc_flags, gpio_isr_handle_t *handle);

//启用 GPIO 上的上拉功能
esp_err_t gpio_pullup_en(gpio_num_t gpio_num);

//禁用 GPIO 上的上拉
esp_err_t gpio_pullup_dis(gpio_num_t gpio_num);

//启用 GPIO 下拉功能
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num);

//禁用 GPIO 上的下拉功能
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);

//安装 GPIO 驱动程序的 ETS_GPIO_INTR_SOURCE ISR 处理程序服务,该服务允许每个引脚的 GPIO 中断处理程序
//此函数与 gpio_isr_register() 不兼容 - 如果使用该函数,则为所有 GPIO 中断注册一个全局 ISR
//如果使用此函数,ISR 服务将提供全局 GPIO ISR,并通过 gpio_isr_handler_add() 函数注册各个引脚处理程序
esp_err_t gpio_install_isr_service(int intr_alloc_flags);

//卸载驱动的GPIO ISR服务,释放相关资源
void gpio_uninstall_isr_service(void);

//为相应的 GPIO 引脚添加 ISR 处理程序
//使用 gpio_install_isr_service() 安装驱动程序的 GPIO ISR 处理程序服务后调用此函数
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void *args);

//删除相应 GPIO 引脚的 ISR 处理程序
esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num);

//设置 GPIO 驱动能力(即输出电流能力)
esp_err_t gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t strength);

//获得 GPIO pad 驱动能力
esp_err_t gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t *strength);

4.注册中断

  // 安装 GPIO 中断服务
gpio_install_isr_service(0);
   // 为 GPIO 引脚设置中断处理函数
gpio_isr_handler_add(GPIO_NUM_3, gpio_isr_handler, NULL);

5.案例

此处借用其他博主内容

#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"

/*
 ****************************************************************
 * 本教程包括的内容有
 * 引脚3,初始化
 * 设置引脚电平
 * 查看引脚电平
 * 设置中断函数
 * 创造任务
 * 创造队列
 ****************************************************************
 */



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 "] intr, val: %d\n", io_num, gpio_get_level(io_num));
        }
    }
}

void gpio_init(void)
{
    gpio_config_t io_conf =
        {
            /*中断使能*/
            .intr_type = GPIO_INTR_DISABLE,
            /*输出模式调节*/
            .mode = GPIO_MODE_OUTPUT,
            /*配置引脚的掩码*/
            .pin_bit_mask = 1 << GPIO_NUM_3,
            /*下拉使能*/
            .pull_down_en = 0,
            /*上拉使能*/
            .pull_up_en = 0,
        };
    gpio_config(&io_conf);

    /*设置中断类型*/
    gpio_set_intr_type(GPIO_NUM_3, GPIO_INTR_ANYEDGE);
}

void app_main(void)
{

    gpio_init();
    // create a queue to handle gpio event from isr
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));

    // GPIO_NUM_16		结构体gpio_num_t中的枚举值
    gpio_set_direction(GPIO_NUM_3, GPIO_MODE_OUTPUT); // 写这个或下一个
    gpio_set_direction(3, GPIO_MODE_OUTPUT);          // 或这个
    // start gpio task
    xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);

    // install gpio isr service
    gpio_install_isr_service(0);
    // hook isr handler for specific gpio pin
    gpio_isr_handler_add(GPIO_NUM_3, gpio_isr_handler, (void *)GPIO_NUM_3);

    printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size());

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


Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐