diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 424a5c3..cf1970a 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -2,7 +2,7 @@ "configurations": [ { "name": "ESP-IDF", - "compilerPath": "/home/beihong/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20251107/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc", + "compilerPath": "/home/beihong/.espressif/tools/riscv32-esp-elf/esp-14.2.0_20251107/riscv32-esp-elf/bin/riscv32-esp-elf-gcc", "compileCommands": "${config:idf.buildPath}/compile_commands.json", "includePath": [ "${workspaceFolder}/**" diff --git a/.vscode/settings.json b/.vscode/settings.json index 6b69752..20973d6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,5 +13,6 @@ "--background-index", "--query-driver=**", "--compile-commands-dir=/home/beihong/esp_projects/esp32c3-smart-scale/build" - ] + ], + "idf.flashType": "UART" } diff --git a/components/ws2812/CMakeLists.txt b/components/ws2812/CMakeLists.txt new file mode 100644 index 0000000..96cf1f0 --- /dev/null +++ b/components/ws2812/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "ws2812.c" + INCLUDE_DIRS "include" + REQUIRES led_strip driver) diff --git a/components/ws2812/include/ws2812.h b/components/ws2812/include/ws2812.h new file mode 100644 index 0000000..6f9b646 --- /dev/null +++ b/components/ws2812/include/ws2812.h @@ -0,0 +1 @@ +void ws2812_start_task(void); diff --git a/components/ws2812/ws2812.c b/components/ws2812/ws2812.c new file mode 100644 index 0000000..caa1a41 --- /dev/null +++ b/components/ws2812/ws2812.c @@ -0,0 +1,109 @@ +#include +#include +#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"); + } +} \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock new file mode 100644 index 0000000..ec7e58e --- /dev/null +++ b/dependencies.lock @@ -0,0 +1,21 @@ +dependencies: + espressif/led_strip: + component_hash: 28621486f77229aaf81c71f5e15d6fbf36c2949cf11094e07090593e659e7639 + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 3.0.3 + idf: + source: + type: idf + version: 5.5.2 +direct_dependencies: +- espressif/led_strip +- idf +manifest_hash: f9f27a7bfd490a8f252ea50084db6f87c986509746a1f4fe61b5ce5bb0e44fcb +target: esp32c3 +version: 2.0.0 diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index cf2c455..d0067f9 100755 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,2 +1,3 @@ idf_component_register(SRCS "main.c" - INCLUDE_DIRS ".") + INCLUDE_DIRS "." + REQUIRES ws2812) diff --git a/main/idf_component.yml b/main/idf_component.yml new file mode 100644 index 0000000..88e3292 --- /dev/null +++ b/main/idf_component.yml @@ -0,0 +1,17 @@ +## IDF Component Manager Manifest File +dependencies: + ## Required IDF version + idf: + version: '>=4.1.0' + # # Put list of dependencies here + # # For components maintained by Espressif: + # component: "~1.0.0" + # # For 3rd party components: + # username/component: ">=1.0.0,<2.0.0" + # username2/component2: + # version: "~1.0.0" + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect dependencies of the `main` component. + # # All dependencies of `main` are public by default. + # public: true + espressif/led_strip: ^3.0.3 diff --git a/main/main.c b/main/main.c index 7b66f33..a389533 100755 --- a/main/main.c +++ b/main/main.c @@ -1,6 +1,10 @@ -#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "ws2812.h" void app_main(void) { - + ws2812_start_task(); + vTaskDelete(NULL); }