3. 初始化时序排查:检查复位时序、检查SPI/I8080初始化序列、检查睡眠唤醒命令
屏幕花屏,很多时候不是代码逻辑错了,而是初始化时序没给对。说白了,就是屏幕在上电到正常显示之间,有一连串的“握手”动作。任何一个动作没卡准点,屏幕就会给你点颜色看看——花屏、闪屏、甚至白屏。
我刚开始调屏幕驱动时,总觉得时序这东西差不多就行。结果有一次,一块新屏死活出不来画面,折腾了两天。最后发现,就是复位信号保持时间短了那么几毫秒。从那以后,我再也不敢小看初始化时序了。
3.1 复位时序——屏幕的“开机自检”
屏幕芯片内部也有个“小电脑”。上电后,它需要一段干净的时间来完成内部状态初始化。这个动作,就是靠复位引脚来触发的。
典型的复位时序要求是这样的:
| 参数 | 最小值 | 典型值 | 说明 |
|---|---|---|---|
| 上电后到复位拉低 | 10 ms | 20 ms | 等电源稳定后再复位 |
| 复位低电平保持 | 10 ms | 20 ms | 给芯片足够时间复位 |
| 复位拉高后等待 | 120 ms | 150 ms | 等待内部振荡器稳定 |
我见过一个案例,工程师把复位低电平时间写成了 1 ms。屏幕偶尔能亮,但大部分时间花屏。查了半天,就是这 1 ms 和 10 ms 的差距。你想想看,芯片内部状态还没清干净,你就开始发命令,不出问题才怪。
正确的复位流程应该是:
- 上电后,等待电源稳定(至少 20 ms)。
- 将复位引脚拉低,保持 20 ms。
- 将复位引脚拉高,等待 150 ms。
- 然后才能开始发送初始化命令。
代码实现上,我习惯这样写:
// 复位屏幕
void lcd_reset(void) {
// 1. 等待电源稳定
delay_ms(20);
// 2. 拉低复位引脚
LCD_RST_GPIO->BRR = LCD_RST_PIN;
delay_ms(20);
// 3. 拉高复位引脚
LCD_RST_GPIO->BSRR = LCD_RST_PIN;
delay_ms(150);
// 4. 复位完成,可以开始初始化
}
3.2 SPI/I8080 初始化序列——命令的“正确姿势”
复位完成后,就要开始给屏幕发初始化命令了。这些命令通常包括:软件复位、睡眠唤醒、像素格式设置、显示方向设置、伽马校正等。
但这里有个坑:命令的发送顺序和间隔,是有严格要求的。
我举个例子。很多屏幕在初始化时,需要先发一个 Software Reset (0x01) 命令,然后等待 5 ms,再发 Sleep Out (0x11) 命令,然后等待 120 ms,最后才能发 Display On (0x29) 命令。
如果你把 Sleep Out 和 Display On 连在一起发,中间没有延时,屏幕很可能就花屏了。为什么?因为屏幕从睡眠模式唤醒,内部需要时间稳定。
典型的 SPI 初始化序列代码:
// 发送初始化命令序列
void lcd_init_sequence(void) {
// 软件复位
lcd_write_cmd(0x01);
delay_ms(5);
// 睡眠唤醒
lcd_write_cmd(0x11);
delay_ms(120);
// 像素格式:16位色
lcd_write_cmd(0x3A);
lcd_write_data(0x55);
delay_ms(1);
// 显示方向设置
lcd_write_cmd(0x36);
lcd_write_data(0x00);
delay_ms(1);
// 打开显示
lcd_write_cmd(0x29);
delay_ms(10);
}
对于 I8080 接口,除了命令延时,还要注意读写时序。I8080 是并行接口,数据线多,时序要求更严格。我曾经遇到一个项目,用 I8080 接口驱动 3.5 寸屏,总是出现水平条纹。后来用逻辑分析仪抓波形,发现是写信号(WR)的保持时间不够。调整了 MCU 的 FSMC 时序参数后,问题就解决了。
3.3 睡眠唤醒命令——最容易忽略的“隐形杀手”
很多屏幕在上电后,默认是处于睡眠模式的。你必须先发 Sleep Out (0x11) 命令,把它唤醒,然后才能正常操作。
但这里有个细节:睡眠唤醒后,需要等待足够长的时间。
数据手册上通常会写:
Sleep Out命令发出后,需要等待 120 ms(有些屏幕甚至需要 200 ms)。- 在等待期间,不能发送任何其他命令,否则屏幕可能进入未知状态。
- 唤醒完成后,屏幕会自动进入正常模式。
我见过一个工程师,在 Sleep Out 后面只等了 10 ms,就开始发显示数据。结果屏幕花得像万花筒。他查了两天代码,最后发现是延时不够。加了 120 ms 延时后,一切正常。
Sleep Out 之后,还需要发一个 Display On 命令,并且中间要等 10 ms。很多人的初始化代码里只发了 Sleep Out,忘了 Display On,导致屏幕虽然亮了,但显示不正常。
完整的睡眠唤醒流程应该是:
- 发
Software Reset (0x01),等 5 ms。 - 发
Sleep Out (0x11),等 120 ms。 - 发其他初始化命令(像素格式、显示方向等)。
- 发
Display On (0x29),等 10 ms。 - 然后才能开始刷屏。
3.4 初始化时序排查流程图
下面这张图,是我自己总结的初始化时序排查流程。每次遇到花屏,我都会按这个顺序检查一遍,基本能定位 90% 的问题。
这张图的核心逻辑很简单:按顺序排查,不要跳步。复位时序不对,后面的初始化序列再完美也没用。睡眠唤醒没做好,屏幕可能根本不会正常显示。
嗯,初始化时序这块,说白了就是“慢工出细活”。别嫌延时浪费 CPU 时间,屏幕稳定显示比什么都重要。我曾经为了省那几十毫秒,把延时全删了,结果屏幕花得一塌糊涂。从那以后,我老老实实按数据手册来,再也不敢偷懒了。