Esp32 外设学习笔记

一.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中断配置

  1. 通过配置gpio_config_t结构体将GPIO配置成需要的中断模式并注册结构体;
  2. 通过函数gpio_install_isr_service(优先级参数)安装GPIO全局中断服务,即所有GPIO中断共享一个优先级!如需单独设置GPIO优先级参考后续学习笔记!
  3. 最后是通过函数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

三.通用定时器

ESP32 内置 4 64-bit 通用定时器。每个定时器包含一个 16-bit 预分频器和一个 64-bit 可自动重新加载向上/向下计数器。
ESP32 的定时器分为 2 组,每组 2 个。 TIMG n _T x n 代表组别, x 代表定时器编号。
定时器特性:
  • 16-bit 时钟预分频器,分频系数为 2-65536
  • 64-bit 时基计数器
  • 可配置的向上/向下时基计数器:增加或减少
  • 暂停和恢复时基计数器
  • 报警时自动重新加载
  • 当报警值溢出/低于保护值时报警
  • 软件控制的即时重新加载
  • 电平触发中断和边沿触发中断

16-bit 预分频器是以 APB 时钟(缩写 APB_CLK,频率通常为 80 MHz)作为基础时钟,在使用寄存 器 TIMGn_Tx_DIVIDER 配置分频器除数前,必须关闭定时器.否则会导致不可预知的结果.

64-bit 通用定时器可自动重新加载向上/向下计数器且支持自动重新加载和软件即时重新加载,计数器达到软件设定值时会触发报警事件

想要通过idf创建硬件定时器需要以下步骤

  1. 包含#include "driver/timer.h"头文件
  2. 提前提供配置结构体 timer_config_t
  3. 将结构传递给 timer_init(定时器分组,定时器型号,结构体地址) 函数创建定时器
  4. 设置定时器预装值 timer_set_counter_value(定时器分组,定时器型号,0x00000000ULL)
  5. 设置报警阈值 timer_set_alarm_value(定时器分组,定时器型号,3000*(TIMER_BASE_CLK/8/1000))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值