启明云端分享|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);//延时1000ms

	    printf("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);
}

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

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值