文章目录
一、ESP32引脚资源分配与使用建议
转到博文:ESP32引脚资源分配与使用建议
二、ESP32需要特别注意的几个GPIO
1. Strapping引脚
ESP32 共有5 个Strapping 管脚。
MTDI/GPIO12
:内部下拉GPIO0
:内部上拉GPIO2
:内部下拉MTDO/GPIO15
:内部上拉GPIO5:
内部上拉
系统复位时,这些管脚的值被保存到寄存器。软件可以读取寄存器“GPIO_STRAPPING”中这5 个位的值。该寄存器值一直保持到掉电。
完成复位后,这些管脚被当做普通GPIO 使用。
因此在系统复位时,要处理好这些引脚,要给一个确定的值
GPIO号 | 引脚号 | 作用 | 处理方法 |
---|---|---|---|
12 | 18 | VDD_SDIO 管脚可配置输出1.8 V(Boot 启动时,需GPIO12 的值为1),或输出3.3 V(Boot 启动时,需GPIO12的值为0,默认状态),给外部电路使用(flash)。 | |
:–: | :–: | :–: | :–: |
:–: | :–: | :–: | :–: |
:–: | :–: | :–: | :–: |
:–: | :–: | :–: | :–: |
2. 专用spi flash引脚
GPIO6
GPIO7
GPIO8
GPIO9
GPIO10
GPIO11
一般在模组内部用于外接SPI flash。
Note that GPIO6-11 are usually used for SPI flash.
3. 只具有输入功能的引脚
GPIO34
GPIO35
GPIO36
GPIO37
GPIO38
GPIO39
以上管脚只具有输入功能,没有上拉下拉选项
can only be set as input mode and do not have software pullup or pulldown functions.
三、ESP32 API GPIO使用
- 官方文档release/v3.3版本 ESP_IDF: GPIO & RTC GPIO
1. 输入输出模式
GPIO_MODE_INPUT 输入
GPIO_MODE_OUTPUT 输出
GPIO_MODE_OUTPUT_OD 开漏输出
GPIO_MODE_INPUT_OUTPUT_OD 开漏输入输出
GPIO_MODE_INPUT_OUTPUT 输入输出
2. 中断类型
GPIO_INTR_DISABLE 禁用GPIO中断
GPIO_INTR_POSEDGE GPIO中断类型:上升沿
GPIO_INTR_NEGEDGE 下降沿
GPIO_INTR_ANYEDGE 上升沿和下降沿
GPIO_INTR_LOW_LEVEL 输入低电平触发
GPIO_INTR_HIGH_LEVEL 输入高电平触发
3. 上下拉使能
GPIO_PULLUP_DISABLE 禁用GPIO上拉电阻
GPIO_PULLUP_ENABLE 启用GPIO上拉电阻
GPIO_PULLDOWN_DISABLE 禁用GPIO下拉电阻
GPIO_PULLDOWN_ENABLE 启用GPIO下拉电阻
4. 驱动能力
GPIO_DRIVE_CAP_0 弱 weak
GPIO_DRIVE_CAP_1 强
GPIO_DRIVE_CAP_2 默认值
GPIO_DRIVE_CAP_DEFAULT 默认值
GPIO_DRIVE_CAP_3 最强
四、ESP32 GPIO 中断使用
示例:打印GPIO4和GPIO5的点平变化
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "driver/gpio.h"
#define GPIO_INPUT_IO_0 4
#define GPIO_INPUT_IO_1 5
#define GPIO_INPUT_PIN_SEL ((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))
#define ESP_INTR_FLAG_DEFAULT 0
static xQueueHandle gpio_evt_queue = NULL;
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
static void gpio_task_example(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()
{
gpio_config_t io_conf;
//interrupt of rising edge
io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
//bit mask of the pins, use GPIO4/5 here
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//enable pull-up mode
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
//change gpio intrrupt type for one pin
gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);
//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//start gpio task
xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);
//install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void*) GPIO_INPUT_IO_1);
//remove isr handler for gpio number.
gpio_isr_handler_remove(GPIO_INPUT_IO_0);
//hook isr handler for specific gpio pin again
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
while(1) {
vTaskDelay(1000 / portTICK_RATE_MS);
}
}
注意:
- 请勿在中断服务函数中使用printf
- 中断服务函数添加
IRAM_ATTR
使其放在IRAM中