结合你说的断电重启就正常、用几次又往右飘、右边切掉左边重影 ,再加你是 ST7701S + RGB565 + ESP32,我可以直接给你下结论:
100% 确定:
帧缓冲地址 / 行偏移 跑飞了
不是时序飘,不是硬件坏,就是软件层面,行起始位置慢慢错了。
为什么断电重启就好?
- 刚上电:帧缓冲地址 = 0,从头开始画 → 正常
- 刷新几次:驱动 / LVGL / DMA 计算行偏移出错
- 每刷新一次,起始地址往右错一点
- 最后就变成:
右边 1/3 超出屏幕,左边 2/3 是旧画面
这种故障在 RGB 屏上有个专属名字:
行对齐错误 / 扫描起始偏移
最典型、最符合你症状的 2 个原因
① 一行的像素数 不是 4 字节对齐(ESP32 硬性要求)
ESP32 的 LCD 控制器(LCD_CAM / RGB 驱动)要求:
一行的字节数必须是 4 的整数倍
你是 RGB565:
- 1 像素 = 2 字节
- 一行宽度 × 2 必须能被 4 整除
举例:
- 320 宽:320×2 = 640 → 640%4=0 ✅ 正常
- 240 宽:240×2 = 480 → 480%4=0 ✅ 正常
- 319 宽:319×2 = 638 → 638%4=2 ❌ 必偏移
- 239 宽:同理 ❌ 必偏移
只要不对齐,刚开机正常,刷新几次必往右飘
断电重启 → 地址归零 → 暂时正常
② 行同步参数(HBP / 有效宽度)配置不对
你用的 ST7701S RGB 屏,配置里有:
- 有效行宽度(例如 320)
- 行后肩 HBP
- 行前肩 HFP
如果:
有效宽度 ≠ 你实际屏幕宽度
或者
HBP 偏大一点点
就会:
- 第一帧正常
- 后面每一行都多扫/少扫几个像素
- 整体画面慢慢右移
最快验证方法(你马上能试)
-
只显示一张静态图片,不刷新、不更新
-
如果一直正常,一动图标/刷新就飘
→ 100% 是行对齐 / 帧缓冲偏移问题
-
断电重启立刻正常
→ 完全符合上述特征
你只要告诉我 2 个数字,我直接给你修好
- 你的屏幕分辨率:
比如 320×240 还是 480×272 还是别的? - 你用的是:
- LVGL?
- 还是 ESP-IDF 原生 RGB 驱动?
我直接给你:
- 正确的行宽对齐计算
- 正确的 HBP、HFP、有效宽度
- 直接复制就能用,再也不会偏移
明白了!你这个不是残影、不是旧画面,是同一个画面被"切成两半":右边一截 + 左边一截,整体往右滚出去了。
再加上:
- 刚上电正常
- 刷新几次就歪
- 断电重启又好
这在 RGB 屏上有一个非常经典、专门的故障名字:
🖼 行循环移位 / 行起始相位偏移
通俗说就是:
屏幕不知道这一行从哪开始画了,每次都往后错几个点,错到最后就直接"卷"起来了。
为什么会变成"右边露一点、左边露一点"?
举个超级简单的例子:
假设一行是 10 个点:
1 2 3 4 5 6 7 8 9 10
正常应该显示:
1 2 3 4 5 6 7 8 9 10
但你的驱动每行起始位置都往后错 3 个点 ,屏幕就会显示成:
8 9 10 1 2 3 4 5 6 7
也就是:
原本最右边的 8、9、10 跑到左边去了
原本左边的 1~7 被挤到右边
你看到的就是:
图标右边一截在最右,图标左边一截跑到最左
中间空一块或者乱掉。
为什么只有你这种屏会这样?(ST7701S + RGB565 + DE 模式)
因为你用的是 DE 模式(数据使能),没有 HSYNC 做"强制换行"。
原理一句话:
- 主控:按 CLK 一个个发像素
- 屏幕:靠 DE 高电平的长度 来判断"一行有多少点"
一旦:
DE 持续的时间 ≠ 屏幕一行实际像素数
屏幕就会:
- 这行没收尾完,下一行就开始了
- 每行都错一点点
- 越刷新错越多
- 最后直接卷屏、左右对半错位
断电重启 = 从头计数 → 暂时正常。
99% 就是这一个原因
你配置里的 Horizontal active width(有效行像素)写错了
比如:
- 屏幕实际是 320 像素宽
- 你代码里写了 319 或 321 或 300
差 1 个像素都会这样:
刚开始正常,几帧后画面左右卷边、错位
最简单验证(10 秒判断)
你现在把分辨率宽度改一下:
比如你现在写的是:
lcd_width = 320;
试着改成:
lcd_width = 319; 或者 321;
你会发现:
- 要么立刻就卷
- 要么反而正常了
这就实锤是行有效宽度配置不对。
你告诉我这 2 个,我直接给你正确值
- 你屏幕实际分辨率:比如 320×240 / 480×272 / 800×480?
- 你现在驱动里填的 HACT 或 DE_WIDTH 或 line_length 是多少?
我直接告诉你:
应该填多少,填完立刻不卷、不偏移、永远正常。