ESP32-S3开发教程二:LED流水灯(基于VS Code+ESP-IDF)
一、新建工程
这里不再赘述,创建一个名为“LED_blink”的工程文件夹,选择项目路径,芯片型号选择esp32s3:

模板依然选择空白模板:

打开新的工程:

二、初始化多个GPIO口
首先,我们还是添加上driver头文件,分别修改CMakeList.txt和main.c文件:
idf_component_register(SRCS "main.c"
PRIV_REQUIRES driver
INCLUDE_DIRS ".")
#include <stdio.h>
#include "driver/gpio.h"
void app_main(void)
{
}
现在,我们来一次性初始化三个GPIO口,作为三个LED的输出引脚。在ESP32中,多个引脚的初始化是通过按位或运算实现的,把多个引脚对应的二进制位 “合并” 为 1,最终生成一个标记了多个引脚的位掩码。
具体过程如下:
1ULL指无符号长整形数字1,64位,这里以20位做演示:00000 00000 00000 00001
1ULL<<15:右移15位,变为00000 10000 00000 00000
1ULL<<16:右移16位,变为00001 00000 00000 00000
1ULL<<17:右移17位,变为00010 00000 00000 00000
(1ULL<<15)|(1ULL<<16)|(1ULL<<17)将三个数字进行或运算:
00011 10000 00000 00000
这样,就创建了一个包含GPIO15、GPIO16、GPIO17的掩码。
三、编写业务逻辑
现在我们来写流水灯的逻辑:
#include <stdio.h>
#include "driver/gpio.h"
void app_main(void)
{
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL<<15)|(1ULL<<16)|(1ULL<<17),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_conf);
int a = 0;
while (1)
{
if (a > 2)
{
a = 0;
}
if (a == 0)
{
gpio_set_level(15, 1);
gpio_set_level(16, 0);
gpio_set_level(17, 0);
}
else if (a == 1)
{
gpio_set_level(15, 0);
gpio_set_level(16, 1);
gpio_set_level(17, 0);
}
else if (a == 2)
{
gpio_set_level(15, 0);
gpio_set_level(16, 0);
gpio_set_level(17, 1);
}
a++;
}
}
在while主循环内,根据状态变量a的取值,让不同的灯亮起来。最后让a自增1,完成流水灯的业务逻辑。
四、添加延时函数
代码写到这里,我们的任务还未完成。因为我们现在没有加入延时代码,现在的主循环是有多快运行多快的。我们如果不加入延时函数,那么肉眼将无法看到LED闪烁的效果。所以我们需要添加一个延时函数。
由于ESP深度集成了FreeRTOS,所以我们的延时函数也不是简单的Delay,但是使用起来确实一样简单。
首先添加freertos头文件:
idf_component_register(SRCS "main.c"
PRIV_REQUIRES driver freertos
INCLUDE_DIRS ".")
#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
FreeRTOS 是一款免费、开源、轻量级的实时操作系统内核(RTOS),这里我们还是不细讲,会用就可以了。
添加延时:
#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void app_main(void)
{
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL<<15)|(1ULL<<16)|(1ULL<<17),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_conf);
int a = 0;
while (1)
{
if (a > 2)
{
a = 0;
}
if (a == 0)
{
gpio_set_level(15, 1);
gpio_set_level(16, 0);
gpio_set_level(17, 0);
}
else if (a == 1)
{
gpio_set_level(15, 0);
gpio_set_level(16, 1);
gpio_set_level(17, 0);
}
else if (a == 2)
{
gpio_set_level(15, 0);
gpio_set_level(16, 0);
gpio_set_level(17, 1);
}
a++;
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
vTaskDelay()函数的作用是将当前任务暂时挂起,CPU可以执行其他任务。它接受的参数是Tick数,一个Tick与系统节拍频率挂钩,如果系统节拍频率为100Hz,那么1个Tick大致为10毫秒。如果我们要精确到秒,则需要使用pdMS_TO_TICKS()函数,将数字转换为毫秒数,那么1000就对应一秒。
五、编译烧录
按照上节操作进行编译和烧录,成功后可以看到三个LED每隔一秒闪烁:

更多推荐

所有评论(0)