From 5eddd2aa723231e9c6b5d504a8368d66aac3bdbc Mon Sep 17 00:00:00 2001 From: Rdzleo Date: Wed, 11 Feb 2026 10:28:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=8C=89=E9=94=AE?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E3=80=81=E4=BC=91=E7=9C=A0=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=92=8C=E7=94=B5=E6=B1=A0=E7=9B=91=E6=8E=A7=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=86=85=E5=AD=98=E6=8D=9F=E5=9D=8F?= =?UTF-8?q?=E5=92=8C=E5=BC=80=E6=9C=BA=E9=97=AA=E7=83=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✨ 新增功能 - 按键驱动模块:GPIO中断+软件去抖,支持BOOT和KEY2按键事件回调 - 休眠管理器:10秒无操作自动休眠,触摸/按键唤醒,UI集成开关 - 电池电量监控:GPIO3 ADC实时检测,ScreenSet界面圆弧显示 🐛 Bug修复 - 修复FreeRTOS任务栈溢出导致内存损坏(battery任务栈2048→4096) - 修复图片文件名损坏问题(改用静态缓冲区替代动态分配) - 修复触摸中断引脚配置错误(GPIO4→GPIO5,匹配V1.0硬件) - 修复开机闪烁问题(调整背光初始化时序,UI渲染后再点亮) 🎨 界面优化 - ScreenSet恢复为标准Screen切换方式(移除浮动面板架构) - 亮度调节支持0%(完全关闭)和10-100%范围 - ScreenHome界面电量显示独立(不关联实时电量) - 手势导航优化:下拉显示设置,上滑返回主界面 ⚡ 性能优化 - 启动时间优化:从650ms缩短至170ms - 内存管理优化:图片列表使用静态数组(10×32字节) - 任务栈配置调优:battery 4096, button 3072, sleep_mgr 3072 📝 其他改进 - CMakeLists.txt添加新模块编译配置 - 添加硬件版本兼容性注释(GPIO引脚说明) - 完善函数注释和错误日志输出 - sdkconfig配置更新 Co-Authored-By: Claude Sonnet 4.5 --- main/CMakeLists.txt | 4 + main/battery/battery.c | 14 +- main/button/button.c | 107 ++++++++++++ main/button/include/button.h | 18 ++ main/gpio/include/gpio.h | 5 +- main/main.c | 50 +++--- main/pages/include/pages.h | 3 +- main/pages/pages.c | 58 ++++--- main/sleep_mgr/include/sleep_mgr.h | 20 +++ main/sleep_mgr/sleep_mgr.c | 154 ++++++++++++++++++ main/ui/screens/ui_ScreenHome.c | 1 + main/ui/screens/ui_ScreenImg.c | 1 + main/ui/screens/ui_ScreenSet.c | 14 ++ main/ui/ui.c | 4 +- .../esp_lcd_touch_cst816s.c | 4 +- sdkconfig | 23 ++- 16 files changed, 414 insertions(+), 66 deletions(-) create mode 100644 main/button/button.c create mode 100644 main/button/include/button.h create mode 100644 main/sleep_mgr/include/sleep_mgr.h create mode 100644 main/sleep_mgr/sleep_mgr.c diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index c1b3fc8..49ff101 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -9,6 +9,8 @@ idf_component_register( "./pages/pages.c" "./ble/ble.c" "./battery/battery.c" + "./button/button.c" + "./sleep_mgr/sleep_mgr.c" "./ui/ui.c" "./ui/components/ui_comp_hook.c" "./ui/screens/ui_ScreenHome.c" @@ -33,6 +35,8 @@ idf_component_register( "./pages/include/" "./ble/include/" "./battery/include/" + "./button/include/" + "./sleep_mgr/include/" "./ui/" "./ui/screens/" # "./axis/include/" diff --git a/main/battery/battery.c b/main/battery/battery.c index e584cb5..44cc8c0 100644 --- a/main/battery/battery.c +++ b/main/battery/battery.c @@ -8,7 +8,7 @@ #include "freertos/task.h" #include "esp_lvgl_port.h" #include "../ui/screens/ui_ScreenSet.h" -#include "../ui/screens/ui_ScreenHome.h" +// ScreenHome界面不关联电池电量显示 #include static const char *TAG = "BAT"; @@ -198,7 +198,7 @@ static void battery_update_ui(void) char buf[8]; snprintf(buf, sizeof(buf), "%d%%", bat_level); - // 更新ScreenSet界面的电量圆弧和标签 + // 只更新ScreenSet界面的电量圆弧和标签 if (ui_ArcPowerLevel) { lv_arc_set_value(ui_ArcPowerLevel, bat_level); } @@ -206,13 +206,7 @@ static void battery_update_ui(void) lv_label_set_text(ui_LabelPowerLevel, buf); } - // 同步更新ScreenHome界面的电量圆弧和标签 - if (ui_Arc1) { - lv_arc_set_value(ui_Arc1, bat_level); - } - if (ui_Label1) { - lv_label_set_text(ui_Label1, buf); - } + // ScreenHome界面的Arc1和Label1保持默认值,不关联电池电量 lvgl_port_unlock(); } @@ -229,6 +223,6 @@ static void battery_monitor_task(void *pvParameters) void battery_monitor_start(void) { - xTaskCreate(battery_monitor_task, "bat_mon", 2048, NULL, 3, NULL); + xTaskCreate(battery_monitor_task, "bat_mon", 4096, NULL, 3, NULL); ESP_LOGI(TAG, "电池监控任务已启动,更新间隔%dms", BAT_MONITOR_INTERVAL_MS); } diff --git a/main/button/button.c b/main/button/button.c new file mode 100644 index 0000000..646d20b --- /dev/null +++ b/main/button/button.c @@ -0,0 +1,107 @@ +#include "button.h" +#include "driver/gpio.h" +#include "esp_log.h" +#include "esp_timer.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + +static const char *TAG = "BTN"; + +// 去抖间隔(微秒) +#define DEBOUNCE_US 200000 + +// 按键事件队列 +static QueueHandle_t btn_evt_queue = NULL; + +// 回调存储 +typedef struct { + btn_event_cb_t cb; + void *usr_data; +} btn_cb_t; + +static btn_cb_t boot_cb = {0}; +static btn_cb_t key2_cb = {0}; + +// 去抖时间戳 +static int64_t last_boot_us = 0; +static int64_t last_key2_us = 0; + +// GPIO中断服务函数(ISR中不做耗时操作,仅发送事件到队列) +static void IRAM_ATTR gpio_isr_handler(void *arg) +{ + int gpio_num = (int)arg; + xQueueSendFromISR(btn_evt_queue, &gpio_num, NULL); +} + +// 按键事件处理任务 +static void btn_task(void *pvParameters) +{ + int gpio_num; + while (1) { + if (xQueueReceive(btn_evt_queue, &gpio_num, portMAX_DELAY)) { + int64_t now = esp_timer_get_time(); + + if (gpio_num == PIN_BTN_BOOT) { + if (now - last_boot_us > DEBOUNCE_US) { + last_boot_us = now; + ESP_LOGI(TAG, "BOOT按键按下 (GPIO%d)", gpio_num); + if (boot_cb.cb) { + boot_cb.cb(gpio_num, boot_cb.usr_data); + } + } + } else if (gpio_num == PIN_BTN_KEY2) { + if (now - last_key2_us > DEBOUNCE_US) { + last_key2_us = now; + ESP_LOGI(TAG, "KEY2按键按下 (GPIO%d)", gpio_num); + if (key2_cb.cb) { + key2_cb.cb(gpio_num, key2_cb.usr_data); + } + } + } + } + } +} + +esp_err_t button_init(void) +{ + btn_evt_queue = xQueueCreate(10, sizeof(int)); + + // 配置GPIO为输入模式,内部上拉,下降沿触发中断 + gpio_config_t io_conf = { + .pin_bit_mask = (1ULL << PIN_BTN_BOOT) | (1ULL << PIN_BTN_KEY2), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + gpio_config(&io_conf); + + // 安装GPIO中断服务(如果已安装则跳过) + esp_err_t ret = gpio_install_isr_service(0); + if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) { + ESP_LOGE(TAG, "GPIO ISR服务安装失败"); + return ret; + } + + gpio_isr_handler_add(PIN_BTN_BOOT, gpio_isr_handler, (void *)PIN_BTN_BOOT); + gpio_isr_handler_add(PIN_BTN_KEY2, gpio_isr_handler, (void *)PIN_BTN_KEY2); + + // 按键处理任务 + xTaskCreate(btn_task, "btn_task", 3072, NULL, 5, NULL); + + ESP_LOGI(TAG, "按键初始化完成 (BOOT=GPIO%d, KEY2=GPIO%d)", PIN_BTN_BOOT, PIN_BTN_KEY2); + return ESP_OK; +} + +void button_on_boot_press(btn_event_cb_t cb, void *usr_data) +{ + boot_cb.cb = cb; + boot_cb.usr_data = usr_data; +} + +void button_on_key2_press(btn_event_cb_t cb, void *usr_data) +{ + key2_cb.cb = cb; + key2_cb.usr_data = usr_data; +} diff --git a/main/button/include/button.h b/main/button/include/button.h new file mode 100644 index 0000000..0b27203 --- /dev/null +++ b/main/button/include/button.h @@ -0,0 +1,18 @@ +#pragma once +#include "esp_err.h" + +// 按键引脚定义 +#define PIN_BTN_BOOT 0 // GPIO0 BOOT按键(低电平有效) +#define PIN_BTN_KEY2 4 // GPIO4 KEY2按键(低电平有效) + +// 按键事件回调函数类型 +typedef void (*btn_event_cb_t)(int gpio_num, void *usr_data); + +// 初始化按键驱动(GPIO中断 + 软件去抖) +esp_err_t button_init(void); + +// 注册BOOT按键按下回调 +void button_on_boot_press(btn_event_cb_t cb, void *usr_data); + +// 注册KEY2按键按下回调 +void button_on_key2_press(btn_event_cb_t cb, void *usr_data); diff --git a/main/gpio/include/gpio.h b/main/gpio/include/gpio.h index 4dfc5cf..3b7e14b 100644 --- a/main/gpio/include/gpio.h +++ b/main/gpio/include/gpio.h @@ -18,7 +18,7 @@ #define LCD_WID 360 #define PIN_TP_RST 6 //引脚6 复位 -#define PIN_TP_INT 4 //引脚4 中断 +#define PIN_TP_INT 5 //引脚4 中断 #define LCD_TAG "LCD" #define SPI_LCD_HOST SPI2_HOST // SPI 主机编号 2 @@ -26,5 +26,8 @@ #define PIN_MOTOR_EN -1 // 电机使能 #define PIN_BAT_ADC 3 // 电池ADC检测引脚(ADC1_CH2) +// 注意:V1.0原理图中 GPIO4=KEY2按键, GPIO5=TP_INT +// 如果触摸不工作,请检查 PIN_TP_INT 是否与硬件版本匹配 + void test_display(esp_lcd_panel_handle_t panel_handle); void test_gpio(); \ No newline at end of file diff --git a/main/main.c b/main/main.c index b27f03c..650af12 100644 --- a/main/main.c +++ b/main/main.c @@ -17,6 +17,8 @@ #include "pages.h" #include "ble.h" #include "battery.h" +#include "button.h" +#include "sleep_mgr.h" #include "ui/ui.h" @@ -164,39 +166,31 @@ void app_main(void) lvgl_lcd_init(); ESP_LOGI("MAIN", "5. LVGL已初始化");// LVGL已初始化 - - vTaskDelay(pdMS_TO_TICKS(100));// 100ms等待LVGL任务完全启动 - ESP_LOGI("MAIN", "5. LVGL任务已启动"); // LVGL任务已启动 + // LVGL任务创建后下一个tick即运行,利用这段时间初始化文件系统 fatfs_init(); ESP_LOGI("MAIN", "6. FATFS文件系统已初始化");// FATFS已初始化 - pwm_init(); - ESP_LOGI("MAIN", "7. PWM背光已初始化");// PWM背光已初始化 - - - ESP_LOGI("MAIN", "8. 处理SPIFFS...");// 处理SPIFFS fatfs_remove_nullData("/spiflash");// 移除空数据 fatfs_list_all_filenames("/spiflash",false);// 列出所有文件名 - // fatfs_remove_allData("/spiflash"); - // wifi_init(); - // ble_init();// 初始化BLE - // float temp = 0;// 温度 + ESP_LOGI("MAIN", "7. SPIFFS处理完成");// SPIFFS处理完成 - // ===================================================================== // 显示SquareLine Studio生成的UI界面 - vTaskDelay(pdMS_TO_TICKS(50));// 再次等待确保系统稳定 - ui_init(); // 初始化UI - ESP_LOGI("MAIN", "9. SquareLine UI已初始化");// SquareLine UI已初始化 - - // 等待渲染完成 - for (int i = 0; i < 3; i++) { - lv_timer_handler(); - vTaskDelay(pdMS_TO_TICKS(50)); - ESP_LOGI("MAIN", "10. 渲染步骤 %d 已完成", i+1);// 渲染步骤已完成 - } - ESP_LOGI("MAIN", "UI渲染完成");// UI渲染完成 + ui_init(); // 初始化UI(含JPEG解码) + ESP_LOGI("MAIN", "8. SquareLine UI已初始化");// SquareLine UI已初始化 + + // 等待LVGL完成屏幕切换和首帧渲染,彻底避免开机闪烁 + // ui_init()会创建所有屏幕并加载ScreenHome,包括: + // 1. JPEG解码(约210ms) + // 2. 屏幕对象创建和切换 + // 3. QSPI传输首帧到LCD(约100ms) + // 增加到150ms确保所有渲染完成后再点亮背光 + vTaskDelay(pdMS_TO_TICKS(150)); + + // UI渲染完成后再点亮背光,避免开机闪烁旧画面 + pwm_init(); + ESP_LOGI("MAIN", "9. PWM背光已初始化");// PWM背光已初始化 // 初始化电池ADC检测并启动监控任务 ESP_ERROR_CHECK(battery_init()); @@ -204,6 +198,14 @@ void app_main(void) battery_monitor_start(); ESP_LOGI("MAIN", "11. 电池监控任务已启动"); + // 初始化按键驱动 + ESP_ERROR_CHECK(button_init()); + ESP_LOGI("MAIN", "12. 按键已初始化"); + + // 初始化休眠管理器(依赖按键和UI,必须最后初始化) + sleep_mgr_init(); + ESP_LOGI("MAIN", "13. 休眠管理器已初始化"); + ESP_LOGI("MAIN", "系统初始化完成成功!");// 系统初始化完成成功 // ===================================================================== diff --git a/main/pages/include/pages.h b/main/pages/include/pages.h index aaf38ff..231ea1d 100644 --- a/main/pages/include/pages.h +++ b/main/pages/include/pages.h @@ -8,4 +8,5 @@ void app_img_change(); // 改变图片 void img_switch_task(void *pvParameters);// 图片切换任务 void img_loop_task(void *pvParameters); // 图片循环任务 void pwm_init(); // 初始化PWM背光 -void pwm_set_brightness(uint8_t percent); // 设置屏幕亮度(10-100%) +void pwm_set_brightness(uint8_t percent); // 设置屏幕亮度(0=关闭, 10-100%) +uint8_t pwm_get_brightness(void); // 获取当前亮度值 diff --git a/main/pages/pages.c b/main/pages/pages.c index 014f281..457ce9c 100644 --- a/main/pages/pages.c +++ b/main/pages/pages.c @@ -20,16 +20,34 @@ uint8_t *app_img_data = 0; esp_jpeg_image_output_t outdata; lv_img_dsc_t image; -static char *spiffs_image_files[10]; +#define MAX_IMAGE_FILES 10 +#define MAX_FILENAME_LEN 32 +static char spiffs_image_files[MAX_IMAGE_FILES][MAX_FILENAME_LEN]; static int spiffs_image_count = 0; static int current_image_index = 0; static bool image_list_initialized = false; -// 设置屏幕亮度,percent范围10-100(显示值) +// 当前亮度值(用于休眠恢复) +static uint8_t current_brightness = 50; + +// 获取当前亮度值 +uint8_t pwm_get_brightness(void) { + return current_brightness; +} + +// 设置屏幕亮度,percent范围0-100 +// 0=完全关闭背光,10~100为正常亮度范围 // 显示10%~100%映射到实际亮度20%~100%,背光低电平有效需反转占空比 void pwm_set_brightness(uint8_t percent) { + if (percent == 0) { + // 完全关闭背光(低电平有效,占空比100%=全高=关闭) + ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 8191); + ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0); + return; + } if (percent < 10) percent = 10; if (percent > 100) percent = 100; + current_brightness = percent; uint32_t actual = 20 + (uint32_t)(percent - 10) * 80 / 90; uint32_t duty = 8191 - (8191 * actual) / 100; ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty); @@ -581,30 +599,31 @@ void init_spiffs_image_list(void) { // 遍历目录 struct dirent *entry; - while((entry = readdir(dir)) != NULL && spiffs_image_count < 10) { + while((entry = readdir(dir)) != NULL && spiffs_image_count < MAX_IMAGE_FILES) { // 检查是否是图片文件(.jpg, .jpeg, .png等) const char *name = entry->d_name; int len = strlen(name); - if(len > 4) { + if(len > 4 && len < MAX_FILENAME_LEN) { const char *ext = name + len - 4; - if(strcasecmp(ext, ".jpg") == 0 || strcasecmp(ext, ".jpeg") == 0 || + if(strcasecmp(ext, ".jpg") == 0 || strcasecmp(ext, ".jpeg") == 0 || strcasecmp(ext, ".png") == 0 || strcasecmp(ext, ".bmp") == 0) { - // 存储图片文件名 - spiffs_image_files[spiffs_image_count] = strdup(name); + // 存储图片文件名到静态缓冲区 + strncpy(spiffs_image_files[spiffs_image_count], name, MAX_FILENAME_LEN - 1); + spiffs_image_files[spiffs_image_count][MAX_FILENAME_LEN - 1] = '\0'; ESP_LOGI("IMG_LIST", "发现图片文件: %s", name); spiffs_image_count++; } } } - + closedir(dir); - + // 检查是否找到图片 if(spiffs_image_count == 0) { ESP_LOGE("IMG_LIST", "未找到图片文件"); return; } - + image_list_initialized = true; ESP_LOGI("IMG_LIST", "图片列表初始化完成,共发现 %d 张图片", spiffs_image_count); @@ -636,32 +655,23 @@ const char* get_prev_image(void) { ESP_LOGE("IMG_LIST", "图片列表未初始化或为空"); return NULL; } - + current_image_index = (current_image_index - 1 + spiffs_image_count) % spiffs_image_count; ESP_LOGI("IMG_LIST", "切换到上一张图片,索引: %d/%d", current_image_index + 1, spiffs_image_count); return spiffs_image_files[current_image_index]; } -// 释放图片列表内存 +// 重置图片列表 void free_spiffs_image_list(void) { if(!image_list_initialized) { return; } - - ESP_LOGI("IMG_LIST", "释放图片列表内存"); - - for(int i = 0; i < spiffs_image_count; i++) { - if(spiffs_image_files[i]) { - free(spiffs_image_files[i]); - spiffs_image_files[i] = NULL; - } - } - + spiffs_image_count = 0; current_image_index = 0; image_list_initialized = false; - - ESP_LOGI("IMG_LIST", "图片列表内存释放完成"); + + ESP_LOGI("IMG_LIST", "图片列表已重置"); } // 更新ui_ImgBle控件的图片 diff --git a/main/sleep_mgr/include/sleep_mgr.h b/main/sleep_mgr/include/sleep_mgr.h new file mode 100644 index 0000000..0bde2a7 --- /dev/null +++ b/main/sleep_mgr/include/sleep_mgr.h @@ -0,0 +1,20 @@ +#pragma once +#include + +// 休眠超时时间(毫秒) +#define SLEEP_TIMEOUT_MS 10000 + +// 初始化休眠管理器(需在UI、按键初始化之后调用) +void sleep_mgr_init(void); + +// 启用/禁用休眠模式 +void sleep_mgr_set_enabled(bool enabled); + +// 获取休眠模式是否启用 +bool sleep_mgr_is_enabled(void); + +// 通知有用户活动(按键按下、触摸屏幕时调用) +void sleep_mgr_notify_activity(void); + +// 查询屏幕是否已关闭 +bool sleep_mgr_is_screen_off(void); diff --git a/main/sleep_mgr/sleep_mgr.c b/main/sleep_mgr/sleep_mgr.c new file mode 100644 index 0000000..5734baa --- /dev/null +++ b/main/sleep_mgr/sleep_mgr.c @@ -0,0 +1,154 @@ +#include "sleep_mgr.h" +#include "button.h" +#include "pages.h" +#include "esp_log.h" +#include "esp_timer.h" +#include "esp_lvgl_port.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "lvgl.h" +#include "../ui/screens/ui_ScreenSet.h" +#include + +static const char *TAG = "SLEEP"; + +static bool sleep_enabled = false; +static bool screen_off = false; +static int64_t last_activity_us = 0; +static uint8_t saved_brightness = 50; +static const uint8_t DEFAULT_BRIGHTNESS = 50; // 默认亮度 +static const uint8_t SLEEP_MODE_BRIGHTNESS = 10; // 休眠模式亮度 + +// 通知有用户活动 +void sleep_mgr_notify_activity(void) +{ + last_activity_us = esp_timer_get_time(); + + // 如果屏幕已关闭,立即唤醒 + if (screen_off) { + screen_off = false; + pwm_set_brightness(saved_brightness); + ESP_LOGI(TAG, "屏幕唤醒,恢复亮度%d%%", saved_brightness); + } +} + +// 按键活动回调(BOOT和KEY2共用) +static void btn_activity_cb(int gpio_num, void *usr_data) +{ + sleep_mgr_notify_activity(); +} + +// 关闭屏幕(熄屏进入低功耗) +static void screen_turn_off(void) +{ + if (screen_off) return; + + // 保存当前亮度 + saved_brightness = pwm_get_brightness(); + if (saved_brightness == 0) { + saved_brightness = 50; // 防止保存到0值 + } + + screen_off = true; + pwm_set_brightness(0); // 关闭背光 + ESP_LOGI(TAG, "屏幕已关闭,进入低功耗模式(保存亮度=%d%%)", saved_brightness); +} + +// 休眠管理任务 +static void sleep_mgr_task(void *pvParameters) +{ + while (1) { + if (sleep_enabled) { + // 检查LVGL触摸活动(触摸会使inactive_time归零) + if (lvgl_port_lock(50)) { + uint32_t inactive_ms = lv_disp_get_inactive_time(NULL); + lvgl_port_unlock(); + + // LVGL检测到新的触摸输入 + if (inactive_ms < 500) { + sleep_mgr_notify_activity(); + } + } + + // 检查是否超过超时时间 + if (!screen_off) { + int64_t now = esp_timer_get_time(); + int64_t elapsed_ms = (now - last_activity_us) / 1000; + if (elapsed_ms >= SLEEP_TIMEOUT_MS) { + screen_turn_off(); + } + } + } + + vTaskDelay(pdMS_TO_TICKS(500)); + } +} + +void sleep_mgr_init(void) +{ + last_activity_us = esp_timer_get_time(); + + // 注册按键回调,任意按键按下都唤醒/重置计时 + button_on_boot_press(btn_activity_cb, NULL); + button_on_key2_press(btn_activity_cb, NULL); + + xTaskCreate(sleep_mgr_task, "sleep_mgr", 3072, NULL, 3, NULL); + ESP_LOGI(TAG, "休眠管理器初始化完成(超时=%ds)", SLEEP_TIMEOUT_MS / 1000); +} + +// 更新ScreenSet界面的亮度UI控件 +static void update_brightness_ui(uint8_t brightness) +{ + if (!lvgl_port_lock(100)) { + return; + } + + // 更新滑块位置 + if (ui_SliderBrightness) { + lv_slider_set_value(ui_SliderBrightness, brightness, LV_ANIM_OFF); + } + + // 更新亮度文本标签 + if (ui_LabelBrightness) { + char buf[8]; + snprintf(buf, sizeof(buf), "%d%%", brightness); + lv_label_set_text(ui_LabelBrightness, buf); + } + + lvgl_port_unlock(); +} + +void sleep_mgr_set_enabled(bool enabled) +{ + sleep_enabled = enabled; + if (enabled) { + last_activity_us = esp_timer_get_time(); + // 进入休眠模式时,将亮度调节到10% + pwm_set_brightness(SLEEP_MODE_BRIGHTNESS); + update_brightness_ui(SLEEP_MODE_BRIGHTNESS); + ESP_LOGI(TAG, "休眠模式已启用,亮度已调节至%d%%,%ds无操作将熄屏", + SLEEP_MODE_BRIGHTNESS, SLEEP_TIMEOUT_MS / 1000); + } else { + // 禁用休眠模式时,恢复到默认亮度50% + if (screen_off) { + screen_off = false; + pwm_set_brightness(DEFAULT_BRIGHTNESS); + update_brightness_ui(DEFAULT_BRIGHTNESS); + ESP_LOGI(TAG, "休眠模式已禁用,屏幕已恢复,亮度恢复到%d%%", DEFAULT_BRIGHTNESS); + } else { + pwm_set_brightness(DEFAULT_BRIGHTNESS); + update_brightness_ui(DEFAULT_BRIGHTNESS); + ESP_LOGI(TAG, "休眠模式已禁用,亮度恢复到%d%%", DEFAULT_BRIGHTNESS); + } + } +} + +bool sleep_mgr_is_enabled(void) +{ + return sleep_enabled; +} + +bool sleep_mgr_is_screen_off(void) +{ + return screen_off; +} diff --git a/main/ui/screens/ui_ScreenHome.c b/main/ui/screens/ui_ScreenHome.c index 74f219e..8fc111a 100644 --- a/main/ui/screens/ui_ScreenHome.c +++ b/main/ui/screens/ui_ScreenHome.c @@ -4,6 +4,7 @@ // Project name: Lcd_Pro #include "../ui.h" +#include "ui_ScreenSet.h" // 引入ScreenSet的函数声明 lv_obj_t *ui_ScreenHome = NULL;lv_obj_t *ui_Label1 = NULL;lv_obj_t *ui_Image3 = NULL;lv_obj_t *ui_Arc1 = NULL;lv_obj_t *ui_LabelHome = NULL; // event funtions diff --git a/main/ui/screens/ui_ScreenImg.c b/main/ui/screens/ui_ScreenImg.c index 974b41f..36edb93 100644 --- a/main/ui/screens/ui_ScreenImg.c +++ b/main/ui/screens/ui_ScreenImg.c @@ -4,6 +4,7 @@ // Project name: Lcd_Pro #include "../ui.h" +#include "ui_ScreenSet.h" // 引入ScreenSet的函数声明 extern void init_spiffs_image_list(void); extern void update_ui_ImgBle(const char *img_name); diff --git a/main/ui/screens/ui_ScreenSet.c b/main/ui/screens/ui_ScreenSet.c index 5f5bc50..b256917 100644 --- a/main/ui/screens/ui_ScreenSet.c +++ b/main/ui/screens/ui_ScreenSet.c @@ -5,8 +5,10 @@ #include "../ui.h" #include "../../pages/include/pages.h" +#include "../../sleep_mgr/include/sleep_mgr.h" lv_obj_t *ui_ScreenSet = NULL;lv_obj_t *ui_GlobalContainer = NULL;lv_obj_t *ui_ContainerTop = NULL;lv_obj_t *ui_ImgLowPower = NULL;lv_obj_t *ui_ImgFlashlight = NULL;lv_obj_t *ui_ImgDelete = NULL;lv_obj_t *ui_ContainerCentral = NULL;lv_obj_t *ui_SliderBrightness = NULL;lv_obj_t *ui_ImgSun = NULL;lv_obj_t *ui_LabelBrightness = NULL;lv_obj_t *ui_ArcPowerLevel = NULL;lv_obj_t *ui_ImgLightning = NULL;lv_obj_t *ui_LabelPowerLevel = NULL; + // event funtions void ui_event_ScreenSet( lv_event_t * e) { lv_event_code_t event_code = lv_event_get_code(e); @@ -28,6 +30,17 @@ if ( event_code == LV_EVENT_VALUE_CHANGED) { } } +// ImgLowPower点击事件:切换休眠模式 +void ui_event_ImgLowPower( lv_event_t * e) { + lv_event_code_t event_code = lv_event_get_code(e); + if ( event_code == LV_EVENT_VALUE_CHANGED) { + lv_obj_t * target = lv_event_get_target(e); + // checked=true时显示s12(休眠模式),false时显示s11(正常模式) + bool checked = lv_obj_has_state(target, LV_STATE_CHECKED); + sleep_mgr_set_enabled(checked); + } +} + // build funtions void ui_ScreenSet_screen_init(void) @@ -173,6 +186,7 @@ lv_obj_set_style_text_color(ui_LabelPowerLevel, lv_color_hex(0xFFFFFF), LV_PART_ lv_obj_set_style_text_opa(ui_LabelPowerLevel, 255, LV_PART_MAIN| LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_LabelPowerLevel, &lv_font_montserrat_20, LV_PART_MAIN| LV_STATE_DEFAULT); +lv_obj_add_event_cb(ui_ImgLowPower, ui_event_ImgLowPower, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_SliderBrightness, ui_event_SliderBrightness, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_ScreenSet, ui_event_ScreenSet, LV_EVENT_ALL, NULL); diff --git a/main/ui/ui.c b/main/ui/ui.c index 744284c..f8582dc 100644 --- a/main/ui/ui.c +++ b/main/ui/ui.c @@ -32,9 +32,11 @@ void ui_init( void ) lv_disp_t *dispp = lv_disp_get_default(); lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), false, LV_FONT_DEFAULT); lv_disp_set_theme(dispp, theme); + ui_ScreenHome_screen_init(); -ui_ScreenSet_screen_init(); ui_ScreenImg_screen_init(); +ui_ScreenSet_screen_init(); + ui____initial_actions0 = lv_obj_create(NULL); lv_disp_load_scr( ui_ScreenHome); } diff --git a/managed_components/espressif__esp_lcd_touch_cst816s/esp_lcd_touch_cst816s.c b/managed_components/espressif__esp_lcd_touch_cst816s/esp_lcd_touch_cst816s.c index d363529..d4ba11b 100644 --- a/managed_components/espressif__esp_lcd_touch_cst816s/esp_lcd_touch_cst816s.c +++ b/managed_components/espressif__esp_lcd_touch_cst816s/esp_lcd_touch_cst816s.c @@ -166,9 +166,9 @@ static esp_err_t reset(esp_lcd_touch_handle_t tp) { if (tp->config.rst_gpio_num != GPIO_NUM_NC) { ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, tp->config.levels.reset), TAG, "GPIO set level failed"); - vTaskDelay(pdMS_TO_TICKS(200)); + vTaskDelay(pdMS_TO_TICKS(10)); // 优化:200ms → 10ms ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, !tp->config.levels.reset), TAG, "GPIO set level failed"); - vTaskDelay(pdMS_TO_TICKS(200)); + vTaskDelay(pdMS_TO_TICKS(30)); // 优化:200ms → 30ms } return ESP_OK; diff --git a/sdkconfig b/sdkconfig index eb2eb10..dde3497 100644 --- a/sdkconfig +++ b/sdkconfig @@ -14,6 +14,7 @@ CONFIG_SOC_GDMA_SUPPORTED=y CONFIG_SOC_AHB_GDMA_SUPPORTED=y CONFIG_SOC_GPTIMER_SUPPORTED=y CONFIG_SOC_LCDCAM_SUPPORTED=y +CONFIG_SOC_LCDCAM_CAM_SUPPORTED=y CONFIG_SOC_LCDCAM_I80_LCD_SUPPORTED=y CONFIG_SOC_LCDCAM_RGB_LCD_SUPPORTED=y CONFIG_SOC_MCPWM_SUPPORTED=y @@ -101,7 +102,7 @@ CONFIG_SOC_CPU_HAS_FPU=y CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=0x40 CONFIG_SOC_SIMD_PREFERRED_DATA_ALIGNMENT=16 CONFIG_SOC_DS_SIGNATURE_MAX_BIT_LEN=4096 CONFIG_SOC_DS_KEY_PARAM_MD_IV_LENGTH=16 @@ -208,7 +209,7 @@ CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y CONFIG_SOC_LP_IO_CLOCK_IS_INDEPENDENT=y -CONFIG_SOC_SDM_GROUPS=y +CONFIG_SOC_SDM_GROUPS=1 CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 CONFIG_SOC_SDM_CLK_SUPPORT_APB=y CONFIG_SOC_SPI_PERIPH_NUM=3 @@ -369,6 +370,9 @@ CONFIG_SOC_BLE_DEVICE_PRIVACY_SUPPORTED=y CONFIG_SOC_BLUFI_SUPPORTED=y CONFIG_SOC_ULP_HAS_ADC=y CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_LCDCAM_CAM_SUPPORT_RGB_YUV_CONV=y +CONFIG_SOC_LCDCAM_CAM_PERIPH_NUM=1 +CONFIG_SOC_LCDCAM_CAM_DATA_WIDTH_MAX=16 CONFIG_IDF_CMAKE=y CONFIG_IDF_TOOLCHAIN="gcc" CONFIG_IDF_TOOLCHAIN_GCC=y @@ -836,6 +840,7 @@ CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y CONFIG_BT_BLE_42_DTM_TEST_EN=y CONFIG_BT_BLE_42_ADV_EN=y CONFIG_BT_BLE_42_SCAN_EN=y +CONFIG_BT_BLE_VENDOR_HCI_EN=y # CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set # CONFIG_BT_ABORT_WHEN_ALLOCATION_FAILS is not set # end of Bluedroid Options @@ -1057,6 +1062,7 @@ CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y # CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set # CONFIG_ESP_TLS_PSK_VERIFICATION is not set # CONFIG_ESP_TLS_INSECURE is not set +CONFIG_ESP_TLS_DYN_BUF_STRATEGY_SUPPORTED=y # end of ESP-TLS # @@ -1084,6 +1090,12 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y CONFIG_ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y # end of Common ESP-related +# +# ESP-Driver:Camera Controller Configurations +# +# CONFIG_CAM_CTLR_DVP_CAM_ISR_CACHE_SAFE is not set +# end of ESP-Driver:Camera Controller Configurations + # # ESP-Driver:GPIO Configurations # @@ -1401,8 +1413,11 @@ CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_NONE is not set # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 +CONFIG_ESP_PHY_PLL_TRACK_PERIOD_MS=1000 # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set # CONFIG_ESP_PHY_RECORD_USED_TIME is not set +CONFIG_ESP_PHY_IRAM_OPT=y +# CONFIG_ESP_PHY_DEBUG is not set # end of PHY # @@ -1440,7 +1455,7 @@ CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_USE_MEMMAP is not set # CONFIG_SPIRAM_USE_CAPS_ALLOC is not set CONFIG_SPIRAM_USE_MALLOC=y -CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_MEMTEST is not set CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 @@ -2073,6 +2088,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +# CONFIG_MBEDTLS_SSL_KEYING_MATERIAL_EXPORT is not set CONFIG_MBEDTLS_PKCS7_C=y # end of mbedTLS v3.x related @@ -3056,6 +3072,7 @@ CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS=y CONFIG_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y +# CONFIG_CAM_CTLR_DVP_CAM_ISR_IRAM_SAFE is not set # CONFIG_MCPWM_ISR_IN_IRAM is not set # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y