Files
esp32c3-smart-scale/components/ws2812/ws2812.c
Wang Beihong f6a1d3af7e 特性:新增 WS2812 组件并迁移至 ESP32-C3
更新编译器路径:切换至 RISC-V 工具链,以支持 ESP32-C3 芯片。
新增 WS2812 组件:集成了基于 RMT(远程控制器)外设的驱动程序,用于控制 RGB LED。
配置烧录方式:将 IDF 的 Flash 烧录类型配置为 UART 模式。
2026-04-05 20:42:45 +08:00

109 lines
3.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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");
}
}