BOOT_KEY按键(学习笔记)

先来让我们了解一下GPIO是什么吧,它在单片机中也有很重要的作用,接下来我们来看看吧。

esp32C3是QFN32封装(一种集成电路(IC)封装类型),GPIO引脚一共有22个,从GPIO-0到GPIO-21。从理论上来说,所有的IO引脚都可以复用为任何外设功能,但有些引脚用作连接芯片内部FLASH或者外部FLASH功能时,官方不建议用作其它用途。

esp32c3的GPIO,可以用作输入、输出,可以配置内部上拉、下拉,可以配置为中断引脚。这里我们将BOOT按键的IO-9引脚连接,设置为GPIO中断,用来接收BOOT按键请求。

1.首先,咱们需要复制esp-idf-v5.1.3\examples\get-started\sample_project这个工程到咱们的项目实操文件夹,然后把这个文件夹的名称修改为gpio_key,之后看的时候容易理解,修改后的工程路径为D:\esp32c3\gpio_key。

2.接着打开VScode软件,并打开gpio_key这个文件夹,打开工程一级目录下的CMakeLists.txt文件(不是main目录下的),继续我们把工程名字修改为gpio_key,保存后关闭。

3.接着继续打开VSCode软件,然后打开esp-idf-v5.1.3整个工程文件夹,然后我们依次找到examples\peripherals\gpio\generic_gpio这个工程作为参考,注意不能修改这个工程中的内容和配置,只是作为参考。我们点击gpio_example_main.c打开这个文件,找到app_main函数。复制它的第80~93行代码到我们自己的gpio_key工程中。复制过来以后,我们按照原理图进行了如下的修改

cpp 复制代码
​
​
#include <stdio.h>

void app_main(void)
{
    //zero-initialize the config structure.
    gpio_config_t io_conf = {};//定义了一个gpio_config_t结构体变量
    //falling edge interrupt
    io_conf.intr_type = GPIO_INTR_DISABLE; //定义引脚中断类型
    //set as input mode
    io_conf.mode = GPIO_MODE_OUTPUT; //配置模式
    //bit mask of the pins GPIO-9
    io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; //配置选择哪个引脚
    //disable pull-down mode
    io_conf.pull_down_en = 0;//第五六句配置是否打开上下拉电阻,0是关闭,1是打开,我们把上拉打开
    //disable pull-up mode
    io_conf.pull_up_en = 0;
    //configure GPIO with the given settings
    gpio_config(&io_conf);
}

​

​

在这顺便对上图代码的注释解释进行补充:

p2:开发板上的按键没有按下的时候是高电平,按下去以后是低电平,我们定义成下降沿中断,这里原来是GPIO_INTR_DISABLE,表示中断关闭,这里我们修改为GPIO_INTR_NEGEDGE,即下降沿中断。这些宏定义在gpio_types.h文件中被定义,我们在gpio_example_main.c文件中的GPIO_INTR_DISABLE上单击右键,然后选择"转到定义",就可以找到这几个宏定义

p3:之前的模式是GPIO_MODE_OUTPUT,我们现在修改为GPIO_MODE_INPUT输入模式

p4:把之前的GPIO_OUTPUT_PIN_SEL修改为1<<GPIO_NUM_9,因为BOOT按键连接到了GPIO-9

接下来,咱们再复制gpio_example_main.c文件中的第108~116行代码到main.c文件中,然后我们进行了修改,下面代码是进行修改后的代码

cpp 复制代码
void app_main(void)
{
    gpio_config_t io_conf = {
        .intr_type = GPIO_INTR_NEGEDGE, //falling edge interrupt
        .mode = GPIO_MODE_INPUT, //set as input mode
        .pin_bit_mask = 1<<GPIO_NUM_9, //bit mask of the pins GPIO9
        .pull_down_en = 0, //disable pull-down mode
        .pull_up_en = 1 //enable pull-up mode
    };
    //configure GPIO with the given settings
    gpio_config(&io_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_9, gpio_isr_handler, (void*) GPIO_NUM_9);
}

ps:

第一条创建了一个队列,队列消息数量为10,gpio_evt_queue是队列句柄,一会儿需要我们在main函数外面定义

第二条创建了一个任务,任务名称为gpio_task_example

第三条代码,启动GPIO中断服务,其中ESP_INTR_FLAG_DEFAULT的值是0,这个宏定义是在gpio_example_main.c文件中定义的,我们可以直接把这里改成0,也可以把这个宏定义复制到我们的main.c文件中

第四条代码,添加某个GPIO的中断,这里我们添加GPIO9,第1个和第3个参数,都修改为GPIO_NUM_9

接下来,我们在app_main函数的上方添加队列、中断等相关的代码,复制gpio_example_main.c中的第60~76行到我们的main.c文件中,放到app_main函数的上方

cpp 复制代码
static QueueHandle_t gpio_evt_queue = NULL; //定义了一个队列句柄,用来处理gpio队列消息

static void IRAM_ATTR gpio_isr_handler(void* arg) //定义了两个函数,第一个函数是gpio中断服务函数,当GPIO产生中断的时候呢,会进入这个函数,xQueueSendFromISR函数将参数GPIO_NUM_9添加到队列消息。
第二个函数是gpio的任务函数,在任务函数中,接收队列消息,当接收到一个队列消息时,打印字符串。PRIu32 是C语言中用于格式化输出的宏,用于打印32位无符号整数。它是由C99标准引入的,位于inttypes.h头文件中。在使用该宏时,需要包含inttypes.h头文件。gpio_get_level函数用于获取引脚的电平
{
    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));
        }
    }
}

我们再把需要的头文件添加到我们的main.c文件就可以了

cpp 复制代码
#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"

使用printf函数,需要添加stdio.h头文件。string.h和stdlib.h我们这里用不着,可以去掉。接下来是3个freeRTOS的头文件,最后一个头文件是用于gpio的配置,接着进行编译就行了。

相关推荐
南宫生5 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
sanguine__5 小时前
Web APIs学习 (操作DOM BOM)
学习
冷眼看人间恩怨5 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
数据的世界017 小时前
.NET开发人员学习书籍推荐
学习·.net
四口鲸鱼爱吃盐8 小时前
CVPR2024 | 通过集成渐近正态分布学习实现强可迁移对抗攻击
学习
OopspoO10 小时前
qcow2镜像大小压缩
学习·性能优化
A懿轩A10 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
居居飒10 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
kkflash311 小时前
提升专业素养的实用指南
学习·职场和发展
Hejjon11 小时前
SpringBoot 整合 SQLite 数据库
笔记