[esp32教程]2、按键中断

描述

esp32的按键中断

0、前期准备

1、参考上一篇文章搭建好esp32环境

2、准备好一块esp32开发开发板(本作者使用了esp32c3作为开发平台)

1、知识储备

消息队列:在RTOS中,常用于任务之间或者是中断与任务之间的数据交换。具有特点是:先入入先出,类似我们平时排队进园区旅游,排在前面总是首先进入里面。
在FreeRTOS中,消息队列用的函数有以下几个:
  • 用于创建消息队列

​ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize )

​ 参数如下:

uxQueueLength:队列最大长度
uxItemSize:数据体的数据大小,注意:队列中每个数据体的大小必须要保存一致
  • 用于读取消息队列

​ portBASE_TYPE xQueueReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait )

​ 参数如下:

pxQueue:队列句柄,其值为xQueueCreate放回值,类型为:xQueueHandle
    pvBuffer:数据指针用于指向出队的数据地址
    xTicksToWait:任务中断并等待队列中可用空间的最大时间。若设置为0且队列为空时,调用立刻返回。如果要设置具体时间可以用(时间/portTICK_RATE_MS)公式来获取具体时间。又若设置为( portMAX_DELAY) 将导致任务阻塞
  • 用于写入消息队列

​ portBASE_TYPE xQueueSendFromISR(xQueueHandle pxQueue,const void *pvItemToQueue,portBASE_TYPE *pxHigherPriorityTaskWoken);

​ 参数如下:

pxQueue:队列句柄,其值为xQueueCreate放回值,类型为:xQueueHandle
    pvItemToQueue:要存入队列的数据的指针,数据类型要和xQueueCreate初始化的数据类型一样
    pxHigherPriorityTaskWoken:如果数据入队使任务解锁,并且解锁的任务的优先级高于当前运行任务的优先级xQueueSendFromISR将设置*pxHigherPriorityTaskWokenpdTRUE 。如果xQueueSendFromISR()设置这个值到 pdTRUE,那么在中断退出的时候将会进行任务切换。
ESP32中断

​ ESP32-C3芯片具有硬件滤波器,可去除输入GPIO中不需要的毛刺脉冲,这有助于减少中断的错误触发。

中断函数介绍

  • 中断服务注册函数

​ esp_err_t gpio_install_isr_service( int intr_alloc_flags )

​ 函数说明

​ 使用该函数,ISR服务将提供全局GPIO的ISR,并通过gpio_isr_handler_add()函数注册各个引脚处理程序

​ 参数如下:

intr_alloc_flags:中断的类型
  • GPIO中断注册函数

​ esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num,gpio_isr_t isr_handler,void * args )

​ 函数说明

​ 用于为相应的GPIO引脚添加中断处理函数

​ 参数如下:

gpio_num:GPIO引脚号
    isr_handler:中断处理函数名
    args:往中断函数传递的参数

2、新建工程

idf.py create-project project_led # 新建工程
cd project_key
idf.py set-target esp32c3 # 设置工程使用的芯片

3、查看原理图确定按键控制引脚

ESP32

经查阅原理图,确定led的引脚为gpio_19,读者需根据自身开发板来修改引脚

4、编写程序

#include 

#include 
#include 
#include 

#include 

#define KEY_PIN GPIO_NUM_9
static QueueHandle_t key_queue = NULL;

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

void app_main(void)
{
    uint32_t gpio_num;
    //配置模式 输入 下降沿触发中断
    gpio_config_t cfg = {
        .mode = GPIO_MODE_INPUT,
        .pin_bit_mask = 1ULL << KEY_PIN,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLUP_DISABLE,
        .intr_type = GPIO_INTR_POSEDGE,
    };

    gpio_config(&cfg);
    //创建消息队列、注册中断函数
    key_queue = xQueueCreate(10, sizeof(uint32_t));
    gpio_install_isr_service(0);
    gpio_isr_handler_add(KEY_PIN, key_isr_handler, (void *)KEY_PIN);

    while (pdTRUE)
    {
        //
        if (xQueueReceive(key_queue, &gpio_num, portMAX_DELAY))
        {
            printf("key is down\\\\\\\\n");
        }
    }
    
}

5、编译下载

#编译
idf.py build
#烧录以及查看日志,使用ctrl+] 可以退出监视窗口
idf.py -p /dev/ttyUSB0 flash monitor

审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分