1、解决了低功耗时屏幕残影(在关闭背光前,先将LCD GRAM清空为黑色);

2、手电筒切换到Home界面瞬间闪烁问题;
This commit is contained in:
Rdzleo 2026-02-12 10:08:40 +08:00
parent ae55ecce5f
commit c36c2bfa08
7 changed files with 115 additions and 20 deletions

View File

@ -5,4 +5,5 @@
void lcd_init();
void lvgl_lcd_init();
void touch_init();
void get_touch(uint16_t* touchx,uint16_t* touchy);
void get_touch(uint16_t* touchx,uint16_t* touchy);
void lcd_clear_screen_black(void); // 清空LCD GRAM为黑色

View File

@ -157,4 +157,29 @@ void get_touch(uint16_t* touchx,uint16_t* touchy){
*touchx = touch_handle->data.coords[0].x;
*touchy = touch_handle->data.coords[0].y;
printf("%x\n",max);
}
// 清空LCD GRAM为黑色用于低功耗熄屏前避免残影
void lcd_clear_screen_black(void) {
if (panel_handle == NULL) {
ESP_LOGE(LCD_TAG, "Panel handle is NULL, cannot clear screen");
return;
}
size_t clear_buffer_size = LCD_WID * 40; // 每次清除40行
uint16_t *clear_buffer = heap_caps_malloc(clear_buffer_size * sizeof(uint16_t), MALLOC_CAP_DMA);
if (clear_buffer) {
memset(clear_buffer, 0, clear_buffer_size * sizeof(uint16_t)); // 填充黑色(0x0000)
// 分批填充整个屏幕
for (int y = 0; y < LCD_HIGH; y += 40) {
int lines = (y + 40 > LCD_HIGH) ? (LCD_HIGH - y) : 40;
esp_lcd_panel_draw_bitmap(panel_handle, 0, y, LCD_WID, y + lines, clear_buffer);
}
heap_caps_free(clear_buffer);
ESP_LOGI(LCD_TAG, "LCD GRAM cleared to black (for low power mode)");
} else {
ESP_LOGE(LCD_TAG, "Failed to allocate clear buffer");
}
}

View File

@ -85,14 +85,31 @@ void boot_btn_handler(int gpio_num, void *usr_data) {
// 先通知活动
sleep_mgr_notify_activity();
// 退出手电筒
if (flashlight_is_active()) {
flashlight_exit();
// 退出手电筒会降亮度到0但不恢复亮度
bool was_flashlight_active = flashlight_is_active();
uint8_t flashlight_saved_brightness = 0;
if (was_flashlight_active) {
flashlight_saved_brightness = flashlight_get_saved_brightness();
flashlight_exit(); // 降亮度到0删除overlay
ESP_LOGI("BTN_HANDLER", "手电筒已退出亮度降为0");
// 延迟80ms确保overlay完全删除至少15个刷新周期
vTaskDelay(pdMS_TO_TICKS(80));
}
// 切换到ScreenHome界面
_ui_screen_change(&ui_ScreenHome, LV_SCR_LOAD_ANIM_NONE, 0, 0, &ui_ScreenHome_screen_init);
ESP_LOGI("BTN_HANDLER", "已切换到ScreenHome界面");
// 如果刚从手电筒退出,延迟恢复亮度(等待界面渲染完成)
if (was_flashlight_active) {
// 延迟150ms等待Home界面完全渲染
// 不使用强制刷新让LVGL自动处理避免多层同时重绘
vTaskDelay(pdMS_TO_TICKS(150));
pwm_set_brightness(flashlight_saved_brightness);
ESP_LOGI("BTN_HANDLER", "亮度已恢复到%d%%", flashlight_saved_brightness);
}
}
}

View File

@ -8,6 +8,7 @@
#include "freertos/task.h"
#include "lvgl.h"
#include "../ui/screens/ui_ScreenSet.h"
#include "../lcd/include/lcd.h"
#include <stdio.h>
static const char *TAG = "SLEEP";
@ -45,9 +46,16 @@ void sleep_mgr_notify_activity(void)
ESP_LOGI(TAG, "LVGL 刷新定时器已恢复");
}
// 3. 强制刷新当前屏幕因为GRAM被清空为黑色需要重绘
lv_obj_invalidate(lv_scr_act());
ESP_LOGI(TAG, "已标记屏幕需要重绘");
lvgl_port_unlock();
}
// 延迟50ms等待LVGL完成至少一次重绘避免看到黑屏
vTaskDelay(pdMS_TO_TICKS(50));
// 恢复背光
pwm_set_brightness(saved_brightness);
ESP_LOGI(TAG, "屏幕唤醒,恢复亮度%d%%", saved_brightness);
@ -91,11 +99,14 @@ static void screen_turn_off(void)
lvgl_port_unlock();
}
// 清空LCD GRAM为黑色避免关闭背光后看到残影
lcd_clear_screen_black();
// 关闭背光
screen_off = true;
pwm_set_brightness(0);
ESP_LOGI(TAG, "屏幕已关闭(亮度=%d%%系统进入真正低功耗模式Light Sleep + LVGL暂停", saved_brightness);
ESP_LOGI(TAG, "屏幕已关闭(亮度=%d%%系统进入真正低功耗模式Light Sleep + LVGL暂停 + LCD GRAM清空", saved_brightness);
}
// 休眠管理任务

View File

@ -8,6 +8,8 @@
#include "../../pages/include/pages.h"
#include "../../sleep_mgr/include/sleep_mgr.h"
#include "esp_lvgl_port.h" // LVGL锁机制
#include "freertos/FreeRTOS.h"
#include "freertos/task.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;
@ -159,21 +161,37 @@ static void flashlight_overlay_event_cb(lv_event_t *e) {
}
// 退出手电筒模式(外部调用)
// 注意:此函数不会恢复亮度,需要调用者在界面切换完成后手动恢复亮度
void flashlight_exit(void) {
// 停止闪烁定时器
if (flashlight_timer) {
lv_timer_del(flashlight_timer);
flashlight_timer = NULL;
// 优化退出时序,避免闪烁:
// 1. 先将亮度降到0黑屏
pwm_set_brightness(0);
// 2. 在LVGL锁保护下删除所有对象和定时器
if (lvgl_port_lock(100)) {
// 停止闪烁定时器
if (flashlight_timer) {
lv_timer_del(flashlight_timer);
flashlight_timer = NULL;
}
// 停止淡入淡出定时器
if (fade_timer) {
lv_timer_del(fade_timer);
fade_timer = NULL;
}
// 删除遮罩层此时屏幕已黑看不到overlay删除的过程
if (flashlight_overlay) {
lv_obj_del(flashlight_overlay);
flashlight_overlay = NULL;
}
lvgl_port_unlock();
}
// 恢复之前的亮度
pwm_set_brightness(saved_brightness);
// 删除遮罩层
if (flashlight_overlay) {
lv_obj_del(flashlight_overlay);
flashlight_overlay = NULL;
}
// 注意不在这里恢复亮度避免看到ScreenSet和Home界面混合显示
// 亮度恢复由调用者boot_btn_handler在界面切换完成后执行
}
// 查询手电筒是否激活
@ -181,6 +199,11 @@ bool flashlight_is_active(void) {
return (flashlight_overlay != NULL);
}
// 获取手电筒模式前保存的亮度值
uint8_t flashlight_get_saved_brightness(void) {
return saved_brightness;
}
// 显示手电筒模式
static void show_flashlight(void) {
// 如果已经显示,则不重复创建

View File

@ -32,8 +32,9 @@ extern lv_obj_t *ui_LabelPowerLevel;
// CUSTOM VARIABLES
// 手电筒功能
extern void flashlight_exit(void); // 退出手电筒模式
extern void flashlight_exit(void); // 退出手电筒模式(不恢复亮度)
extern bool flashlight_is_active(void); // 查询手电筒是否激活
extern uint8_t flashlight_get_saved_brightness(void); // 获取手电筒模式前保存的亮度值
#ifdef __cplusplus
} /*extern "C"*/

View File

@ -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
#
@ -1083,6 +1089,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
#
@ -1403,8 +1415,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
#
@ -2084,6 +2099,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
@ -3067,6 +3083,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