记录3:ESP32-C3的中断

环境

系统:Ubuntu 16.04
软件:ESP-IDF
硬件平台:安信可开发板(使用自制开发板或者其他开发板子都可以)

1、前期准备

这里笔者还是使用安信可开发板上的资源(因为懒得画板子)

按键的引脚的确定
在这里插入图片描述
在这里插入图片描述
led引脚的确定
在这里插入图片描述
在这里插入图片描述

2、创建工程

#1、初始化ESP-IDF环境
get_idf
#2、创建工程 idf.py create-project 工程名
idf.py create-project led
#3、配置工程芯片为esp32c3
cd led
idf.py set-target esp32c3
#4、使用menuconfig配置工程
#进入配置界面,配置相关信息,配置完成后保存,退出
#配置详情如下:
#Component config → ESP32C3-Specific → Minimum Supported ESP32-C3 Revision
#选择REV0
idf.py menuconfig

3、代码编写

这里笔者参考了官方历程写的一个例子

#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"

#define GPIO_OUTPUT_IO_0    18
#define GPIO_INPUT_IO_0     9
#define ESP_INTR_FLAG_DEFAULT 0

static xQueueHandle gpio_evt_queue = NULL;

static void gpio_task(void *arg);
static void IRAM_ATTR gpio_isr_handler(void *arg);


void app_main(void)
{
    gpio_config_t io_config;
    io_config.intr_type = GPIO_INTR_DISABLE;
    io_config.pin_bit_mask = 1ULL << GPIO_OUTPUT_IO_0;
    io_config.mode = GPIO_MODE_OUTPUT;
    io_config.pull_down_en = 0;
    io_config.pull_up_en = 0;
    gpio_config(&io_config);

    io_config.intr_type = GPIO_INTR_NEGEDGE;
    io_config.pin_bit_mask = 1ULL << GPIO_INPUT_IO_0;
    io_config.mode = GPIO_MODE_INPUT;
    io_config.pull_down_en = 1;
    gpio_config(&io_config);

    gpio_evt_queue = xQueueCreate(10,sizeof(uint32_t));
    xTaskCreate(gpio_task,"gpio_task",2048,NULL,10,NULL);
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    gpio_isr_handler_add(GPIO_INPUT_IO_0,gpio_isr_handler,NULL);

    printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
    int cnt = 0;
    while (1)
    {
        printf("cnt: %d\n", cnt++);
        vTaskDelay(1000 / portTICK_RATE_MS);
    }
}

char cntt = 0;
static void IRAM_ATTR gpio_isr_handler(void *arg)
{
    cntt++;
    char led_state = cntt %2;
    gpio_set_level(GPIO_OUTPUT_IO_0,led_state);
    xQueueSendFromISR(gpio_evt_queue,&led_state,NULL);

}
static void gpio_task(void *arg)
{
    char led_state;
    while (1)
    {
        if(xQueueReceive(gpio_evt_queue,&led_state,portMAX_DELAY)){
            printf("led state :%d\n",led_state);
        }
    }
}

代码解析
上面的代码工作流程:
1、初始化相关引脚
2、初始化消息队列,用于存放led的状态
3、创建任务,用于打印led的状态
4、安装中断处理服务
5、设置引脚中断时,中断处理函数

相关函数以及结构体解析:
gpio_config_t结构体:

typedef struct {
    uint64_t pin_bit_mask;          //GPIO的引脚
    gpio_mode_t mode;              //GPIO模式 其参数见gpio_mode_t
    gpio_pullup_t pull_up_en;      //上拉使能
    gpio_pulldown_t pull_down_en;  //下拉使能
    gpio_int_type_t intr_type;     //GPIO中断类型 参数见gpio_int_type_t
} gpio_config_t;
typedef enum {
    GPIO_MODE_DISABLE = GPIO_MODE_DEF_DISABLE,                                                         /*!< GPIO mode : disable input and output             */
    GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT,                                                             /*!< GPIO mode : input only                           */
    GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT,                                                           /*!< GPIO mode : output only mode                     */
    GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)),                               /*!< GPIO mode : output only with open-drain mode     */
    GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)), /*!< GPIO mode : output and input with open-drain mode*/
    GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT)),                         /*!< GPIO mode : output and input mode                */
} gpio_mode_t;

typedef enum {
    GPIO_INTR_DISABLE = 0,     /*!< Disable GPIO interrupt (不使能中断)   */
    GPIO_INTR_POSEDGE = 1,     /*!< GPIO interrupt type : rising edge (上升沿)*/
    GPIO_INTR_NEGEDGE = 2,     /*!< GPIO interrupt type : falling edge(下降沿)*/
    GPIO_INTR_ANYEDGE = 3,     /*!< GPIO interrupt type : both rising and falling edge (上升沿和下降沿)*/
    GPIO_INTR_LOW_LEVEL = 4,   /*!< GPIO interrupt type : input low level trigger(低电平)      */
    GPIO_INTR_HIGH_LEVEL = 5,  /*!< GPIO interrupt type : input high level trigger(高电平)     */
    GPIO_INTR_MAX,
} gpio_int_type_t;
esp_err_t gpio_config(const gpio_config_t * pGPIOConfig ):

该函数用于初始化引脚配置

xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize )

该函数用于新建一个队列
参数:

uxQueueLength队列最大长度
uxItemSize数据体的数据大小,注意:队列中每个数据体的大小必须要保存一致
portBASE_TYPE xQueueReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait )

该函数用于读取队列的里面的数值
参数

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将设置 *pxHigherPriorityTaskWoken到 pdTRUE 。如果xQueueSendFromISR()设置这个值到 pdTRUE,那么在中断退出的时候将会进行任务切换。
esp_err_t gpio_install_isr_service( int intr_alloc_flags )

该函数用于安装驱动程序的GPIO ISR处理程序服务,该服务允许每针GPIO中断处理程序
参数

intr_alloc_flags用于分配中断的标志
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num,gpio_isr_t isr_handler,void * args )

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

gpio_numGPIO引脚号
isr_handler中断处理函数名
args往中断函数传递的参数
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)

该函数用于设置GPIO输出的电平
参数

gpio_numGPIO引脚号
level高低电平,1:高电平,0:低电平

4、编译,烧录

//编译
idf.py build
//烧录
idf.py -p /dev/ttyUSB0 flash monitor

附录
环境初始化脚本 init_env.sh

#!/bin/bash
#给usb设备设置权限
echo "sudo chmod 777 /dev/#具体的usb设备名"
$echo sudo chmod 777 /dev/#具体的usb设备名
echo "get_idf"
$echo get_idf

编译运行脚本run.sh

#!/bin/bash
#编译
echo "idf.py build"
$echo idf.py build
#烧录
echo "idf.py -p /dev/ttyUSB0 flash monitor"
$echo idf.py -p /dev/ttyUSB0 flash monitor
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值