特性:新增 WS2812 组件并迁移至 ESP32-C3

更新编译器路径:切换至 RISC-V 工具链,以支持 ESP32-C3 芯片。
新增 WS2812 组件:集成了基于 RMT(远程控制器)外设的驱动程序,用于控制 RGB LED。
配置烧录方式:将 IDF 的 Flash 烧录类型配置为 UART 模式。
This commit is contained in:
Wang Beihong
2026-04-05 20:42:45 +08:00
parent 400bf83204
commit f6a1d3af7e
9 changed files with 162 additions and 5 deletions

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "ws2812.c"
INCLUDE_DIRS "include"
REQUIRES led_strip driver)

View File

@@ -0,0 +1 @@
void ws2812_start_task(void);

109
components/ws2812/ws2812.c Normal file
View File

@@ -0,0 +1,109 @@
#include <stdio.h>
#include <stdbool.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "led_strip.h"
#include "esp_log.h"
#include "esp_err.h"
static const char *TAG = "led_strip";
// --- 针对 ESP32-C3 和单颗 LED 的配置 ---
// 设置为 0 使用非 DMA 模式。
// 虽然 C3 支持 DMA但单颗 LED 数据量极小,非 DMA 模式足够且更节省资源。
#define LED_STRIP_USE_DMA 0
// 只有 1 个灯
#define LED_STRIP_LED_COUNT 1
// GPIO 0
#define LED_STRIP_GPIO_PIN 0
// 10MHz 分辨率 (1 tick = 0.1us)
#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000)
// 内存块大小:单颗 LED 需要的数据非常少,设为 0 让驱动自动分配最合适的内存
#define LED_STRIP_MEMORY_BLOCK_WORDS 0
led_strip_handle_t configure_led(void)
{
// 1. LED 灯带通用配置
led_strip_config_t strip_config = {
.strip_gpio_num = LED_STRIP_GPIO_PIN, // GPIO 0
.max_leds = LED_STRIP_LED_COUNT, // 1 颗 LED
.led_model = LED_MODEL_WS2812, // WS2812 型号
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB, // GRB 顺序
.flags = {
.invert_out = false, // 不反转信号
}
};
// 2. RMT 后端配置
led_strip_rmt_config_t rmt_config = {
.clk_src = RMT_CLK_SRC_DEFAULT, // 默认时钟源
.resolution_hz = LED_STRIP_RMT_RES_HZ, // 10MHz 分辨率
.mem_block_symbols = LED_STRIP_MEMORY_BLOCK_WORDS, // 自动分配
.flags = {
.with_dma = LED_STRIP_USE_DMA, // 不使用 DMA
}
};
// 3. 创建 LED 灯带对象
led_strip_handle_t led_strip;
// 初始化 RMT 设备
esp_err_t ret = led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to create LED strip object: %s", esp_err_to_name(ret));
while (1); // 初始化失败则卡死
}
ESP_LOGI(TAG, "Created LED strip object with RMT backend on GPIO %d", LED_STRIP_GPIO_PIN);
return led_strip;
}
static void ws2812_blink_task(void *pvParameters)
{
(void)pvParameters;
// 初始化 LED 灯带
led_strip_handle_t led_strip = configure_led();
uint8_t r = 0, g = 0, b = 0;
int color_state = 0; // 0:红, 1:绿, 2:蓝
ESP_LOGI(TAG, "Start RGB cycling");
while (1) {
// 根据状态设置颜色
if (color_state == 0) {
r = 50; g = 0; b = 0; // 红色
ESP_LOGI(TAG, "Color: RED");
} else if (color_state == 1) {
r = 0; g = 50; b = 0; // 绿色
ESP_LOGI(TAG, "Color: GREEN");
} else {
r = 0; g = 0; b = 50; // 蓝色
ESP_LOGI(TAG, "Color: BLUE");
}
// 设置像素 (索引0, R, G, B)
ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, 0, r, g, b));
// 刷新显示
ESP_ERROR_CHECK(led_strip_refresh(led_strip));
// 更新状态0->1->2->0...
color_state = (color_state + 1) % 3;
// 延时 500ms
vTaskDelay(pdMS_TO_TICKS(1600));
}
}
void ws2812_start_task(void)
{
BaseType_t ret = xTaskCreate(ws2812_blink_task, "ws2812_blink_task", 4096, NULL, 5, NULL);
if (ret != pdPASS) {
ESP_LOGE(TAG, "Failed to create ws2812 blink task");
}
}