ESP32之ESP-IDF学习笔记3——GPIO输入、外部中断

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

记录一下,对知识的整理和复习,方便你我他。。。
只是记录的外设的API函数的使用,外设知识不介绍。
IDF版本V5.1.2

一、需要的头文件

#include "driver/gpio.h"
#include "esp_attr.h"

二、API

/*
函数: gpio_config
功能: gpio通用配置函数
输入: pGPIOConfig:结构体
返回值: ESP_OK:成功;其它:失败
*/
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)

/*
函数: gpio_set_intr_type
功能: 单独设置中断的触发类型
输入: gpio_num:要配置的引脚号;intr_type:触发类型(枚举值)
返回值: ESP_OK:成功;其它:失败
*/
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)

/*
函数: gpio_install_isr_service
功能: 安装GPIO中断服务 -> 分配中断标志,与gpio_isr_register()有冲突。
输入: intr_alloc_flags:中断标志
返回值: ESP_OK:成功;其它:失败
*/
esp_err_t gpio_install_isr_service(int intr_alloc_flags);

/*
函数: gpio_isr_handler_add
功能: 给GPIO添加中断服务函数,可以把多个GPIO的中断服务添加在同一个函数中,用传的引脚号来做区分。猜测是因为中断标志有限才这样做的
输入: gpio_num:引脚号,isr_handler:中断服务函数,args:数据用来区分是哪个引脚触发的
返回值: ESP_OK:成功;其它:失败
*/
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void *args);

/*
函数: gpio_isr_handler_add
功能:删除对应GPIO引脚的ISR处理程序。
输入: gpio_num:引脚号
返回值: ESP_OK:成功;其它:失败
*/
esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num);

三、普通的输入引脚初始化

void KeyInint(void)
{
    gpio_config_t GpioConfigt;

    GpioConfigt.pin_bit_mask = BIT64(KEY);//设置引脚
    GpioConfigt.mode = GPIO_MODE_INPUT;//设置模式
    GpioConfigt.pull_up_en = GPIO_PULLUP_ENABLE;//上拉使能
    GpioConfigt.pull_down_en = GPIO_PULLDOWN_DISABLE;//下拉失能
    GpioConfigt.intr_type = GPIO_INTR_DISABLE;//配置中断
    gpio_config(&GpioConfigt);
}

//使用,按一次按键灯翻转一次
void app_main(void)
{
    char *tag = "main";
    uint8_t flag1 = 0;
    esp_log_level_set(tag, ESP_LOG_DEBUG); //设置日志等级
    Led_init();
    KeyInint();
    while(1)
    {
        if(gpio_get_level(KEY) == 0)
        {
            vTaskDelay(10);
            while(gpio_get_level(KEY) == 0);
            flag1 = !flag1;
            LED0(flag1);
        }
        vTaskDelay(10);
    }
}

四、外部中断初始化

注意:IRAM_ATTR 需要添加 “esp_attr.h” 头文件,否则会编译报错。

uint8_t flag = 0;
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    
    switch(gpio_num)
    {
        case GPIO_NUM_0:
        {
            flag = !flag;
            LED0(flag);
            break;
        }
        default: break;
    }  
}

void KeyExtiInit(void)
{
    gpio_config_t GpioConfigt;

    GpioConfigt.pin_bit_mask = BIT64(KEY);//设置引脚
    GpioConfigt.mode = GPIO_MODE_INPUT;//设置模式
    GpioConfigt.pull_up_en = GPIO_PULLUP_ENABLE;//上拉使能
    GpioConfigt.pull_down_en = GPIO_PULLDOWN_DISABLE;//下拉失能
    GpioConfigt.intr_type = GPIO_INTR_POSEDGE;//配置中断,上降沿
    gpio_config(&GpioConfigt);

    //gpio_set_intr_type(KEY, GPIO_INTR_NEGEDGE);//单独设置引脚的中断

    //安装GPIO中断服务 -> 分配中断标志,与gpio_isr_register()有冲突。
    gpio_install_isr_service(KeyIntrNo);
    
    //给GPIO添加中断服务函数,可以把多个GPIO的中断服务添加在同一个函数中,用传的引脚号来做区分。猜测是因为中断标志有限才这样做的。
    gpio_isr_handler_add(KEY, gpio_isr_handler, (void*) KEY);

    //删除gpio号的isr处理程序
    // gpio_isr_handler_remove(GPIO_INPUT_IO_0);
}

使用的时候只要初始化一下就行了。每触发一次中断就会执行gpio_isr_handler函数

五、补充

  1. IRAM_ATTR 需要添加 “esp_attr.h” 头文件,否则会编译报错。
  2. 不要再中断中用 printf 和 ESP LOGX函数,否则会报硬件错误,网上有大佬说ESP就这样不支持。
  3. ESPIDF对GPIO的输出没有翻转函数,很麻烦。而且GPIO再输出模式下gpio_get_level()函数是失效的。
  4. ESPIDF学习还是很慢的,可能会转学Arduino。
  5. 2024.02.23 GPIO设置为 GPIO_MODE_INPUT_OUTPUT 或者 GPIO_MODE_INPUT_OUTPUT_OD 模式时可以用gpio_get_level()获取引脚的电平情况。
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值