欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

启明云端分享|ESP32学习笔记参考GPIO口操作

发布时间:2024/10/14 编程问答 57 豆豆
生活随笔 收集整理的这篇文章主要介绍了 启明云端分享|ESP32学习笔记参考GPIO口操作 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考。同时也用心整理了乐鑫及星宸科技的新产品、新方案的主要特点及应用!希望你能第一时间了解并快速用上好的方案和产品!


ESP32 芯片有40个物理GPIO pad。每个pad都可用作一个通用 IO,或连接一个内部的外设信号。IO_MUX、RTC IO_MUX 和 GPIO 交换矩阵用于将信号从外设传输至 GPIO pad。这些模块共同组成了芯片的 IO 控制。
注意:其中 GPIO 34-39 仅用作输入管脚,其他的既可以作为输入又可以作为输出管脚。GPIO6-11通常用于SPI闪存。

  • 官方资料

ESP-IDF 编程指南——GPIO&RTC GPIO
ESP32-DevKitC V4 的介绍

  • 头文件
#include "driver/gpio.h"
  • ESP32-DevKitC V4 的GPIO接口



2、GPIO设置

  • 简单方法
gpio_pad_select_gpio(GPIO_NUM_1); // 选择一个GPIO gpio_set_direction(GPIO_NUM_1, GPIO_MODE_OUTPUT);// 把这个GPIO作为输出 gpio_set_level(GPIO_NUM_1, 0); // 把这个GPIO输出低电平

笔记:通过 gpio.h 文件可以调用 gpio_types.h 文件,在 gpio_types.h 文件中定义了一个结构体,定义了ESP32-DevKitC V4的40个GPIO接口,GPIO_NUM_1IO1口。

  • 结构体方法
-`#define GPIO_OUTPUT_IO_0 1 #define GPIO_OUTPUT_PIN_SEL (1ULL<<GPIO_OUTPUT_IO_0) // 配置GPIO_OUT位寄存器void gpio_init(void) {gpio_config_t io_conf; // 定义一个gpio_config类型的结构体,下面的都算对其进行的配置io_conf.intr_type = GPIO_PIN_INTR_DISABLE; // 禁止中断 io_conf.mode = GPIO_MODE_OUTPUT; // 选择输出模式io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; // 配置GPIO_OUT寄存器io_conf.pull_down_en = 0; // 禁止下拉io_conf.pull_up_en = 0; // 禁止上拉gpio_config(&io_conf); // 最后配置使能 } gpio_set_level(GPIO_OUTPUT_IO_0, 0); // 把这个GPIO输出低电平 gpio_set_level(GPIO_OUTPUT_IO_0, 1); // 把这个GPIO输出高电平`
  • 示例: LED灯闪烁
#include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h"//用到了FreeRTOS系统中的tesk #include "driver/gpio.h" //配置gpio的头文件void app_main(void) {gpio_pad_select_gpio(GPIO_NUM_2);//选择IO2作为GPIO口gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);//把这个GPIO作为输出while(1) {printf("Turning off the LED\n");gpio_set_level(GPIO_NUM_2, 0);//IO2 输出为低电平 灯灭vTaskDelay(1000 / portTICK_PERIOD_MS);//延时1000msprintf("Turning on the LED\n");gpio_set_level(GPIO_NUM_2, 1);//IO2 输出为高电平 灯亮vTaskDelay(1000 / portTICK_PERIOD_MS);//延时1000ms} }

3、GPIO与中断

3.1 API介绍

gpio_config_t 结构体

  • pin_bit_mask端口号: GPIO_SEL_X。

  • intr_type中断触发类型: GPIO_INTR_DISABLE关闭中断触发;GPIO_INTR_POSEDGE上升沿;

  • GPIO_INTR_NEGEDGE下降沿; GPIO_INTR_ANYEDGE双边沿;GPIO_INTR_LOW_LEVEL低电平; GPIO_INTR_HIGH_LEVEL高电平。

  • mode模式:

    GPIO_MODE_DISABLE关闭;GPIO_MODE_INPUT输入;GPIO_MODE_OUTPUT输出;GPIO_MODE_OUTPUT_OD开漏输出; PIO_MODE_INPUT_OUTPUT_OD开漏输入输出; GPIO_MODE_INPUT_OUTPUT输入输出。

  • pull_up_en上拉电阻:GPIO_PULLUP_DISABLE断开;GPIO_PULLUP_ENABLE使能。

  • pull_down_en下拉电阻:GPIO_PULLDOWN_DISABLE断开;GPIO_PULLDOWN_ENABLE使能。

gpio_config

通过gpio_config_t结构体初始化gpio功能
返回值:ESP_OK初始化成功;ESP_ERR_INVALID_ARG初始化。

gpio_reset_pin

将gpio重置为默认状态

gpio_set_level

设置输出电平 返回值:ESP_OK成功;ESP_ERR_INVALID_ARG GPIO编号错误。

gpio_get_level

获取输入电平 返回值:如果pad没有配置为输入(或输入输出),则返回值总是0。

gpio_set_drive_capability

设置GPIO驱动能力

gpio_get_drive_capability

获取GPIO 驱动能力

补充函数

gpio_set_direction 设置GPIO模式
gpio_set_pull_mode 配置GPIO的上拉/下拉功能
gpio_pullup_en 开启上拉模式
gpio_pullup_dis 关闭上拉模式
gpio_pulldown_en 开启下拉模式
gpio_pulldown_dis 关闭下拉模式
gpio_set_intr_type 设置中断触发模式

3.2 中断API

gpio_install_isr_service

安装GPIO ISR服务的驱动,开启每个引脚GPIO中断处理程序 。
这个函数与gpio_isr_register()不兼容。如果使用这个函数,ISR服务将提供一个全局GPIO ISR,并且通过gpio_isr_handler_add()函数注册单个的pin处理程序。

gpio_uninstall_isr_service

卸载GPIO ISR服务的驱动,释放相关资源。

gpio_isr_handler_add

为GPIO引脚添加中断处理回调函数。
ISR处理程序不再需要用IRAM_ATTR来声明,除非你在gpio_install_isr_service()中分配ISR时传递了ESP_INTR_FLAG_IRAM标志。
这个ISR处理程序将从ISR中调用。因此存在一个堆栈大小限制(可在menuconfig中配置为“ISR堆栈大小”)。

gpio_isr_handler_remove

删除GPIO引脚的中断处理回调函数。

gpio_intr_enable

使能GPIO中断

gpio_intr_disable

关闭GPIO中断

gpio_isr_register

统一为所有的GPIO口注册一个全局的ISR,即任何的GPIO中断触发,都会调用该中断处理函数

3.3 示例

用boot控制led灯 由电路可知boot键接的是IO0口

#include <stdio.h> #include <string.h> #include <stdlib.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "driver/gpio.h"#define ESP_INTR_FLAG_DEFAULT 0 gpio_num_t gpio_led_num = GPIO_NUM_32; // 连接LED的GPIO gpio_num_t gpio_contact_switch_num = GPIO_NUM_0; // 连接触点开关GPIO static xQueueHandle gpio_evt_queue = NULL; // 事务队列int cnt = 0; // 计数,反转LED /*** 中断处理*/ static void IRAM_ATTR gpio_isr_handler(void *arg) {cnt++;// 反转gpio的电平,让LED灯出现显示的反转gpio_set_level(gpio_led_num, cnt % 2);uint32_t gpio_num = (uint32_t)arg;// 向gpio事件处理的队列中添加一条消息xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); } static void gpio_task_led(void *arg) {uint32_t io_num;for (;;){if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)){printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));}} } void app_main(void) {// 设置控制LED的GPIO为输出模式gpio_set_direction(gpio_led_num, GPIO_MODE_OUTPUT);// 设置作为中断的GPIO pin为输出模式gpio_set_direction(gpio_contact_switch_num, GPIO_MODE_INPUT);// 设置作为中断模式为沿上升沿触发gpio_set_intr_type(gpio_contact_switch_num, GPIO_INTR_POSEDGE);// 创建队列处理来自isr的gpio事件gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));// 启动gpio的任务xTaskCreate(gpio_task_led, "gpio_task_led", 2048, NULL, 10, NULL);// 初始化全局GPIO的中断服务程序,并设置中断的电平等级gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);// 将指定的GPIO挂载到中断服务上,并设定中断触发的回调函数和传入参数gpio_isr_handler_add(gpio_contact_switch_num, gpio_isr_handler, (void *) gpio_contact_switch_num); }

小伙伴们,看明白了吗?如果还有不明白的,可以留言给小明哈!

总结

以上是生活随笔为你收集整理的启明云端分享|ESP32学习笔记参考GPIO口操作的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。