ESP32外设-1.GPIO入门
说明:
- 本文档由DuRuofu撰写,由DuRuofu负责解释及执行。
- 本文档介绍GPIO的基本使用。
修订历史:
文档名称 | 版本 | 作者 | 时间 | 备注 |
---|---|---|---|---|
ESP32外设-GPIO入门 | v1.0.0 | DuRuofu | 2024-02-29 | 首次建立 |
ESP32外设-GPIO入门
一、GPIO介绍
“通用 IO”或”GPIO”是英文”General-Purpose Input/Output Port”的简写,意为通用输入/输出接 口。当设置为输入模式时,它可以用于感知外部信号;而设置为输出模式时,则可以用于控制 外部设备。在开发过程中,我们经常使用一些简单的外部模块,如 LED、按键和蜂鸣器等。要 使用这些模块,只需将它们与芯片的 GPIO 连接,然后通过控制 GPIO 的输出/读取高低电平即可。
ESP32 芯片具有 34 个物理 GPIO 管脚(GPIO0 ~ GPIO19、GPIO21 ~ GPIO23、GPIO25 ~ GPIO27 和 GPIO32 ~ GPIO39)。每个管脚都可用作一个通用 IO,或连接一个内部的外设信号。通过 IO MUX、RTC IO MUX 和 GPIO 交换矩阵,可配置外设模块的输入信号来源于任何的 IO 管脚,并且外设模块的输出信号也可连接到任意 IO 管脚。这些模块共同组成了芯片的 IO 控制。
二、相关函数介绍
具体参考:GPIO & RTC GPIO
gpio_config 函数:
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
该函数用来配置指定管脚的实时配置状态,包括上下拉、输入输出使能、管脚映射等
gpio_config_t
简介:
成员 | 类型 | 意义 |
---|---|---|
pin_bit_mask | uint64_t | GPIO pin:使用位掩码设置,每个位对应一个GPIO |
mode | gpio_mode_t | GPIO模式:设置输入/输出模式 |
pull_up_en | gpio_pullup_t | GPIO上拉:表示是否启用内部上拉电阻 |
pull_down_en | gpio_pulldown_t | GPIO下拉:表示是否启用内部下拉电阻 |
intr_type | gpio_int_type_t | GPIO中断类型 |
gpio_set_level 函数
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
该函数用来设置 gpiod 电平状态。
gpio_get_level 函数
int gpio_get_level(gpio_num_t gpio_num);
gpio_num 用来指向获取那个 IO 的电平,该函数的返回值就是指定 IO 的电平状态 0 或 1
二、GPIO输出/输入配置
引用头文件:#include "driver/gpio.h"
1、使用结构体配置:
例子:配置GPIO2和4为输出:
1 |
|
这里的pin_bit_mask
是一个uint64_t
类型的变量,有64个二进制位,其中部分位对应这个配置对哪些 GPIO 生效。
1 |
|
2、使用函数单个配置:
使用函数配置,就是把结构体法拆成了函数。
1、设置GPIO方向(输入 或者 输出)
调用函数gpio_set_direction(gpio_num_tgpio_num, gpio_mode_tmode)
1 |
|
2、配置为输出
时,设置某个GPIO的 输出电平
调用函数gpio_set_level(gpio_num_t gpio_num, uint32_t level)
1 |
|
例:GPIO2配置为输出,并输出高电平
1 |
|
3、在配置为输入
模式时,检测GPIO的电平。
调用函数int gpio_get_level(gpio_num_t gpio_num)
1 |
|
例:将GPIO2配置为输入,当GPIO2电平改变时打印
1 |
|
4、函数配置GPIO内部上下拉电阻
gpio_set_pull_mode()
配置GPIO上拉/下拉电阻器。gpio_pullup_en()
启用GPIO上的上拉。gpio_pullup_dis()
禁用GPIO上的上拉。gpio_pulldown_en()
gpio_pulldown_dis()
gpio_set_pull_mode()
:
1 |
|
pull的几种模式:
GPIO_PULLUP_ONLY
—— 仅上拉GPIO_PULLDOWN_ONLY
—— 仅下拉GPIO_PULLUP_PULLDOWN
—— 全部启用GPIO_FLOATING
—— 悬空这个 GPIO
注:只有同时支持输入和输出的引脚集成了上拉和下拉电阻。(仅输入的GPIO 34 至 GPIO 39不需要)
二、GPIO输出/输入实例
下面我们使用上面提到的函数,实现按键按下LED灯亮:
1 |
|
效果:按下LED亮,代码见:
https://github.com/DuRuofu/ESP32_Learning/tree/master/03.peripheral/gpio
二、GPIO中断配置:
通过gpio_config()
函数传递一个结构体gpio_config_t
指针,在gpio_config_t
结构体中声明中断类型。或通过函数gpio_set_intr_type()
函数
必须将GPIO配置为
包含输入
的模式,比如GPIO_MODE_INPUT
或GPIO_MODE_INPUT_OUTPUT
等。
gpio_set_intr_type()
函数介绍:
1 |
|
配置中断示例:
使用结构体:
1 |
|
使用函数:
1 |
|
响应中断:
抛开原理不谈,我们需要做的是写一个函数,让CPU在对应中断触发时执行这个函数即可。
中断服务函数
首先是中断服务函数,我们需要创建一个静态的,带有IRAM_ATTR
宏的函数作为中断服务程序 Handler
原因是GPIO的中断在IRAM中工作。这样的好处是在flash禁用的情况下也可以响应中断。且速度更快,对于这种频繁触发的中断是有利的。但是这个中断也因此无法使用
printf
等串口打印工作,需要转入其他Task中执行,参考中断分配
1 |
|
绑定中断服务函数
为某个GPIO口设置中断服务程序 Handler
1 |
|
函数详解:
esp_err_t gpio_install_isr_service(int intr_alloc_flags);
- 功能:安装GPIO中断服务。这个服务允许你为多个GPIO引脚注册中断处理回调函数。这个函数只需要在第一次设置GPIO中断时被调用一次,用于初始化中断服务。
- 参数:
intr_alloc_flags
:中断分配标志,用于指定中断的分配行为。对于大多数应用,传递0
作为参数即可。如果需要更精细的控制(如指定中断的CPU核心),可以使用ESP_INTR_FLAG_*
系列宏定义。
- 返回值:执行结果,
ESP_OK
表示成功,其他值表示错误。
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void* args);
- 功能:为指定的GPIO引脚添加中断处理函数。当指定的GPIO引脚发生配置的中断事件时(例如电平变化),注册的回调函数将被调用。
- 参数:
gpio_num
:GPIO引脚号,指定要为其添加中断处理函数的GPIO引脚。isr_handler
:中断服务例程(ISR),即当GPIO引脚触发中断时要调用的回调函数。args
:传递给中断处理函数的参数,可以是任意类型的指针。在回调函数中,你可以通过这个参数获取额外的上下文信息。
中断案例:
将刚才的按键点灯修改为中断模式:
1 |
|
注:中断程序要保持简短,不能执行耗时的工作,所以我们一般将中断服务转入其他Task中执行,这部分涉及FreeRTOS,这里不再展开叙述