原创 ESP32开发之GPIO中断

2025-6-12 10:11 137 0 1 分类: MCU/ 嵌入式 文集: ESP32
  • 电路图
  • GPIO的中断类型
  • 相关API函数
  • 应用举例
  • 总结

电路图

在ESP32中内部有完整的控制电路,比如上下拉以及滤波器等,所以我们这里可以直接用一个微动开关连接到地。

fig:

GPIO的中断类型

GPIO_INTR_DISABLE

不使能中断

GPIO_INTR_POSEDGE

上升沿触发

GPIO_INTR_NEGEDGE

下降沿触发

GPIO_INTR_ANYEDGE

上升沿和下降沿都触发

GPIO_INTR_LOW_LEVEL

低电平触发

GPIO_INTR_HIGH_LEVEL

高电平触发

在GPIO中断应用中,一般使用上升沿或者下降沿触发

相关API函数

  1. GPIO配置结构体


typedef struct {
    uint64_t pin_bit_mask;          /*gpio引脚的位掩码 ,设置为(1ULL<<GPIO_NUM)*/
    gpio_mode_t mode;               /*GPIO模式,中断设置为输入模式                    */
    gpio_pullup_t pull_up_en;       /*GPIO上拉使能                               */
    gpio_pulldown_t pull_down_en;   /*GPIO下拉使能                                      */
    gpio_int_type_t intr_type;      /*GPIO中断类型                            */
#if SOC_GPIO_SUPPORT_PIN_HYS_FILTER
    gpio_hys_ctrl_mode_t hys_ctrl_mode;       /*GPIO迟滞过滤控制模式 */
#endif
} gpio_config_t;


  1. GPIO配置函数


esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
//参数为填充过的gpio_config_t结构体
//返回值:成功返回ESP_OK
//             失败返回ESP_ERR_INVALID_ARG,表示参数错误


  1. 注册中断


//步骤一:安装中断服务,匹配一个gpio中断
esp_err_t gpio_install_isr_service(
    int intr_alloc_flags     //用于分配中断的标志,一般为ESP_INTR_FLAG_*,在 esp_intr_alloc.h定义
)
/*返回值:
ESP_OK :成功
ESP_ERR_NO_MEM :没有内存安装这个服务
ESP_ERR_INVALID_STATE :中断服务已安装
ESP_ERR_NOT_FOUND :没有找到指定标志的空闲中断
ESP_ERR_INVALID_ARG :gpio错误
*/
    
//步骤二:给gpio中断添加服务函数   
esp_err_t gpio_isr_handler_add(
    gpio_num_t gpio_num,  //gpio编号
    gpio_isr_t isr_handler,//中断服务函数
    void *args//传递给中断服务函数的参数
)


应用举例


/**
 * Copyright (C) 2024-2034 HalfMoon2.
 * All rights reserved.
 * 
 * @file 	 Filename without the absolute path
 * @brief 	 Brief description
 * @author 	 HalfMoon2
 * @date 	 2025-06-10
 * @version	 v0.1
 * 
 * @revision history:
 * 	 2025-06-10 - Initial version.
 */
#include <stdio.h>
#include <driver/gpio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include <esp_log.h>

#define KEY_GPIO GPIO_NUM_7
#define LED_GPIO GPIO_NUM_4

#define EVENT_BIT0  (1<<0)

static EventGroupHandle_t gpio_event=NULL;

static void IRAM_ATTR gpio_isr_handler(void *pvparam)
{
	BaseType_t  pxHigherPriorityTaskWoken= pdFALSE;//先储存下来,在此例程中不做处理
	xEventGroupSetBitsFromISR(gpio_event,EVENT_BIT0,&pxHigherPriorityTaskWoken);
}

void event_task(void *pvparam)
{
	while(1){
		if(xEventGroupWaitBits(gpio_event,EVENT_BIT0,pdTRUE,pdFALSE,portMAX_DELAY)==0x01){
			gpio_set_level(LED_GPIO,1);
			vTaskDelay(pdMS_TO_TICKS(100));
			gpio_set_level(LED_GPIO,0);
			ESP_LOGI("key","Event Wait Success!!!");
		}
	}
}

/**
 * @brief 	 GPIO初始化
 */
void gpio_init(void)
{
	/*配置LED所连接的GPIO*/
	gpio_config_t led_config={
		.mode=GPIO_MODE_OUTPUT,
		.pin_bit_mask=(1ULL << LED_GPIO),
		.pull_up_en=GPIO_PULLUP_DISABLE,
		.pull_down_en=GPIO_PULLDOWN_DISABLE,
		.intr_type=GPIO_INTR_DISABLE
	};
	gpio_config(&led_config);

	/*配置key所连接的GPIO*/
	gpio_config_t key_config={
		.mode=GPIO_MODE_INPUT,
		.pin_bit_mask=(1ULL << KEY_GPIO),
		.pull_up_en=GPIO_PULLUP_ENABLE,
		.pull_down_en=GPIO_PULLDOWN_DISABLE,
		.intr_type=GPIO_INTR_NEGEDGE
	};
	gpio_config(&key_config);

	/*创建事件组,用于发出中断事件*/
	gpio_event=xEventGroupCreate();

	/*任务创建 */
	xTaskCreatePinnedToCore(event_task,"event_task",2048,NULL,10,NULL,1);

	/*安装中断服务,此函数进行中断寄存器初始化,并注册中断*/
	gpio_install_isr_service(0);

	/*给特定GPIO添加中断服务函数 */
	gpio_isr_handler_add(KEY_GPIO,gpio_isr_handler,NULL);
	
}

void app_main(void)
{
	gpio_init();		
}


当每次按键按下,将触发中断服务函数,中断服务函数设置事件组,任务函数获取并处理事件。将得到如下情况:

fig:

总结

  1. 在中断服务函数中不要使用ESP_LOGI或者printf等打印函数,将报错
  2. 不能直接使用gpio_isr_register()函数,会报段错误,因为在注册之前需要清除中断寄存器等操作。可以通过分析gpio_install_isr_service()函数原型了解其中缘由。
  3. GPIO中断服务函数前一定要添加IRAM_ATTR关键字,表示将此函数放在内部RAM中,未添加则将放在flash中,中断触发后会反应很慢。

作者: 二月半, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-1862109.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

eeNick 2025-6-12 14:51

感谢分享,奖励50E币
相关推荐阅读
二月半 2025-06-12 14:32
【拆解】一款远程控制开关
七年前买了个远程控制开关,想想那个时候应该物联网才兴起的时候吧。如今因为控制麻烦且经常出现连接掉线问题,于是给淘汰了。这个设备我是拿来控制吊灯,特别麻烦的是,当晚上关灯后,会有一点灯点亮着,掉线的时候...
二月半 2025-06-09 22:37
ESP32开发之WS2812B控制
WS2812B数据手册重点摘录硬件电路Remote Control Transceive(RMT)概念RMT的相关API函数一段简单的控制WS2812B的应用举例总结WS2812B数据手册重点摘录WS...
二月半 2025-06-04 09:07
10. ESP32开发之LED闪烁和呼吸的实现
硬件电路介绍GPIO输出模式GPIO配置过程闪烁灯的源码LED PWM的控制器(LEDC)概述LEDC配置过程及现象整体流程硬件电路介绍电路图如下:只要有硬件基础的应该都知道上图中,当GPIO4的输出...
二月半 2025-06-02 21:24
【Milk-V Duo 开发板】+初用体验
许久未在面包板社区申请板卡评测了。这一次偶然最近的这款Milk-V Duo开发板正在评测。首次看到如此简单切功能强大的嵌入式平台:· 支持linux、rtos· 可接一路Camera,做人脸检测、目标...
二月半 2025-05-18 20:54
7. ESP32开发之freeRTOS的互斥量
什么是互斥量互斥量的应用场合互斥量的API函数基本代码结构互斥量使用举例递归锁递归锁举例总结什么是互斥量在freeRTOS中,多个任务访问一块共享资源,会产生竞争现象。比如马路上只有一个很早以前的电话...
我要评论
1
0
关闭 站长推荐上一条 /3 下一条