ESP32 GPIO中断服务程序注册失败

妖辰晚安 2019-11-03 11:03:30
同样的GPIO初始化代码,放到主程序里就会注册失败,单独一个工程就没问题,为啥?求大佬解释
(已阅读涉及到的源代码,但未能发现错误原因)
下面贴初始化代码(在第67行程序出错):

#define GPIO_INPUT_IO_0 12 //拍照开关
#define GPIO_INPUT_IO_1 4 //靶信号第一位,下面以此类推到第五位
#define GPIO_INPUT_IO_2 2
#define GPIO_INPUT_IO_3 14
#define GPIO_INPUT_IO_4 15
#define GPIO_INPUT_IO_5 13
#define GPIO_INPUT_PIN_SEL1 (1ULL<<GPIO_INPUT_IO_0)
#define GPIO_INPUT_PIN_SEL2 ((1ULL<<GPIO_INPUT_IO_1) | (1ULL<<GPIO_INPUT_IO_2) | (1ULL<<GPIO_INPUT_IO_3) | (1ULL<<GPIO_INPUT_IO_4) | (1ULL<<GPIO_INPUT_IO_5))
#define ESP_INTR_FLAG_DEFAULT 0
static xQueueHandle gpio_evt_queue = NULL;
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}

//gpio_task是中断函数的回调函数,负责完成中断期间的任务
static void gpio_task(void* arg)
{
uint32_t io_num;
while(1) {//不断读取消息队列以便在第一时间处理中断事件
if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
}
}
}
static void my_gpio_init()
{
gpio_config_t io_conf;
//下降沿中断
io_conf.intr_type = GPIO_PIN_INTR_NEGEDGE;
//bit mask of the pins, use GPIO12 here
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL1;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//enable pull-up mode
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
//禁用中断
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
//bit mask of the pins, use GPIO2/4/13/14/15 here
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL2;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//disable pull-up mode
io_conf.pull_up_en = 0;
//disable pull-down mode
io_conf.pull_down_en = 0;
gpio_config(&io_conf);

//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//新建队列
xTaskCreate(gpio_task //任务函数
, "gpio_task" //任务名字
, 2048 //任务堆栈大小
, NULL //传递给任务函数的参数
, 10 //任务优先级
, NULL); //任務句柄

//安装GPIO中断服务
ESP_LOGI(TAG, "GPIO 中断服务安装中...");
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
ESP_LOGI(TAG, "GPIO 中断服务安装完成");
//为GPIO12注册中断服务
ESP_LOGI(TAG, "GPIO12 中断服务注册中...");
//每次都会到这出问题
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
ESP_LOGI(TAG, "GPIO12 中断服务注册完成");
}


下面是相关例程:

/* GPIO Example

This example code is in the Public Domain (or CC0 licensed, at your option.)

Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"

/**
* Brief:
* This test code shows how to configure gpio and how to use gpio interrupt.
*
* GPIO status:
* GPIO18: output
* GPIO19: output
* GPIO4: input, pulled up, interrupt from rising edge and falling edge
* GPIO5: input, pulled up, interrupt from rising edge.
*
* Test:
* Connect GPIO18 with GPIO4
* Connect GPIO19 with GPIO5
* Generate pulses on GPIO18/19, that triggers interrupt on GPIO4/5
*
*/

#define GPIO_OUTPUT_IO_0 18
#define GPIO_OUTPUT_IO_1 19
#define GPIO_OUTPUT_PIN_SEL ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1))
#define GPIO_INPUT_IO_0 4
#define GPIO_INPUT_IO_1 5
#define GPIO_INPUT_PIN_SEL ((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))
#define ESP_INTR_FLAG_DEFAULT 0

static xQueueHandle gpio_evt_queue = NULL;

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}

static void gpio_task_example(void* arg)
{
uint32_t io_num;
for(;;) {
if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
}
}
}

void app_main()
{
gpio_config_t io_conf;
//disable interrupt
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
//set as output mode
io_conf.mode = GPIO_MODE_OUTPUT;
//bit mask of the pins that you want to set,e.g.GPIO18/19
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
//disable pull-down mode
io_conf.pull_down_en = 0;
//disable pull-up mode
io_conf.pull_up_en = 0;
//configure GPIO with the given settings
gpio_config(&io_conf);

//interrupt of rising edge
io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
//bit mask of the pins, use GPIO4/5 here
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//enable pull-up mode
io_conf.pull_up_en = 1;
gpio_config(&io_conf);

//change gpio intrrupt type for one pin
gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);

//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//start gpio task
xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);

//install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void*) GPIO_INPUT_IO_1);

//remove isr handler for gpio number.
gpio_isr_handler_remove(GPIO_INPUT_IO_0);
//hook isr handler for specific gpio pin again
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);

int cnt = 0;
while(1) {
printf("cnt: %d\n", cnt++);
vTaskDelay(1000 / portTICK_RATE_MS);
gpio_set_level(GPIO_OUTPUT_IO_0, cnt % 2);
gpio_set_level(GPIO_OUTPUT_IO_1, cnt % 2);
}
}


下面是出错界面:
...全文
631 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
flyunlimit 2021-10-27
  • 打赏
  • 举报
回复

gpio_install_isr_service 配置的是中断优先级,从1~7,没有0。参数定义在esp_intr_alloc.h里,如ESP_INTR_FLAG_LEVEL1这样的格式。例程里是自己定义了个ESP_INTR_FLAG_DEFAULT 瞎搞的。

妖辰晚安 2019-11-04
  • 打赏
  • 举报
回复
真就没人呗,大佬们呢,难不成我这问题太弱智?!

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧