一.GPIO输入输出配置
想要配置GPIO为简单的高低电平输出有2种方法
方式一:基本方式
1:将GPIO设置成普通IO口 | gpio_pad_select_gpio(需要设置的IO口) |
2:设置GPIO模式 | gpio_set_direction(需要设置的IO口,IO模式) |
3:设置默认电平(输入模式不需要) | gpio_set_level(需要设置的IO口,0/1) |
代码如下:
void LED_GPIO_Init(void)
{
gpio_pad_select_gpio(GPIO_LED); // 选择GPIO口
gpio_set_direction(GPIO_LED, GPIO_MODE_OUTPUT); // GPIO作为输出,GPIO模式如下
//GPIO_MODE_DISABLE 禁用输入和输出;
//GPIO_MODE_INPUT 仅输入;
//GPIO_MODE_OUTPUT 仅输出模式;
//GPIO_MODE_OUTPUT_OD 只输出开漏模式;
//GPIO_MODE_INPUT_OUTPUT_OD 输出和输入采用开漏模式;
//GPIO_MODE_INPUT_OUTPUT 输出和输入模式
gpio_set_level(GPIO_LED, 0); // 默认低电平
}
方式二:结构体方式
通过配置gpio_config_t结构体来配置GPIO,再通过gpio_config(配置好的结构体)函数使能.
代码如下:
#define GPIO_SET 22 // 配置GPIO口
#define GPIO_SET_IO (1ULL<<GPIO_Set) // 配置GPIO_Set位寄存器
void gpio_init(void)
{
gpio_config_t io_conf; // 定义一个gpio_config类型的结构体,下面的都算对其进行的配置
io_conf.intr_type = GPIO_INTR_DISABLE; // 禁止中断,中断模式如下
//GPIO_INTR_POSEDGE 上升沿中断
//GPIO_INTR_NEGEDGE 下降沿中断
//GPIO_INTR_ANYEDGE 上升沿和下降沿中断
//GPIO_INTR_LOW_LEVEL 输入低电平触发中断
//GPIO_INTR_HIGH_LEVEL 输入高电平触发中断
//GPIO_INTR_DISABLE 禁止中断
io_conf.mode = GPIO_MODE_OUTPUT; // 选择输出模式
//GPIO_MODE_DISABLE 禁用输入和输出;
//GPIO_MODE_INPUT 仅输入;
//GPIO_MODE_OUTPUT 仅输出模式;
//GPIO_MODE_OUTPUT_OD 只输出开漏模式;
//GPIO_MODE_INPUT_OUTPUT_OD 输出和输入采用开漏模式;
//GPIO_MODE_INPUT_OUTPUT 输出和输入模式
io_conf.pin_bit_mask = GPIO_SET_IO; // 配置GPIO_OUT寄存器
io_conf.pull_down_en = 0; // 禁止下拉
io_conf.pull_up_en = 0; // 禁止上拉
gpio_config(&io_conf); // 最后配置使能
}
gpio_set_level(GPIO_SET, 0); // 把这个GPIO输出低电平
gpio_set_level(GPIO_SET, 1); // 把这个GPIO输出高电平
二.GPIO中断配置
- 通过配置gpio_config_t结构体将GPIO配置成需要的中断模式并注册结构体;
- 通过函数gpio_install_isr_service(优先级参数)安装GPIO全局中断服务,即所有GPIO中断共享一个优先级!如需单独设置GPIO优先级参考后续学习笔记!
- 最后是通过函数gpio_isr_handler_add(GPIO,相应 ISR 处理函数,ISR 处理程序的参数);注册中断回调函数开启中断;
具体代码如下
#define GPIO_SET 22 // 配置GPIO口
#define GPIO_SET_IO (1ULL<<GPIO_Set) // 配置GPIO_Set位寄存器
void gpio_init(void)
{
gpio_config_t io_conf; // 定义一个gpio_config类型的结构体,下面的都算对其进行的配置
io_conf.intr_type = GPIO_INTR_NEGEDGE; // 禁止中断,中断模式如下
//GPIO_INTR_POSEDGE 上升沿中断
//GPIO_INTR_NEGEDGE 下降沿中断
//GPIO_INTR_ANYEDGE 上升沿和下降沿中断
//GPIO_INTR_LOW_LEVEL 输入低电平触发中断
//GPIO_INTR_HIGH_LEVEL 输入高电平触发中断
//GPIO_INTR_DISABLE 禁止中断
io_conf.mode = GPIO_MODE_INPUT; // 选择输出模
io_conf.pin_bit_mask = GPIO_SET_IO; // 配置GPIO_OUT寄存器
io_conf.pull_down_en = 0; // 禁止下拉
io_conf.pull_up_en = 1; // 引脚电平上拉
gpio_config(&io_conf); // 最后配置使能
gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1); //注册GPIO全局中断服务,参数为优先级如下
/*具体参阅 esp_intr_alloc.h
ESP_INTR_FLAG_LEVEL1 //< Accept a Level 1 interrupt vector (lowest priority)
ESP_INTR_FLAG_LEVEL2 //< Accept a Level 2 interrupt vector
ESP_INTR_FLAG_LEVEL3 //< Accept a Level 3 interrupt vector
ESP_INTR_FLAG_LEVEL4 //< Accept a Level 4 interrupt vector
ESP_INTR_FLAG_LEVEL5 //< Accept a Level 5 interrupt vector
ESP_INTR_FLAG_LEVEL6 //< Accept a Level 6 interrupt vector
ESP_INTR_FLAG_NMI //< Accept a Level 7 interrupt vector (highest priority)
ESP_INTR_FLAG_SHARED //< Interrupt can be shared between ISRs
ESP_INTR_FLAG_EDGE //< Edge-triggered interrupt
ESP_INTR_FLAG_IRAM //< ISR can be called if cache is disabled
ESP_INTR_FLAG_INTRDISABLED //< Return with this interrupt disabled
ESP_INTR_FLAG_LOWMED //< Low and medium prio interrupts.These can be handled in C.
ESP_INTR_FLAG_HIGH //< High level interrupts. Need to be handled in assembly.
ESP_INTR_FLAG_LEVELMASK //< Mask for all level flags
*/
gpio_isr_handler_add(GPIO_SET, gpio_isr_handler,NULL);//添加中断处理函数
}
void IRAM_ATTR gpio_isr_handler()//中断回调函数
{
;//中断内容
}
拓展:ESP32 芯片具有 34 个物理 GPIO 焊盘,对应功能如下表
通用输入输出口 |
模拟功能 | 实时时钟通用输入输出 | 注释 |
---|---|---|---|
GPIO0 | ADC2_CH1 | RTC_GPIO11 | Strapping pin;电容式触摸GPIO |
GPIO1 | TXD | ||
GPIO2 | ADC2_CH2 | RTC_GPIO12 | Strapping pin;电容式触摸GPIO |
GPIO3 | RXD | ||
GPIO4 | ADC2_CH0 | RTC_GPIO10 | 电容式触摸GPIO |
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;电容式触摸GPIO |
GPIO13 | ADC2_CH4 | RTC_GPIO14 | JTAG;电容式触摸GPIO |
GPIO14 | ADC2_CH6 | RTC_GPIO16 | JTAG;电容式触摸GPIO |
GPIO15 | ADC2_CH3 | RTC_GPIO13 | Strapping pin;JTAG;电容式触摸GPIO |
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 | 电容式触摸GPIO |
GPIO32 | ADC1_CH4 | RTC_GPIO9 | 电容式触摸GPIO |
GPIO33 | ADC1_CH5 | RTC_GPIO8 | 电容式触摸GPIO |
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 |
需要注意:
- GPI:GPIO34-39只能设置为输入模式,没有软件使能的上拉或下拉功能
- TXD & RXD 通常用于刷机和调试
- ADC2:使用 Wi-Fi 时不能使用 ADC2 引脚。因此,如果您使用 Wi-Fi 并且无法从 ADC2 GPIO 获取值,您可以考虑改用 ADC1 GPIO
- 使用 ADC 或睡眠模式下使用 Wi-Fi 和蓝牙时,请不要使用 GPIO36 和 GPIO39 的中断。有关问题的详细描述,请参考 ESP32 ECO 和 Bug 解决方法 > 中的第 3.11 节。
- Strapping 引脚:GPIO0、GPIO2、GPIO5(开机时必须为高电平)、GPIO12 (MTDI)(开机时必须为高电平) 和 GPIO15 (MTDO)(开机时必须为高电平) 是 Strapping 引脚。更多信息,请参考ESP32 datasheet
- SPI0/1:GPIO6-11 和 GPIO16-17 通常连接到模块集成的 SPI flash 和 PSRAM,因此不应用作其他用途。
- JTAG:GPIO12-15 通常用于在线调试。
-
ESP32有两个I2C通道,任何引脚都可以设置为SDA或SCL.默认的I2C引脚是GPIO 21 (SDA);GPIO 22 (SCL)
-
默认情况下,SPI的引脚映射是:
-
每个GPIO的绝对最大电流为40mA
-
有些GPIO在启动或复位时,会将其状态变为HIGH或输出PWM信号.这意味着,如果您的输出连接到这些GPIO上,当ESP32复位或启动时,您可能会得到意想不到的结果
GPIO 1
GPIO 3
GPIO 5
GPIO 6-11(连接到ESP32集成的SPI闪存——不建议使用)
GPIO 14
GPIO 15 -
EN是3.3V调节器的使能引脚。它是被拉起的,因此连接到GND以禁用3.3V调节器。例如,这意味着您可以使用这个连接到按钮的引脚来重启您的ESP32
三.通用定时器
- 16-bit 时钟预分频器,分频系数为 2-65536
- 64-bit 时基计数器
- 可配置的向上/向下时基计数器:增加或减少
- 暂停和恢复时基计数器
- 报警时自动重新加载
- 当报警值溢出/低于保护值时报警
- 软件控制的即时重新加载
- 电平触发中断和边沿触发中断
16-bit 预分频器是以 APB 时钟(缩写 APB_CLK,频率通常为 80 MHz)作为基础时钟,在使用寄存 器 TIMGn_Tx_DIVIDER 配置分频器除数前,必须关闭定时器.否则会导致不可预知的结果.
64-bit 通用定时器可自动重新加载向上/向下计数器且支持自动重新加载和软件即时重新加载,计数器达到软件设定值时会触发报警事件
想要通过idf创建硬件定时器需要以下步骤
- 包含#include "driver/timer.h"头文件
- 提前提供配置结构体 timer_config_t
- 将结构传递给 timer_init(定时器分组,定时器型号,结构体地址) 函数创建定时器
- 设置定时器预装值 timer_set_counter_value(定时器分组,定时器型号,0x00000000ULL)
- 设置报警阈值 timer_set_alarm_value(定时器分组,定时器型号,3000*(TIMER_BASE_CLK/8/1000))