ESP32-GPIO带详细注释

原创不易,转载需注明来源:https://blog.csdn.net/qq_32955031

下面程序呢是乐鑫提供的GPIO使用例程,其中包括GPIO的输入输出设置,中断设置,当然避免不了ESP32基于的Free RTOS系统的一些内容,笔者呢,对其进行了一些注解,将一些函数的API解析文件整理了出来(中文的版本的),为了自己方便学习,在运行例程的基础上也对这个例程做了一些改变,对应自己整理处理出的文档实验,方便自己的理解。
下面就是解析后的源码了
 
/**
 * 本例程在Esp 官方例程上加以改动以及注释本人对本例程的理解
 * 例程功能见下方Brief(简介)
 * 本人联系方式QQ:1737410733
 * 本人CSDN博客:https://blog.csdn.net/qq_32955031
 * 
*/

#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以及如何使用gpio中断。
 *
 * 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-在GPIO18 / 19上产生脉冲,触发GPIO4 / 5上的中断
 *
 */



#define GPIO_OUTPUT_IO_0    18                                                       //定义GPIO18为输出管脚0
#define GPIO_OUTPUT_IO_1    19                                                       //定义GPIO19为输出管脚1
#define GPIO_OUTPUT_PIN_SEL  ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1))   //混合
#define GPIO_INPUT_IO_0     4                                                        //定义GPIO4为输入管脚0
#define GPIO_INPUT_IO_1     5                                                        //定义GPIO5为输入管脚1
#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;
    //向消息队列中投递消息,消息内容为GPIO的管脚号
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
//GPIO中断消息处理任务
static void gpio_task_example(void* arg)
{
    uint32_t io_num;
    for(;;) {
        //API函数:xQueueReceive,见本人整理文档之FreeRTOS篇【整理以最新版本最优】
        //这是一个调用xQueueGenericReceive()函数的宏。
        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的结构体
    gpio_config_t io_conf;
    //disable interrupt
    //禁用GPIO中断
    io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
    //set as output mode
    //GPIO设置为输出模式
    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配置,API函数:gpio_config 见本人整理文档之GPIO篇【整理版本以最新最优】
    gpio_config(&io_conf);

    //interrupt of rising edge
    //GPIO中断类型:上升沿
    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   
    //GPIO输入模式 
    io_conf.mode = GPIO_MODE_INPUT;
    //enable pull-up mode
    //势能上拉模式
    io_conf.pull_up_en = 1;
    //configure GPIO with the given settings
    //GPIO配置,API函数:gpio_config, 见本人整理文档之GPIO篇【整理版本以最新最优】   
    gpio_config(&io_conf);

    //change gpio intrrupt type for one pin
    //改变其中一个管教的中断管脚;API函数:gpio_set_intr_type,见本人整理文档之GPIO篇【整理版本以最新最优】  
    gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);

    //create a queue to handle gpio event from isr
    //创建一个队列来处理来自isr的gpio事件
    //创建新的队列实例,API函数:xQueueCreate,见本人整理文档之FreeRTOS篇
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
    //start gpio task
    //创建任务,API函数;xTaskCreate 见本人整理文档之FreeRTOS篇【整理以最新版本最优】
    xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);

    //install gpio isr service
    //安装驱动程序的GPIO ISR处理程序服务,该服务允许每个引脚的GPIO中断处理程序。
    //该API函数:gpio_install_isr_service,见本人整理文档之GPIO篇【整理版本以最新最优】
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    //hook isr handler for specific gpio pin
    //为相应的GPIO引脚添加ISR处理程序。
    //该API函数:gpio_isr_handler_add,见本人整理文档之GPIO篇【整理版本以最新最优】
    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处理程序。
    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);
        //设置RTC IO输出电平。
        gpio_set_level(GPIO_OUTPUT_IO_0, cnt % 2);
        gpio_set_level(GPIO_OUTPUT_IO_1, cnt % 2);
    }
}

这个例程,理解起来并不复杂,总的功能就是把 GPIO 18以及GPIO 19设置为输出管脚,输出电平只有0或者1,即搞定电平,根据ESP32 的供电电压,高电平近3.3V ,低电平约为0V。GPIO 4 与GPIO 5为电平输入管脚,即只能体现输入电压为高电平还是低电平,这个应用可以用于 按键输入控制,根据实际电路情况去对应按键的输入输出情况。
需要注意的是基本GPIO(输入&输出)有上拉、下拉的配置,暂时我没有注意到默认是什么模式。如果有认真看过文档知道也可以评论说一下一起进步啊;
除了设置一些基本的GPIO模式外就是Free RTOS的的事情了,这部分我没有好好研读官方文件,之前了解过的也忘得差不多了。就暂时不误人子弟了。看注释就多多少少能理解了。
效果演示的话,参考下面图片。
在这里插入图片描述
因为这里延迟了1秒,即方波的频率为0.5HZ,高电平为3.3。

vTaskDelay(1000 / portTICK_RATE_MS);

这边显示的是串口信息,上电打印了部分系统信息外,还输出了GPIO的设置。
在这里插入图片描述
将GPIO4 连接到 GPIO19后的实验现象如下
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值