一、目的
在前面的章节中我们已经介绍了ESP32的开发环境的搭建过程,从本篇开始我们将从最基本的GPIO控制讲起,介绍ESP32上面相关的外设操作。
二、介绍
参考资料
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功能。
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中断相关知识点。