ESP32系列:GPIO基本输入输出操作实战

一、目的

        在前面的章节中我们已经介绍了ESP32的开发环境的搭建过程,从本篇开始我们将从最基本的GPIO控制讲起,介绍ESP32上面相关的外设操作。

二、介绍

        参考资料

        GPIO & RTC GPIO – ESP32 – — ESP-IDF Programming Guide latest documentation (espressif.com)https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html

        esp32具有35个GPIO引脚,分别为GPIO0-GPIO23、GPIO25-GPIO27、GPIO32-GPIO39。

        注意:有些GPIO在一些芯片封装上没有,所以使用时一定要查阅一些对应的芯片手册。

        每一个引脚可以用作通用IO,也可以作为内部外设的输入输出信号。

GPIO

Analog Function

RTC GPIO

Comments

GPIO0

ADC2_CH1

RTC_GPIO11

Strapping pin

GPIO1

TXD

GPIO2

ADC2_CH2

RTC_GPIO12

Strapping pin

GPIO3

RXD

GPIO4

ADC2_CH0

RTC_GPIO10

GPIO5

Strapping pin

GPIO6

SPI0/1

GPIO7

SPI0/1

GPIO8

SPI0/1

GPIO9

SPI0/1

GPIO10

SPI0/1

GPIO11

SPI0/1

GPIO12

ADC2_CH5

RTC_GPIO15

Strapping pin; JTAG

GPIO13

ADC2_CH4

RTC_GPIO14

JTAG

GPIO14

ADC2_CH6

RTC_GPIO16

JTAG

GPIO15

ADC2_CH3

RTC_GPIO13

Strapping pin; JTAG

GPIO16

SPI0/1

GPIO17

SPI0/1

GPIO18

GPIO19

GPIO20

This pin is only available on ESP32-PICO-V3 chip package

GPIO21

GPIO22

GPIO23

GPIO25

ADC2_CH8

RTC_GPIO6

GPIO26

ADC2_CH9

RTC_GPIO7

GPIO27

ADC2_CH7

RTC_GPIO17

GPIO32

ADC1_CH4

RTC_GPIO9

GPIO33

ADC1_CH5

RTC_GPIO8

GPIO34

ADC1_CH6

RTC_GPIO4

GPI

GPIO35

ADC1_CH7

RTC_GPIO5

GPI

GPIO36

ADC1_CH0

RTC_GPIO0

GPI

GPIO37

ADC1_CH1

RTC_GPIO1

GPI

GPIO38

ADC1_CH2

RTC_GPIO2

GPI

GPIO39

ADC1_CH3

RTC_GPIO3

GPI

        注意

        GPIO0、GPIO2、GPIO5、GPIO12、GPIO15作为strapping引脚,也就是说芯片上电时会检查这些引脚的电压,具体细节可以查看芯片手册进行了解。

        SPI0/1会使用GPIO6-11、GPIO16-17,模组内部会使用这些引脚作为SPI flash/psram的引脚,故也不应该使用;

        GPIO12-15通常用作JTAG调试使用;

        GPIO34-39只能用作输入模式并且内部没有软件上拉或者下拉功能;

        ADC2引脚当WiFi功能被使用时禁止使用,所以建议使用ADC1。

         上图中排针旁边对应的数字就是GPIO x

        为了帮助大家理解IO交换矩阵和IO MUX,我从技术参考手册里面找来这张图帮助大家理解

         有些信号可以直接通过IO MUX直接送入外设,有些必须经过IO矩阵

        

         IO的内部上拉、下拉实现框图

        以上我们已经简单介绍了一些ESP32的GPIO,下面我们根据ESP-IDF开发框架来具体讲讲GPIO功能。

        GitHub – espressif/esp-idf: Espressif IoT Development Framework. Official development framework for Espressif SoCs.https://github.com/espressif/esp-idf

esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)

        此接口用于配置GPIO,可以一次配置一个IO,也可以同时配置多个IO,前提是多个IO的属性相同。

        下面让我们来看一下gpio_config_t这个结构体的内容

        pin_bit_mask设置需要操作的GPIO引脚,例如我要设置GPIO1和GPIO33

        则pin_bit_mask应该设置为(1ULL << 1 | 1ULL << 33),注意pin_bit_mask类型为uint64_t

        mode用于设置gpio的模式

                GPIO_MODE_INPUT 输入

                GPIO_MODE_OUTPUT 输出

                GPIO_MODE_OUTPUT_OD 开漏输出(如果外部或者内部不上拉电阻则无法输出高电平)

                GPIO_MODE_INPUT_OUTPUT_OD 开漏输入输出

                GPIO_MODE_INPUT_OUTPUT 输入输出

        pull_up_en用于设置是否上拉

        pull_down_en用于设置是否下拉

        gpio_int_type_t intr_type用于设置GPIO中断相关属性

                    GPIO_INTR_DISABLE 关闭中断
                    GPIO_INTR_POSEDGE 上升沿触发
                    GPIO_INTR_NEGEDGE 下降沿触发
                    GPIO_INTR_ANYEDGE 任意边沿触发
                    GPIO_INTR_LOW_LEVEL 低电平触发
                    GPIO_INTR_HIGH_LEVEL 高电平触发

     

三、实战

        现在我们就基于乐鑫原厂esp32-dev开发板讲解GPIO的功能

         我们以实际工程为例,给大家从源代码层面演示一下GPIO的使用

        下面的代码我们初始化GPIO21为上拉输出,GPIO22为下拉输入,然后GPIO21每隔500ms翻转一次,每1s检查一次GPIO22的状态并打印出来。

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"

#define TAG "gpio"

#define BLINK_LED_PIN GPIO_NUM_21
#define BLINK_LED_BLINK 500

//设置GPIO21为上拉输出
//设置GPIO22为下拉输入
void app_main(void) {
    {
        //配置输出引脚21
        //zero-initialize the config structure.
        gpio_config_t io_conf = {};
        //disable interrupt
        io_conf.intr_type = GPIO_INTR_DISABLE;
        //set as output mode
        io_conf.mode = GPIO_MODE_OUTPUT;
        //bit mask of the pins that you want to set,e.g.21
        io_conf.pin_bit_mask = 1ULL << BLINK_LED_PIN;
        //disable pull-down mode
        io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
        //disable pull-up mode
        io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
        //configure GPIO with the given settings
        gpio_config(&io_conf);
    }

    {
        //配置输入引脚22
        //zero-initialize the config structure.
        gpio_config_t io_conf = {};
        //disable interrupt
        io_conf.intr_type = GPIO_INTR_DISABLE;
        //set as output mode
        io_conf.mode = GPIO_MODE_INPUT;
        //bit mask of the pins that you want to set,e.g.22
        io_conf.pin_bit_mask = 1ULL << 22;
        //disable pull-down mode
        io_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
        //disable pull-up mode
        io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
        //configure GPIO with the given settings
        gpio_config(&io_conf);
    }

    int level;
    while (1) {
        gpio_set_level(BLINK_LED_PIN, 1);
        vTaskDelay(BLINK_LED_BLINK / portTICK_PERIOD_MS);
        gpio_set_level(BLINK_LED_PIN, 1);
        vTaskDelay(BLINK_LED_BLINK / portTICK_PERIOD_MS);
        level = gpio_get_level(GPIO_NUM_22);
        ESP_LOGI(TAG, "gpio input level is [%d]", level);
    }
}

       代码里只有这么一行需要特别注意下,一定要给数字常量加上ULL后缀,否则会被当做int对待导致设置比特位出错

        io_conf.pin_bit_mask = 1ULL << 22;

        

        以上,就是ESP32 GPIO的最基本操作;下一篇将介绍GPIO中断相关知识点。

物联沃分享整理
物联沃-IOTWORD物联网 » ESP32系列:GPIO基本输入输出操作实战

发表评论