在ESP32中内部有完整的控制电路,比如上下拉以及滤波器等,所以我们这里可以直接用一个微动开关连接到地。
GPIO_INTR_DISABLE | 不使能中断 |
GPIO_INTR_POSEDGE | 上升沿触发 |
GPIO_INTR_NEGEDGE | 下降沿触发 |
GPIO_INTR_ANYEDGE | 上升沿和下降沿都触发 |
GPIO_INTR_LOW_LEVEL | 低电平触发 |
GPIO_INTR_HIGH_LEVEL | 高电平触发 |
在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;
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
//参数为填充过的gpio_config_t结构体
//返回值:成功返回ESP_OK
// 失败返回ESP_ERR_INVALID_ARG,表示参数错误
//步骤一:安装中断服务,匹配一个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();
}
当每次按键按下,将触发中断服务函数,中断服务函数设置事件组,任务函数获取并处理事件。将得到如下情况:
作者: 二月半, 来源:面包板社区
链接: https://mbb.eet-china.com/blog/uid-me-1862109.html
版权声明:本文为博主原创,未经本人允许,禁止转载!
eeNick 2025-6-12 14:51