ESP32学习——VSCode点灯实验

发布时间:2024年01月24日

本次实验是使用GOOUUU-ESP32-C3开发板,芯片型号为ESP32-C3-MINI-1,使用下载方式是USB串口,芯片资料:ESP32-C3-MINI-1/ESP32-C3-MINI-1U数据手册,通过VSCode中的espressif-idf插件开发。

一、硬件介绍

1、通过数据手册可以得知芯片的所引脚,且启动管脚为IO2、IO8和IO9。

2、查看开发板原理图可以得知开发板有一个三色LED的引脚为IO3、IO4、IO5,分别控制着红色,绿色和蓝色

二、点亮LED灯实验

1、打开VSCode,快捷键Ctrl+Shift+P打开命令面板,输入show exmaples projects打开示例程序,选择sample_project样本示例,里面是个空项目,并且选择不要出现中文或空格的路径保存,否则程序无法编译,会报错;

步骤1:打开示例项目

步骤2:选择样本示例,保存项目路径

2、通过硬件得知LED为IO3、IO4、IO5控制,本实验只控制蓝色LED,引脚为IO5,打开main.c文件,所有程序就在main.c文件编写了,首先就得引用所需的头文件,定义LED引脚,配置LED,控制LED亮灭;

步骤1:打开main.c文件

步骤2:引用头文件,定义LED引脚

#include "driver/gpio.h"    //GPIO固件库

#define blueLED GPIO_NUM_2    //定义蓝色LED引脚

步骤3:配置LED推挽输出

gpio_reset_pin(blueLED);    //复位LED
gpio_set_direction(blueLED, GPIO_MODE_OUTPUT);    //配置LED输入输出

步骤4::通过硬件电路,得知LED一端连接VCC,另一端连接LED引脚,所以通过控制LED引脚高电平让LED灭,低电平让LED,但程序执行效率很快,肉眼无法直观看到LED亮灭,所以需要延时

a、引用头文件

#include "freertos/FreeRTOS.h"    //FreeRTOS固件库
#include "freertos/task.h"        //延时函数需要用到该头文件

b、在app_main函数中循环

while(true)
{
    gpio_set_level(blueLED, 0);    //LED亮
    vTaskDelay(1000 / portTICK_PERIOD_MS);    //延时1000ms,portTICK_PERIOD_MS为毫米周期
    gpio_set_level(blueLED, 1);    //LED灭
    vTaskDelay(1000 / portTICK_PERIOD_MS);
}

main.c程序

#include <stdio.h>
#include "driver/gpio.h"    //GPIO固件库
#include "freertos/FreeRTOS.h"    //FreeROTS固件库
#include "freertos/task.h"        //延时函数需要用到该头文件

#define blueLED GPIO_NUM_5  //定义蓝色LED引脚
void app_main(void)
{
    gpio_reset_pin(blueLED);    //复位LED
    gpio_set_direction(blueLED, GPIO_MODE_OUTPUT);    //配置LED输入输出

    while (true)
    {
        gpio_set_level(blueLED, 0); //LED亮
        vTaskDelay(1000 / portTICK_PERIOD_MS);   //延时1000ms,portTICK_PERIOD_MS为毫米周期
        gpio_set_level(blueLED, 1); //LED灭
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
    
}

3、连接开发板,在VSCode底部有espressif工具,选择对应的端口号、芯片型号和烧录方式,进行程序编译,最后点击下载,查看实验效果;

实验效果:

二、呼吸灯实验

1、本次实验是利用LED PWM控制器实现的呼吸灯,具体可以查看ESP32-C3技术参考手册,工程创建不用多说了,就是上面的步骤,后面直接编写程序;

步骤1:查看手册可以知道,LED PWM控制可以由4个定时器,由6个通道控制。本地实验选用定时器0,PWM0通道控制,首先配置LED PWM;

a、添加头文件

#include "driver/gpio.h"    //GPIO固件库
#include "freertos/FreeRTOS.h"  //FreeRTOS固件库
#include "freertos/task.h"  //延时函数需要用到该头文件
#include "driver/ledc.h"    //LED PWM固件库

b、创建LED PWM配置函数,将LED PWM配置成5KPWM频率,13位精度,占空比为0

#define blueLED GPIO_NUM_5  //定义蓝色LED引脚
ledc_channel_config_t ledc_channel;    //定义LED PWM通道

void breathingLed_init(void);   //配置LED PWM控制器

void breathingLed_init(void)
{
    ledc_timer_config_t ledc_timer = {
        .duty_resolution =  LEDC_TIMER_13_BIT,  //PWM分辨率
        .freq_hz = 5000,                        //频率
        .speed_mode = 0,                        //速度
        .timer_num = LEDC_TIMER_0,              //选择定时器
    };

    ledc_timer_config(&ledc_timer);        //配置LED为定时器PWM模式


    ledc_channel.channel = LEDC_CHANNEL_0;  //LED PWM通道
    ledc_channel.duty = 0;                  //占空比
    ledc_channel.gpio_num = blueLED;        //IO口映射
    ledc_channel.speed_mode = 0;            //速度
    ledc_channel.timer_sel = LEDC_TIMER_0;  //选择定时器
    ledc_channel_config(&ledc_channel);     //配置LED PWM通道

    ledc_fade_func_install(0);  //开启LEDC渐变功能,参数为是否允许中断
}

步骤2:实现呼吸效果

a、因为配置LED PWM控制器的时候,设置13位分辨率,占空比为0%,所以要让占空比达到100%,占空比值就需要2^13-1 = 8191,通过ledc_set_fade_with_time函数设置,第4个参数是从原来的占空比到达指定占空比时,所需花费的时间;

//LED渐变到100%,需要花费1000ms
ledc_set_fade_with_time(ledc_channel.speed_mode, ledc_channel.channel, 8191, 1000);

b、将LED PWM占空比调到0%也是一样的原理;

//LED渐变到0%,需要花费1000ms
ledc_set_fade_with_time(ledc_channel.speed_mode, ledc_channel.channel, 0, 1000);

c、设置好占空比之后,需要让LED PWM运行起来,就需要用到ledc_fade_start函数;

ledc_fade_start(ledc_channel.speed_mode,ledc_channel.channel, LEDC_FADE_NO_WAIT);

main.c程序

#include <stdio.h>
#include "driver/gpio.h"    //GPIO固件库
#include "freertos/FreeRTOS.h"  //FreeRTOS固件库
#include "freertos/task.h"  //延时函数需要用到该头文件
#include "driver/ledc.h"    //LED PWM固件库

#define blueLED GPIO_NUM_5  //定义蓝色LED引脚
ledc_channel_config_t ledc_channel;    //定义LED PWM通道

void breathingLed_init(void);   //配置LED PWM控制器
void app_main(void)
{
    breathingLed_init();

    while (true)
    {
        //LED渐变到100%,需要花费1000ms
        ledc_set_fade_with_time(ledc_channel.speed_mode,
                                ledc_channel.channel,
                                8191, 
                                1000);
        ledc_fade_start(ledc_channel.speed_mode,ledc_channel.channel, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);  //延时1000ms

        //LED渐变到0%,需要花费1000ms
        ledc_set_fade_with_time(ledc_channel.speed_mode,
                                ledc_channel.channel,
                                0, 
                                1000);
        ledc_fade_start(ledc_channel.speed_mode,ledc_channel.channel, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void breathingLed_init(void)
{
    ledc_timer_config_t ledc_timer = {
        .duty_resolution =  LEDC_TIMER_13_BIT,  //PWM分辨率
        .freq_hz = 5000,                        //频率
        .speed_mode = 0,                        //速度
        .timer_num = LEDC_TIMER_0,              //选择定时器
    };

    ledc_timer_config(&ledc_timer);        //配置LED为定时器PWM模式


    ledc_channel.channel = LEDC_CHANNEL_0;  //LED PWM通道
    ledc_channel.duty = 0;                  //占空比
    ledc_channel.gpio_num = blueLED;        //IO口映射
    ledc_channel.speed_mode = 0;            //速度
    ledc_channel.timer_sel = LEDC_TIMER_0;  //选择定时器
    ledc_channel_config(&ledc_channel);     //配置LED PWM通道

    ledc_fade_func_install(0);  //开启LEDC渐变功能,参数为是否允许中断
}

2、编译后烧录程序查看实验效果

三、彩虹灯实验

思路:RGB灯从呼吸灯实验只用到了一种颜色,所以如果把RGB三种颜色都用上了,不就可以形成多种颜色组合,变成彩虹色了吗?就此展开本次实验。

1、一开始想着很简单,因为LED PWM控制器有4个定时,6个PWM通道,那么每个引脚用一个定时器一个PWM通道控制完成了

main.c代码如下:

#include <stdio.h>
#include "driver/gpio.h"    //GPIO固件库
#include "freertos/FreeRTOS.h"  //FreeRTOS固件库
#include "freertos/task.h"  //延时函数需要用到该头文件
#include "driver/ledc.h"    //LED PWM固件库

#define blueLED GPIO_NUM_5  //定义蓝色LED引脚
#define greenLED GPIO_NUM_4  //定义绿色LED引脚
#define redLED GPIO_NUM_3  //定义红色LED引脚
ledc_channel_config_t ledc_channel0;    //定义LED PWM0通道
ledc_channel_config_t ledc_channel1;    //定义LED PWM1通道
ledc_channel_config_t ledc_channel2;    //定义LED PWM2通道

//配置LEDC PWM控制器
void breathingLed_init(ledc_timer_t timer,  //定时器
                        ledc_channel_config_t channel_config,   //LED PWM控制配置器
                        ledc_channel_t channel, //PWM通道
                        gpio_num_t gpio_num);   //IO映射
void ledc_pwmDir(ledc_channel_config_t channel, bool flag); //LED PWM占空比调节
void app_main(void)
{
    
    breathingLed_init(LEDC_TIMER_0, ledc_channel0, LEDC_CHANNEL_0, blueLED);//配置蓝灯
    breathingLed_init(LEDC_TIMER_1, ledc_channel1, LEDC_CHANNEL_1, greenLED);//配置绿灯
    breathingLed_init(LEDC_TIMER_2, ledc_channel2, LEDC_CHANNEL_2, redLED);//配置红灯

    while (true)
    {
        ledc_pwmDir(ledc_channel0, false);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel0, true);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel1, false);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel1, true);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel2, false);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel2, true);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void breathingLed_init(ledc_timer_t timer, ledc_channel_config_t channel_config, ledc_channel_t channel, gpio_num_t gpio_num)
{
    ledc_timer_config_t ledc_timer = {
        .duty_resolution =  LEDC_TIMER_13_BIT,  //PWM分辨率
        .freq_hz = 5000,                        //频率
        .speed_mode = 0,                        //速度
        .timer_num = timer,              //选择定时器
    };

    ledc_timer_config(&ledc_timer);        //配置LED为定时器PWM模式


    channel_config.channel = channel;  //LED PWM通道
    channel_config.duty = 8191;               //占空比
    channel_config.gpio_num = gpio_num;       //IO口映射
    channel_config.speed_mode = 0;            //速度
    channel_config.timer_sel = timer;   //选择定时器
    ledc_channel_config(&channel_config);     //配置LED PWM通道

    ledc_fade_func_install(0);  //开启LEDC渐变功能,参数为是否允许中断
}

void ledc_pwmDir(ledc_channel_config_t channel, bool flag)
{
    ledc_set_fade_with_time(channel.speed_mode,channel.channel,flag ? 8191 : 0, 1000);
    ledc_fade_start(channel.speed_mode,channel.channel, LEDC_FADE_NO_WAIT);
}

实验效果:只有蓝色灯在渐变

2、经过此次实验,又查到ESP32-C3技术参考手册,修改了几次代码,最后查到了第十章 ESP32开发指南---PWM全彩LED灯显示这篇内容,得知:LED PWM控制只能通过一个定时器控制,不同通道来控制不同的IO输出,但需要注意的事:

a、配置LED PWM控制器智能配置一次,否则会有问题,如下代码不能重复。

ledc_timer_config_t ledc_timer = {
    .duty_resolution =  LEDC_TIMER_13_BIT,  //PWM分辨率
    .freq_hz = 5000,                        //频率
    .speed_mode = 0,                        //速度
    .timer_num = timer,              //选择定时器
};
ledc_timer_config(&ledc_timer);        //配置LED为定时器PWM模式

b、如下函数是对LED PWM控制器进行启动的,所以也只需在配置完LED PWM控制器后执行一次就行。

ledc_fade_func_install(0);  //开启LEDC渐变功能,参数为是否允许中断

main.c代码如下:

#include <stdio.h>
#include "driver/gpio.h"    //GPIO固件库
#include "freertos/FreeRTOS.h"  //FreeRTOS固件库
#include "freertos/task.h"  //延时函数需要用到该头文件
#include "driver/ledc.h"    //LED PWM固件库

#define blueLED GPIO_NUM_5  //定义蓝色LED引脚
#define greenLED GPIO_NUM_4  //定义绿色LED引脚
#define redLED GPIO_NUM_3  //定义红色LED引脚
ledc_channel_config_t ledc_channel0;    //定义LED PWM0通道
ledc_channel_config_t ledc_channel1;    //定义LED PWM1通道
ledc_channel_config_t ledc_channel2;    //定义LED PWM2通道

void breathingLed_init(void);   //配置LED PWM控制器
void ledc_pwmDir(ledc_channel_config_t channel, bool flag); //LED PWM占空比调节
void app_main(void)
{
    
    breathingLed_init();//配置LED PWM控制器

    while (true)
    {
        ledc_pwmDir(ledc_channel0, false);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel0, true);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel1, false);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel1, true);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel2, false);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_pwmDir(ledc_channel2, true);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}


void breathingLed_init(void)
{
    ledc_timer_config_t ledc_timer = {
        .duty_resolution =  LEDC_TIMER_13_BIT,  //PWM分辨率
        .freq_hz = 5000,                        //频率
        .speed_mode = 0,                        //速度
        .timer_num = LEDC_TIMER_0,              //选择定时器
    };

    ledc_timer_config(&ledc_timer);        //配置LED为定时器PWM模式


    ledc_channel0.channel = LEDC_CHANNEL_0;  //LED PWM通道
    ledc_channel0.duty = 8191;               //占空比
    ledc_channel0.gpio_num = blueLED;       //IO口映射
    ledc_channel0.speed_mode = 0;            //速度
    ledc_channel0.timer_sel = LEDC_TIMER_0;   //选择定时器
    ledc_channel_config(&ledc_channel0);     //配置LED PWM通道

    ledc_channel1.channel = LEDC_CHANNEL_1;  //LED PWM通道
    ledc_channel1.duty = 8191;               //占空比
    ledc_channel1.gpio_num = greenLED;       //IO口映射
    ledc_channel1.speed_mode = 0;            //速度
    ledc_channel1.timer_sel = LEDC_TIMER_0;   //选择定时器
    ledc_channel_config(&ledc_channel1);     //配置LED PWM通道

    ledc_channel2.channel = LEDC_CHANNEL_2;  //LED PWM通道
    ledc_channel2.duty = 8191;               //占空比
    ledc_channel2.gpio_num = redLED;       //IO口映射
    ledc_channel2.speed_mode = 0;            //速度
    ledc_channel2.timer_sel = LEDC_TIMER_0;   //选择定时器
    ledc_channel_config(&ledc_channel2);     //配置LED PWM通道

    ledc_fade_func_install(0);  //开启LEDC渐变功能,参数为是否允许中断
}

void ledc_pwmDir(ledc_channel_config_t channel, bool flag)
{
    ledc_set_fade_with_time(channel.speed_mode,channel.channel,flag ? 8191 : 0, 1000);
    ledc_fade_start(channel.speed_mode,channel.channel, LEDC_FADE_NO_WAIT);
}

实验效果:三种颜色渐变,在切换颜色的短暂时间会有颜色融合的效果,形成其他颜色,可以修改while(true)函数里面内容进行自由搭配

改进一下main.c代码:彩虹灯效果更好看

#include <stdio.h>
#include "driver/gpio.h"    //GPIO固件库
#include "freertos/FreeRTOS.h"  //FreeRTOS固件库
#include "freertos/task.h"  //延时函数需要用到该头文件
#include "driver/ledc.h"    //LED PWM固件库

#define blueLED GPIO_NUM_5  //定义蓝色LED引脚
#define greenLED GPIO_NUM_4  //定义绿色LED引脚
#define redLED GPIO_NUM_3  //定义红色LED引脚
ledc_channel_config_t ledc_channel0;    //定义LED PWM0通道
ledc_channel_config_t ledc_channel1;    //定义LED PWM1通道
ledc_channel_config_t ledc_channel2;    //定义LED PWM2通道

void breathingLed_init(void);   //配置LED PWM控制器
void app_main(void)
{
    breathingLed_init();//配置LED PWM控制器
    while (true)
    {
        
        ledc_set_fade_with_time(ledc_channel0.speed_mode, ledc_channel0.channel, 8191, 1000); //蓝色渐变灭
        ledc_set_fade_with_time(ledc_channel1.speed_mode, ledc_channel1.channel, 0, 1000); //绿灯渐变亮
        ledc_fade_start(ledc_channel0.speed_mode, ledc_channel0.channel, LEDC_FADE_NO_WAIT); //开始渐变
        ledc_fade_start(ledc_channel1.speed_mode, ledc_channel1.channel, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_set_fade_with_time(ledc_channel1.speed_mode, ledc_channel1.channel, 8191, 1000);
        ledc_set_fade_with_time(ledc_channel2.speed_mode, ledc_channel2.channel, 0, 1000);
        ledc_fade_start(ledc_channel1.speed_mode, ledc_channel1.channel, LEDC_FADE_NO_WAIT);
        ledc_fade_start(ledc_channel2.speed_mode, ledc_channel2.channel, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ledc_set_fade_with_time(ledc_channel2.speed_mode, ledc_channel2.channel, 8191, 1000);
        ledc_set_fade_with_time(ledc_channel0.speed_mode, ledc_channel0.channel, 0, 1000);
        ledc_fade_start(ledc_channel2.speed_mode,ledc_channel2.channel, LEDC_FADE_NO_WAIT);
        ledc_fade_start(ledc_channel0.speed_mode, ledc_channel0.channel, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}


void breathingLed_init(void)
{
    ledc_timer_config_t ledc_timer = {
        .duty_resolution =  LEDC_TIMER_13_BIT,  //PWM分辨率
        .freq_hz = 5000,                        //频率
        .speed_mode = 0,                        //速度
        .timer_num = LEDC_TIMER_0,              //选择定时器
    };

    ledc_timer_config(&ledc_timer);        //配置LED为定时器PWM模式


    ledc_channel0.channel = LEDC_CHANNEL_0;  //LED PWM通道
    ledc_channel0.duty = 0;               //占空比
    ledc_channel0.gpio_num = blueLED;       //IO口映射
    ledc_channel0.speed_mode = 0;            //速度
    ledc_channel0.timer_sel = LEDC_TIMER_0;   //选择定时器
    ledc_channel_config(&ledc_channel0);     //配置LED PWM通道

    ledc_channel1.channel = LEDC_CHANNEL_1;  //LED PWM通道
    ledc_channel1.duty = 8191;               //占空比
    ledc_channel1.gpio_num = greenLED;       //IO口映射
    ledc_channel1.speed_mode = 0;            //速度
    ledc_channel1.timer_sel = LEDC_TIMER_0;   //选择定时器
    ledc_channel_config(&ledc_channel1);     //配置LED PWM通道

    ledc_channel2.channel = LEDC_CHANNEL_2;  //LED PWM通道
    ledc_channel2.duty = 8191;               //占空比
    ledc_channel2.gpio_num = redLED;       //IO口映射
    ledc_channel2.speed_mode = 0;            //速度
    ledc_channel2.timer_sel = LEDC_TIMER_0;   //选择定时器
    ledc_channel_config(&ledc_channel2);     //配置LED PWM通道

    ledc_fade_func_install(0);  //开启LEDC渐变功能,参数为是否允许中断
}

注意:

1、Micro-USB是数据线,不是电源线,数据线能用作下载线,但电源线仅供电;

2、再次提示项目路径不能存在中文或者空格,否则会报错,编译不成功;

3、编译成功会在终端显示内存大小,

4、编译成功后依然提示有问题,忽略就可以。

5、因为GOOUUU-ESP32-C3开发板有自动下载电路,所以可以直接接USB烧录程序,不用改变启动管脚,如果没有自动下载电路,需要手动设置启动管脚。

6、开发板中的RGB灯是由3个引脚控制的,相当于三个不同颜色的LED灯而已,而WS2812 RGB灯是由1个引脚控制,两者控制方式不同。

文章来源:https://blog.csdn.net/m0_71413375/article/details/135690129
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。