ESP32系列文章目录

ESP32C3学习&开发之路——操作GPIO点灯



前言

通过前面的学习了解到ESP32C3的内置ESP32C3 芯片是一个 RISC-V 32 位单核微处理器而且有丰富的外设,在STM32系列单片机的开发中最基础的是操作GPIO,控制外接的灯、继电器或者一些简单的设备,ESP32C3 里面的32位单片机也是可以通过编程操作GPIO输出高低电平或者读取输入GPIO的电平值。本次会正式进入ESP32C3的编程中,包括了解ESP的GPIO特性、了解ESP的编程风格、了解ESP的freertos风格和了解ESP的GPIO驱动库。


一、ESP32C3的GPIO

GPIO:通用输入/输出,在处理器中没有特定的功能,但它的功能是可以通过软件控制的。
ESP32C3的GPIO结构要简单些,可以查看《esp32-c3_technical_reference_manual_cn》第五章有关GPIO描述,如下图,展示了ESP32C3的GPIO基本结构。
在这里插入图片描述
GPIO引脚可配置:
• 输入关闭,高阻(IE = 0)
• 输入使能,高阻(IE = 1)
• 输入使能,下拉电阻使能(IE = 1, WPD = 1)
• 输入使能,上拉电阻使能(IE = 1, WPU = 1)
• 输出使能,上拉电阻使能(OE = 1, WPU = 1)
• 模拟输入(部分引脚支持)
• 复用功能
驱动强度:~5 mA——40mA,不同的引脚驱动能力不一样。

GPIO的功能还能通过GPIO 交换矩阵将引脚复用作其他功能,例如 UART、 SPI 等,这里不做延伸,后面有使用到再记录。

ESP32C3的所有GPIO引脚都是按照顺序来定义的,不像STM32因为有众多GPIO引脚需要分为PA、PB、……等,所以配置和使用会不同,从ESP32引脚定义的头文件gpio_types.h中也可以了解到,ESP32C3只有22个引脚,如图
在这里插入图片描述
要操作GPIO引脚实现一些特定的功能需要编写软件对相关的寄存器进行配置和操作,ESP32C3的GPIO也有众多的寄存器(参考《esp32-c3_technical_reference_manual_cn》)。这次主要是操作GPIO控制灯的闪烁,需要用到的寄存器相对较少。
在这里插入图片描述
下面来通过GPIO让LED闪烁。

二、电路设计

驱动强度:~5 mA——40mA,不同的引脚驱动能力不一样。
ESP32C3引脚的驱动能力并不强,所以不通过GPIO输出电流来驱动LED灯。LED灯正极接3.3V,负极串联一个限流电阻再接到指定的GPIO引脚上,如图:
在这里插入图片描述
在这里插入图片描述
实际接线是采用了面包板,如图
在这里插入图片描述

三、程序编写

使用vscode+ESpressif IDF来开发,打开vscode按“ctrl+shift+p”组合键在输入框ESP-IDF:Show Examples Projects点击,选择peripherals->gpio->generic_gpio来创建一个官方工程
在这里插入图片描述
官方工程结构如下,底部栏的相关参数要配置好,在工程里面是没有ESP32C3有关GPIO驱动的库文件的,但是将光标放置在“gpio.h”右键选择“转到定义”则可以打开库文件。
在这里插入图片描述
修改官方的例程代码,这里只需要一个GPIO4来控制LED灯,所以只需配置GPIO4的参数;让LED灯1秒钟闪烁一次。
代码结构是:
定义相关的变量;
初始化LED对应的GPIO;
编写main函数;
编写led任务函数。
ESP32C3的工程是支持freertos系统的,可为led的控制建立一个任务。

代码如下(示例):

#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 GPIO4_OUTPUT_IO    4
#define GPIO_OUTPUT_PIN_SEL  (1ULL<<GPIO4_OUTPUT_IO)

void app_led_task(void *pvParameters);

void led_int(void)
{
    //zero-initialize the config structure.
    gpio_config_t io_conf = {};
    //disable interrupt
    io_conf.intr_type = GPIO_INTR_DISABLE;
    //set as output mode
    io_conf.mode = GPIO_MODE_OUTPUT;
    //bit mask of the pins that you want to set,e.g.GPIO4
    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_config(&io_conf);
}

void app_main(void)
{

    led_int();
    
    printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());

    xTaskCreate(app_led_task, "app_led_task", 1024*2, NULL, 6, NULL);
}

void app_led_task(void *pvParameters)
{
    int cnt = 0;
    while(1) {
        printf("cnt: %d\n", cnt++);
        vTaskDelay(1000 / portTICK_RATE_MS);
        gpio_set_level(GPIO4_OUTPUT_IO, cnt % 2);
    }
}

以上代码我们可以看到,在ESP32C3中main函数不需要调用vTaskStartScheduler()来启动任务调度,因为它自动启动了任务调度器。
运行效果如下:
在这里插入图片描述

四、总结

通过查看官方数据手册了解GPIO的特性,能用esp32点亮还是挺好玩的。对数据手册、esp32工程结构和freertos还需要更深入的了解,才能应用的得心应手。路漫漫其修远兮,一步一个脚印,了解其本质。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐