esp-idf(GPIO篇)
本教程采用esp-idf-5.3版本,型号为esp32-s3。
·
GPIO的API
本教程采用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);
}
}
更多推荐



所有评论(0)