1. 花屏现象的本质:什么是花屏?

说实话,做嵌入式UI这些年,我最怕半夜接到测试电话——「屏幕花了」。花屏这玩意儿,说大不大,说小不小。轻则重启就好,重则直接让你怀疑人生,从硬件到驱动到LVGL配置,挨个排查一遍。

那到底什么是花屏?说白了,就是屏幕显示的内容和预期不一致。你本来想画一个漂亮的蓝色按钮,结果屏幕上出现了一堆彩色条纹;你明明更新了温度数值,结果数字像鬼影一样拖在后面。这些,都算花屏。

我个人习惯把花屏分成两大类:「显存层面的问题」和「时序层面的问题」。前者是数据错了,后者是数据对了但没显示对。搞清楚这个分类,排查方向就清晰多了。

核心定义:花屏 = 显示缓冲区内容与屏幕实际像素之间的映射关系被破坏。

花屏的常见表现形式

我整理了一下,实际项目中遇到的花屏,基本逃不出下面这四种。你对照着看,很快就能定位问题类型。

表现形式 典型现象 常见原因
条纹 水平或垂直的彩色/黑色线条,像栅栏一样 DMA传输错位、行同步参数错误
噪点 随机分布的彩色小点,像雪花屏 显存未初始化、内存越界写入
颜色错乱 红色变成蓝色,绿色变成紫色 颜色格式不匹配(RGB565 vs RGB888)
图像撕裂 画面上下部分显示不同帧的内容,像被撕开 帧缓冲区切换时未同步刷新

条纹——最让人头疼的「栅栏效应」

条纹花屏,我在项目里遇到得最多。有一次调试一个320x240的屏幕,刷出来全是斜向的彩色条纹,像万花筒一样。查了半天,最后发现是行偏移参数(HBP)少配了2个像素。

为什么会这样?你想想看,屏幕是一行一行刷新的。如果每行的起始位置算错了,后面的数据就会整体偏移,形成条纹。LVGL本身不直接控制这些参数,但底层驱动如果配错了,LVGL再漂亮也没用。

我的排查习惯:遇到条纹花屏,先看驱动初始化代码中的时序参数。特别是 HBP(水平后沿)、HFP(水平前沿)、VBP(垂直后沿)这几个值,对照屏幕数据手册逐项核对。

噪点——「显存里有垃圾」

噪点花屏,说白了就是显存里的数据是乱的。我记得有一次,系统启动后屏幕左上角总有一块区域在闪烁彩色噪点。代码逻辑看起来没问题,LVGL的控件也都正常初始化了。

后来用调试器读了一下那块区域的显存,发现里面全是0xCDCDCDCD——这是编译器在Debug模式下给未初始化内存填充的「哨兵值」。问题找到了:我给LVGL分配的缓冲区太大了,超出了实际可用的SRAM范围,溢出的部分读回来全是垃圾数据。

避坑指南:我曾经在STM32F4上吃过这个亏。LVGL的 draw buffer 大小一定要用 sizeof() 确认,不要想当然。特别是用了外部SRAM时,地址映射对不对、内存是否连续,都要验证。

颜色错乱——「RGB顺序搞反了」

颜色错乱这个问题,新手特别容易踩。LVGL默认用的是RGB565颜色格式,但有些屏幕驱动芯片(比如ILI9341)默认是BGR顺序。你传一个红色(0xF800)过去,它当成蓝色显示出来。

我习惯在初始化LVGL时,显式设置颜色格式:

/* 在lv_conf.h中配置 */
#define LV_COLOR_DEPTH     16
#define LV_COLOR_16_SWAP   0   /* 如果屏幕是BGR顺序,改为1 */

/* 或者在运行时设置 */
lv_display_set_color_format(disp, LV_COLOR_FORMAT_RGB565);

嗯,这里要注意:不是所有屏幕驱动都支持运行时切换RGB/BGR顺序。有些需要你在初始化SPI或并行接口时,通过写寄存器来配置。我建议你拿到一个新屏幕时,先画一个纯红、纯绿、纯蓝的色块,确认颜色顺序对不对。

图像撕裂——「帧同步没做好」

图像撕裂,说白了就是屏幕在刷新到一半的时候,你改了显存里的数据。上半部分还是上一帧的内容,下半部分已经变成下一帧了。看起来就像画面被撕开了一样。

LVGL本身提供了双缓冲机制来解决这个问题。但很多开发者图省事,只用了一个缓冲。我个人的建议是:只要硬件条件允许,一定要用双缓冲 + 垂直同步。

双缓冲的核心逻辑:
  1. LVGL在后台缓冲区绘制新帧
  2. 等待屏幕的垂直消隐期(VBlank)
  3. 在VBlank期间交换前后缓冲区指针
  4. 屏幕从新的缓冲区读取数据,完成刷新

你可能会问:「那我用单缓冲行不行?」行,但要做好心理准备。我在一个低成本的项目上用过单缓冲,结果只要UI更新频率超过30fps,撕裂就肉眼可见。后来加了双缓冲,问题立刻消失。

花屏分类与排查路径 花屏现象 显存层面问题 时序层面问题 未初始化显存 内存越界写入 颜色格式不匹配 行/场同步参数错误 DMA传输错位 帧同步缺失 表现形式(症状) 条纹 噪点 颜色错乱 图像撕裂 排查原则:先看表现形式,再判断是显存问题还是时序问题 同一表现形式可能对应多个根因,需要结合调试工具进一步确认

怎么快速判断是哪一类花屏?

我总结了一个简单的排查流程,你可以记一下:

  1. 先看花屏是否固定位置——如果是固定区域的条纹或噪点,大概率是显存问题或驱动参数问题。
  2. 再看花屏是否动态变化——如果画面不动时花屏消失,一动就出现撕裂,那基本是帧同步问题。
  3. 最后看颜色是否整体偏色——如果所有颜色都不对,先检查LVGL的颜色格式配置和屏幕驱动的RGB/BGR顺序。
一个小技巧:我习惯在LVGL初始化完成后,先画一个纯色渐变条。从黑到白,从红到蓝。这样一眼就能看出颜色顺序对不对、有没有条纹、显存有没有坏块。比看UI界面直观多了。