ESP-IoT-Solution LCD 屏幕撕裂(Screen Tearing)原理与防撕裂方案全解析

发布时间:2026/9/19 2:04:46
ESP-IoT-Solution LCD 屏幕撕裂(Screen Tearing)原理与防撕裂方案全解析 ESP-IoT-Solution LCD 屏幕撕裂Screen Tearing原理与防撕裂方案全解析【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution屏幕撕裂是 LCD 应用尤其是 GUI 全屏/大面积刷新中最常见也最影响视觉体验的问题之一。本文基于 esp-iot-solution 官方文档 LCD 屏幕撕裂详解系统讲解撕裂产生的底层原理并针对不同接口类型RGB / MIPI-DSI / QSPI / SPI / I80给出两种主流防撕裂方案基于多 GRAM 的方法与基于 TE 信号的方法。读完本文你将能理解撕裂的本质成因并学会参考仓库中的 rgb_avoid_tearing、qspi_without_ram 与 lcd_with_te 三个 LVGL 实战示例在自己的项目中选择并落地正确的防撕裂配置。屏幕撕裂的原理现象屏幕撕裂Tearing Effect是 LCD 应用中的常见问题通常在 GUI 发生全屏或较大面积区域变化时出现。其现象是LCD 上同时显示了多帧图像的不同部分人眼可以观察到画面出现明显的断层线严重降低 GUI 的视觉体验。典型场景如运行 LVGL Music 演示时快速滚动的动画区域就会暴露出这种撕裂。原因为了方便分析文档将屏幕的刷新过程简化为两个步骤写入Write主控将渲染得到的色彩数据写入 GRAMGraphics RAM图形缓冲区的过程读取Read屏幕驱动 IC 持续从 GRAM 中读取色彩数据并显示到面板上的过程。图中主控持续向 GRAM 写入新一帧数据同时屏幕持续从 GRAM 中读出当前帧并刷新显示。只要这两个过程在时间上交错、空间上重叠撕裂就随之而来。注意一些 LCD 可以通过命令控制主控写入与屏幕读取的方向例如ST7789的36h命令地址控制。当写入与读取方向不一致时也可能出现撕裂下文仅针对方向一致的情况进行说明。基于上述模型可以分两种情况推导撕裂的成因情况一写入时没有任何同步操作此时写入的初始位置与初始时刻都是未知的。只要写入和读取的速度不相等就会出现撕裂写入比读取慢速度比 1:2在主控写入第二帧图像的过程中读取位置会超过写入位置屏幕只能读取到第二帧的前半部分画面后半部分仍停留在第一帧从而出现撕裂。写入比读取快速度比 2:1在屏幕读取第一帧图像的过程中写入位置会越过读取位置屏幕会读到第二帧的后半部分同样出现撕裂。情况二写入时采取了同步操作即便写入的初始位置与初始时刻和读取保持同步若速度不匹配仍可能撕裂写入速度小于读取的二分之一速度比 1:3写入第二帧的过程中读取位置会超过写入位置屏幕只读到第二帧前半部分出现撕裂。写入速度大于或等于读取的二分之一速度比 1:2写入第二帧的过程中读取位置不会与写入位置重叠屏幕能够读到完整的第二帧图像不会出现撕裂。由此可以总结出出现屏幕撕裂的两个必要原因写入和读取同时操作同一个 GRAM写入和读取的初始状态不同步或者速度不匹配。只要破坏其中任意一个条件即可从根源上消除撕裂。防止屏幕撕裂的方法在理解成因之后可以分别从GRAM与读写的状态和速度两个角度实现防撕裂。由于不同接口类型的 LCD 可能具有不同的 刷新机制 与 GRAM 位置需要根据接口类型选择推荐的防撕裂方法接口类型GRAM 位置防撕裂方法RGB、MIPI-DSIvideo mode、QSPI无内部 GRAM主控基于多 GRAM 的方法SPI、I80、QSPI有内部 GRAMLCD基于 TE 信号的方法基于多 GRAM 的方法该方法适用于GRAM 在主控内如 RGB 面板、MIPI-DSI video mode 面板、无内部 GRAM 的 QSPI 面板的场景要求主控可以自由调整屏幕读取的目标 GRAM。其工作原理是通过增加额外的 GRAM避免写入和读取同时操作同一个 GRAM。以双 GRAM 为例初始时主控准备将第二帧图像写入 GRAM2而屏幕准备读取 GRAM1 中的第一帧图像。主控写入完成后先设置屏幕的下一帧从 GRAM2 读取然后等待屏幕读取完当前帧。屏幕读取完成后开始读取 GRAM2 中的第二帧同时主控开始将第三帧写入 GRAM1。写入与读取始终操作不同的 GRAM撕裂被彻底消除。三 GRAM 优化为了优化显示性能还可以在双 GRAM 基础上再增加一个 GRAM此时主控完成一帧写入后无需等待屏幕读取完一帧而是直接开始写入下一帧进一步消除同步等待的开销。具体实现可参考下文的示例代码。仓库中的参考示例display/lcd/rgb_avoid_tearingRGB 接口 LVGL 的防撕裂示例display/lcd/qspi_without_ram无内部 GRAM 的 QSPI 接口防撕裂示例同类方法也适用于 MIPI-DSI video mode 面板可参考 display/lcd/mipi_dsi_avoid_tearing。源码剖析帧缓冲数量如何自动计算以 rgb_avoid_tearing 主程序 为例示例使用esp_lvgl_adapter组件位于 components/display/tools/esp_lvgl_adapter自动完成防撕裂相关的核心配置// 根据旋转方向自动计算所需的帧缓冲数量 esp_lv_adapter_rotation_t rotation CONFIG_EXAMPLE_LCD_ROTATION; uint8_t num_fbs esp_lv_adapter_get_required_frame_buffer_count( ESP_LV_ADAPTER_TEAR_AVOID_MODE_DEFAULT_RGB, rotation);随后在创建 RGB 面板时把num_fbs填入esp_lcd_rgb_panel_config_tesp_lcd_rgb_panel_config_t rgb_config { .clk_src LCD_CLK_SRC_DEFAULT, .psram_trans_align 64, .data_width EXAMPLE_RGB_DATA_WIDTH, // 16 位数据宽度 .bits_per_pixel EXAMPLE_RGB_BIT_PER_PIXEL, // 16 bpp .de_gpio_num EXAMPLE_LCD_IO_RGB_DE, .pclk_gpio_num EXAMPLE_LCD_IO_RGB_PCLK, .vsync_gpio_num EXAMPLE_LCD_IO_RGB_VSYNC, .hsync_gpio_num EXAMPLE_LCD_IO_RGB_HSYNC, .timings ST7701_480_480_PANEL_60HZ_RGB_TIMING(), .flags.fb_in_psram 1, // 帧缓冲放在 PSRAM .num_fbs num_fbs, // 帧缓冲数量防撕裂关键 .bounce_buffer_size_px EXAMPLE_RGB_BOUNCE_BUFFER_SIZE, };从源码结构看帧缓冲数量并非写死的常量而是由esp_lv_adapter_get_required_frame_buffer_count()依据撕裂规避模式和旋转角度动态计算旋转会改变面板行列读取顺序进而影响防撕裂所需的最小缓冲数。示例默认采用ESP_LV_ADAPTER_TEAR_AVOID_MODE_DEFAULT_RGB推荐默认模式同时借助esp_lv_adapter的自动 VSYNC 同步、LVGL 任务管理与线程安全锁机制完成整个显示链路esp_lv_adapter_init→esp_lv_adapter_register_display→esp_lv_adapter_start。多帧缓冲依赖大容量内存因此该示例在 sdkconfig.defaults 中开启了 PSRAM 相关配置CONFIG_SPIRAMy、CONFIG_SPIRAM_MODE_OCTy、CONFIG_SPIRAM_SPEED_80My并把 LVGL 刷新周期设为 15 msCONFIG_LV_DISP_DEF_REFR_PERIOD15。你在自己的 RGB 项目中使用多 GRAM 方案时务必确保芯片具备足够的 PSRAM/内部 SRAM 容纳 23 个全尺寸帧缓冲面板驱动支持通过命令切换读取起始 GRAM 地址如 ST7701 的 vendor 配置使用esp_lcd_panel_io_additions等组件完成 RGB 面板初始化命令下发。补充说明该示例 README 还提到在 ESP-IDF v5.5 特定提交下使用旋转 防撕裂组合功能时可能需要应用仓库内提供的 PPA freeze 修复补丁components/display/tools/esp_lvgl_adapter/0001-bugfix-lcd-Fixed-PPA-freeze.patch具体操作步骤见 rgb_avoid_tearing README实际部署时请以所用 ESP-IDF 版本为准。基于 TE 信号的方法该方法适用于GRAM 在 LCD 内如 SPI、I80、带内部 GRAM 的 QSPI 面板的场景并要求 LCD 提供对外的TETearing Effect信号引脚。其工作原理是通过 TE 信号控制写入的初始状态使其与读取保持同步同时控制写入速度不小于读取的二分之一从而避免写入与读取在 GRAM 中间位置发生重合。典型流程初始时主控等待 TE 信号屏幕准备进入消影区域Porch。当屏幕开始读取 GRAM 中的第一帧图像时向主控发送 TE 信号主控收到 TE 后立即开始向 GRAM 写入第二帧图像并保证写入与读取速度比值为 2:3。由于写入起点被 TE 信号精确锚定在帧边界消影期且写入速度不低于读取的一半写入位置永远不会与读取位置在 GRAM 中间相遇撕裂由此消除。仓库中的参考示例display/lcd/lcd_with_te适用于 I80Intel 8080 并口接口的 LCD支持 ESP32 / ESP32-S2 / ESP32-S3 目标芯片。源码剖析全帧缓冲与旋转配置lcd_with_te 主程序 的核心逻辑是在 BSP 配置中指定整帧大小的 LVGL 缓冲buffer_size 屏幕宽 × 高使 LVGL 一次性渲染完整帧后配合 TE 同步写入 LCD 内部 GRAMbsp_display_cfg_t cfg { .lvgl_port_cfg ESP_LVGL_PORT_INIT_CONFIG(), #if CONFIG_BSP_LCD_BOARD_I80_170_560 .buffer_size EXAMPLE_LCD_I80_H_RES * EXAMPLE_LCD_I80_V_RES, #else .buffer_size EXAMPLE_LCD_QSPI_H_RES * EXAMPLE_LCD_QSPI_V_RES, #endif #if CONFIG_EXAMPLE_DISPLAY_ROTATION_90 .rotate LV_DISP_ROT_90, #elif CONFIG_EXAMPLE_DISPLAY_ROTATION_270 .rotate LV_DISP_ROT_270, #elif CONFIG_EXAMPLE_DISPLAY_ROTATION_180 .rotate LV_DISP_ROT_180, #elif CONFIG_EXAMPLE_DISPLAY_ROTATION_0 .rotate LV_DISP_ROT_NONE, #endif }; bsp_display_start_with_config(cfg); bsp_display_backlight_on();从代码结构看示例通过CONFIG_BSP_LCD_BOARD_I80_170_560区分 I80 与 QSPI 两种面板并通过CONFIG_EXAMPLE_DISPLAY_ROTATION_*选择 LVGL 旋转方向。I80 面板走并口总线、数据线DATA[0..7]配合PCLK、CS、D/C、RST背光与触摸I2C SCL/SDA接线见 lcd_with_te README。使用 TE 方案的关键注意事项为保证 TE 方案的实效文档明确提示两点正确配置 TE 信号参数部分 LCD 可通过命令控制 TE 信号的开关与触发时机例如ST7789的35hTE 使能与44h设置撕裂扫描线命令。用户必须根据具体 LCD 驱动 IC 数据手册设置参数确保 TE 信号开启并在合适的位置如帧消影区起始处触发否则同步点偏移会导致防撕裂失效。保证写入与读取方向一致如ST7789的36h命令可改变扫描方向若写入方向与读取方向不一致防撕裂方法将失效需要按数据手册配置为方向一致。此外还需满足速度约束TE 信号只解决“初始状态同步”写入速度仍需不小于读取速度的二分之一。若渲染/传输速度过慢即使有 TE 同步写入仍可能被读取追上重新出现撕裂——这也是 TE 方案示例中要求使用整帧缓冲、并在高刷场景关注接口带宽的原因。总结与方案选型屏幕撕裂的本质是“写入与读取同时操作同一 GRAM”且“初始状态不同步或速度不匹配”。esp-iot-solution 据此给出两条清晰的工程化路径GRAM 在主控内RGB / MIPI-DSI video mode / 无内部 GRAM 的 QSPI采用**多 GRAM双缓冲/三缓冲**方案通过切换读取目标 GRAM 从物理上隔离读写参考 rgb_avoid_tearing、qspi_without_ram 与 mipi_dsi_avoid_tearing帧缓冲数量可由esp_lv_adapter_get_required_frame_buffer_count()按旋转角自动计算无需手工试错GRAM 在 LCD 内SPI / I80 / 带内部 GRAM 的 QSPI采用TE 信号同步方案用 TE 引脚锚定写入起点并控制写读速度比 ≥ 1:2参考 lcd_with_te务必按数据手册配置 TE 开关/触发点如 ST778935h、44h并保证读写方向一致如 ST778936h。更多背景概念可进一步阅读 LCD 术语表、LCD 概述 与 LCD 开发指南完整文档目录见 LCD 显示屏。在选定接口类型后按对应示例接线、配置并idf.py -p PORT build flash monitor即可在屏幕上直观对比防撕裂开启前后的显示效果。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考