从零开始学习ESP-S3(二)————以立创的ESP-S3开发板为例

得益于ESP32提供的巨多例子程序,导致用ESP32写代码显得非常的顺理成章,基本上只要记得步骤(甚至只要跟着示例给的步骤)就可以写完代码。

目标:实现按键中断

一、在ESP-IDF工程中找到GPIO口的代码

在这里插入图片描述
打开之后直接跳到app_main()入口函数,以下是部分语句。

    //定义一个GPIO的结构体
    gpio_config_t io_conf = {};
    //使能选择
    io_conf.intr_type = GPIO_INTR_DISABLE;
    //输出、输入模式选择
    io_conf.mode = GPIO_MODE_OUTPUT;
    //引脚选择
    io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
    //禁用下拉电阻
    io_conf.pull_down_en = 0;
    //禁用上拉电阻
    io_conf.pull_up_en = 0;
    //初始化
    gpio_config(&io_conf);

那么首先,和STM32类似,就是先定义了一个GPIO口的结构体,并且进行初始化。

    //选择引脚中断的触发方式
    gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);

    //创建一个队列,来存放GPIO引脚的编号,
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
    //创造一个任务,传入任务函数,任务名臣,栈内存,传入参数,优先级,句柄。
    xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);

    //启动 GPIO 中断服务
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    //为指定的引脚添加中断任务,传入GPIO引脚,中断服务函数,传入函数的参数
    gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);

接下来是给GPIO口启用中断服务和添加中断函数,与STM32常规配置不同,这里用的是FreeRTOS的函数。它通过创建一个队列,将触发中断GPIO引脚传入队列中,并根据此调用对应的中断函数。我们可以在中断函数中看到它。

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

当触发中断的时候,程序进入gpio_isr_handler函数,然后将这个参数传给xQueueSendFromISR函数。通过这个函数,它会将gpio_num存入gpio_evt_queue队列中,然后后台任务开始被调用。

static void gpio_task_example(void* arg)
{
    uint32_t io_num;
    for(;;) {
    	//如果在gpio_evt_queue中对应的GPIO口触发了中断,则打印对应的端口和电平值。
        if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
            printf("GPIO[%"PRIu32"] intr, val: %d\n", io_num, gpio_get_level(io_num));
        }
    }
}

根据这个代码,我们可以写个非常非常简单的复制版本:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"

static QueueHandle_t 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[%"PRIu32"] intr, val: %d\n", io_num, gpio_get_level(io_num));
        }
    }
}


void app_main(void)
{
    //zero-initialize the config structure.
    gpio_config_t io0_conf = {
    //上升沿触发中断
        .intr_type = GPIO_INTR_POSEDGE,
    //设置为输出模式
        .mode = GPIO_MODE_INPUT,
    //初始化引脚IO0
        .pin_bit_mask = (1ULL << GPIO_NUM_0),
    //禁止推挽
        .pull_down_en = 0,
    //打开内部上拉电阻
        .pull_up_en = 1
    };

    //初始化
    gpio_config(&io0_conf);

    //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(0);
    //hook isr handler for specific gpio pin
    gpio_isr_handler_add(GPIO_NUM_0, gpio_isr_handler, (void*) GPIO_NUM_0);
}

实验结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值