ST7701S屏幕点亮实战:SPI只是配角,MIPI DSI才是关键
做带屏项目的时候我最怕看到的就是“代码写完了屏幕不亮”这种问题。尤其是 ST7701S 这种 MIPI DSI 接口的 4寸屏很多人第一次接触都会被带偏以为 SPI 初始化写完屏幕就应该亮了。结果代码跑完屏幕要么黑着要么白屏然后就开始怀疑人生。这篇文章就把我踩过的坑、查过的问题、最后怎么点亮的思路完整拆给你看。先说结论避免各位走弯路ST7701S 这颗 IC 虽然可以用 SPI 写入初始化寄存器但它本质上是一颗 MIPI DSI 接口的显示驱动芯片。SPI 只是配角MIPI DSI 才是真正把图像数据送进屏幕的通道。你 SPI 初始化写得再漂亮如果 MIPI 端没有数据或者上电时序不对屏幕照样不亮。这也是很多人“SPI 初始化了屏幕还是不亮”的根本原因。1. 先想清楚ST7701S 到底是什么接口的IC1.1 SPI在整个方案里到底扮演什么角色ST7701S 是一颗用于中小尺寸 LCD 的显示驱动 IC常见于 4寸、4.3寸、5寸这类 480x800 分辨率的屏幕模组。它的数据手册写得挺清楚支持 MIPI DSI 作为显示数据主通道同时支持 SPI 或 I2C 作为辅助控制通道。什么意思呢就是你要给屏幕写初始化寄存器配置可以通过 SPI 来写但你要真正把图像数据刷到屏幕上必须走 MIPI DSI 的 D0/D1 差分信号线SPI 这条小水管根本送不了这么多数据。我打个比方你就明白了。SPI 通道就像一个设备的“调试串口”你通过它可以设置设备的参数、查看状态但设备真正工作时的业务数据走的是旁边那条千兆网线。你把调试串口配置得再好网线不插设备照样没法正常工作。很多第一次点 ST7701S 的朋友就是把 SPI 当成了那条“网线”觉得 SPI 初始化完成等于屏幕驱动完成这是最大的认知误区。1.2 很多人点不亮的第一个原因主控根本没有MIPI输出这个原因说出来你可能觉得搞笑但确实是实打实的高频问题。我见过不少朋友拿 STM32F103、STM32F407 这类 MCU 去接 ST7701S 的 4寸屏SPI 引脚确实连好了初始化代码也写了然后屏幕死活不亮。原因很简单STM32F103 和 F407 根本没有 MIPI DSI 控制器这个外设它连 MIPI 差分信号都发不出来。屏幕的 MIPI 接口压根收不到任何数据怎么可能亮你可能会说那我用 SPI 让 ST7701S 输出测试图案不就行了抱歉不行。ST7701S 虽然内部有测试模式但常规模组出厂时不会让客户通过 SPI 触发测试画面而且就算能触发那也不是应用场景该做的事。真正让屏幕亮起来显示你的 UI、图片、视频流MIPI DSI 通道是必须的。所以接 ST7701S 之前先确认你的主控平台主控平台是否支持 MIPI DSI常见型号STM32F1/F4 系列不支持STM32F103、STM32F407STM32MP1 系列支持STM32MP157i.MX 6/7/8 系列支持i.MX6ULL、i.MX8M Mini全志 V3s / F1C200s支持常用于带屏方案瑞芯微 RV1126 / PX30支持常用于 IPC / 带屏设备树莓派 CM4支持通过 DSI 接口FPGA MIPI TX IP支持需要额外 IP 核这里插一句很多人可能听商家说“4寸屏 SPI 接口”实际拿到的模组引脚里既有 SPI 引脚又有 MIPI 引脚有的还把 RGB 并行信号也引出来了这就很容易让人误会。一定以模组丝印和规格书为准ST7701S 的模组一般会有两种形态一种是纯 MIPI 接口SPI 只是配置口另一种是 RGB 接口版本实际内部由 ST7701S 转接这时候主控需要提供并行 RGB 信号和时钟跟 SPI 关系也不大。所以你第一步要搞清楚你手上的屏到底是哪一种。2. 硬件连接与上电时序先别碰代码检查这些2.1 供电与电压检查ST7701S 正常工作需要几组电源分别是 VCI 主电源、VDDIO 接口电源以及内部电荷泵产生的 AVDD、AVCL、VGH、VGL 等电压。VCI 通常是 2.5V~3.3VVDDIO 根据接口电平可能是 1.8V 或 3.3V。在排线端子上一般会有 VCI、VDDI 或者 IOVCC 引脚先拿万用表量一下确保电压到位。重点在后面这几个电压。ST7701S 内部有 DC-DC 电荷泵电路用来产生 TFT 屏幕驱动需要的 AVDD正压、AVCL负压、VGH栅极高压约 15V 左右、VGL栅极负压约 -10V 左右。这些电压由初始化寄存器里的 Power Setting 控制在代码没写对或者 IC 没正常启动时这些电压可能完全不存在。如果你屏幕黑着第一步不是盯着代码看而是拿万用表戳 VGH 和 VGL 测试点。没有这两组电压说明 ST7701S 内部的电源系统根本没有启动那代码写得再全也没用。反过来如果 VGH/VGL 正常但屏幕还不亮问题就在数据通路上。对于 4寸这种模组有些直接把 AVDD、AVCL 等电压在屏内部COG 绑定区或 FPC 上生成了不一定会引出来给你量。这种情况你就量 VCI 和 VDDIO再结合测试点判断总之先把供电链路捋清楚。2.2 引脚连接与常见接线坑ST7701S 的 SPI 引脚一般叫 SCL时钟、SDA数据、CS片选、DC 或者 RS命令/数据选择。有的模组上标注的是 SCLK、SDIN、PCS、DCX其实就是同一组东西。接线时注意 DC 这根线它决定了当前 SPI 传输的是命令还是数据必须由主控 GPIO 控制不能直接接固定电平。很多人点亮失败就是 DC 线和 CS 线搞反了或者 DC 直接接地导致命令数据全部分不清。复位引脚 RESX 也要重点看。这个引脚需要主控提供一个完整的低电平复位脉冲有些模组上设计成了 RC 上电自动复位接法上如果跟主控 GPIO 冲突可能导致复位状态不对。我的习惯是如果主控有 GPIO直接把 RESX 接管过来由代码控制复位时序不要依赖板上的 RC 复位。因为上电时序要求严格时RC 复位可能比 MIPI 初始化早太多或者复位释放时 SPI 还没就绪导致初始化丢失。背光控制同样容易被忽略。ST7701S 模组的背光一般由 LED / LED- 两根线控制有些模组会额外引出一根 BL_EN 或 PWM 控制脚。如果你的屏幕白屏但能看到背光亮说明背光已经工作如果整个屏幕全黑连背光都没有先检查背光灯供电和对地回路。需要注意的是背光使能最好不要在初始化之前打开否则屏幕会先亮一下然后黑屏容易误导你判断问题方向。FPC 排线的问题是另一个隐形杀手。4寸屏模组的 FPC 引脚间距通常很小焊接时容易连锡或者排线插座接触不良。我之前调一款 ST7701S 的屏代码怎么改都不行最后发现是 FPC 排线在测试座上没压紧MIPI 差分线有一根接触不良。这种问题最浪费时间所以动手前先拿放大镜检查排线特别是 MIPI 差分对 D0P/D0N、D1P/D1N 有没有虚焊。2.3 上电时序datasheet最容易被忽略的一页ST7701S 的数据手册里有一页 Power On Sequence中文叫上电时序是整颗 IC 能不能正常启动的关键。它规定了 VCI、VDDIO、RESX 等信号的上电先后顺序和时间间隔。很多工程师拿到屏的第一个动作就是写寄存器完全不管上电时序结果 IC 内部电源管理状态机没有正确走到工作态后面的初始化全部无效。按照我实测过并且稳定工作的流程先上 VCI 主电源延时至少 10ms再上 VDDIO 接口电源延时 10ms拉高 RESX 释放复位有些流程是先拉低再拉高;延时 120ms 左右等内部 OSC 和电源稳定然后才通过 SPI 写初始化寄存器。有人可能会问我只要复位信号和 SPI 在同一个电源域晚一点延时行不行行延时拉长一般是安全的但注意不要反过来如果在 VCI 还没稳定时就拉高 RESX或者复位释放得太早IC 可能进入不确定状态。这里我建议在代码里严格按延时来写别用“大概、差不多”这种心态延时长短就几行代码的事别省。另外RESX 复位脉冲本身也有要求。低电平保持时间至少要 10us很多人的代码里 GPIO 拉低后立刻拉高脉冲宽度根本不够IC 压根没接收到复位信号。我把这个时序写进代码后屏幕就正常了这是我踩过的最典型的低级错误。3. 初始化代码到底该怎么写从SPI寄存器到MIPI序列3.1 SPI写寄存器封装命令与数据之分ST7701S 的 SPI 写寄存器有个特点需要区分命令Command和数据Data。这个区分由 DC 引脚决定DC 为低时传输的是命令字节DC 为高时传输的是数据字节。写一条带参数的寄存器一般是先写命令字节再跟着写 n 个数据字节。整个传输靠 CS 片选包住。我给出一个基于 STM32 SPI 的封装示例这段代码是常规做法逻辑清晰适合参考void ST7701S_WriteCmd(uint8_t cmd) { LCD_DC_CLR; // DC 0传输命令 LCD_CS_CLR; SPI_SendByte(cmd); LCD_CS_SET; } void ST7701S_WriteData(uint8_t data) { LCD_DC_SET; // DC 1传输数据 LCD_CS_CLR; SPI_SendByte(data); LCD_CS_SET; } void ST7701S_WriteReg(uint8_t cmd, uint8_t *data, uint8_t len) { ST7701S_WriteCmd(cmd); for (uint8_t i 0; i len; i) { ST7701S_WriteData(data[i]); } }SPI 通信的参数方面ST7701S 一般支持 Mode 0 或 Mode 3也就是 CPOL0/CPOL1 配合 CPHA0/CPHA1 的四种组合。实际模组大部分用 Mode 0CPOL0、CPHA0也就是空闲时钟为低、第一个边沿采样。时钟频率建议不要超过 10MHz初始化寄存器数据量很小跑高了没必要反而容易因为飞线干扰导致时序不稳。我一般用 1MHz 到 4MHz 之间稳定性好。这里要特别提醒 DMA 的坑。如果你用 STM32 的 SPI DMA 去写一大串寄存器数据必须等 DMA 传输完成之后再去拉高 CS。不然 DMA 还在缓冲CS 就已经释放了最后一个字节会丢导致寄存器写错位。初始化这种千字节级别的数据量用轮询方式完全够没必要 DMA。DMA 更适合高频刷图但 ST7701S 刷图走的是 MIPISPI 这边根本轮不到 DMA 上场。3.2 先解锁寄存器组0xFF命令不能省ST7701S 的寄存器是按组Bank划分的不是所有寄存器地址都能直接访问。在切换寄存器组之前必须先发送一个解锁命令序列典型的写法是uint8_t unlock[] {0x77, 0x01, 0x00, 0x00, 0x13}; ST7701S_WriteReg(0xFF, unlock, 5);这条 0xFF 命令的作用是把芯片从“普通显示模式”切换到“寄存器配置模式”。很多从 ILI9341 这类老驱动 IC 转过来的人习惯性地直接写 0x21、0x3A 这类寄存器跳过 0xFF 解锁导致后面所有寄存器全部写入失败但芯片又不会报错看起来就像 SPI 发成功了实际一点效果没有。我第一次点 ST7701S 的时候也在这里翻了车。SPI 波形我看过了CS 正常、SCL 正常、SDA 上的字节也全部正确但屏幕就是不亮。后来对照 datasheet 才发现寄存器组没有解锁写在“空气”上了。所以你要记住ST7701S 的初始化代码开头第一件事就是 0xFF 解锁后面所有配置都跟着它走。还有一些屏的模组厂商会要求写两次 0xFF第一次切到厂商寄存器组第二次才是标准配置。这个不同模组差异较大以你拿到的初始化代码为准。通用的排查办法是如果初始化完成后 VGH/VGL 电压没起来大概率就是 0xFF 没写对。3.3 一套能用的初始化序列基于常见模组逻辑补充下面给出一套针对 480x800 4寸屏的基础初始化序列寄存器配置逻辑参照 ST7701S 常见模组驱动具体参数以你手上模组的规格书为准static void ST7701S_InitSequence(void) { // 1. 解锁寄存器组 uint8_t t1[] {0x77, 0x01, 0x00, 0x00, 0x13}; ST7701S_WriteReg(0xFF, t1, 5); // 2. 电源设置VCI、内部LDO、VGH/VGL相关 uint8_t t2[] {0x09, 0x00, 0x01, 0x05}; ST7701S_WriteReg(0xC6, t2, 4); uint8_t t3[] {0x13, 0xAD, 0x1F}; ST7701S_WriteReg(0xC7, t3, 3); uint8_t t4[] {0x05, 0x05, 0x05}; ST7701S_WriteReg(0xC8, t4, 3); uint8_t t5[] {0x3E}; ST7701S_WriteReg(0xCC, t5, 1); uint8_t t6[] {0x02, 0x03, 0x00, 0x01, 0x03, 0x0A, 0x0B, 0x09}; ST7701S_WriteReg(0xD0, t6, 8); // 3. Porch和时序设置决定图像位置和消隐区 uint8_t t7[] {0x00, 0xD8, 0x00, 0x00, 0x00, 0x28, 0x00, 0x50, 0x00, 0x10, 0x18, 0x00}; ST7701S_WriteReg(0xB0, t7, 12); // 4. Gamma设置这片直接决定了色彩和对比度 uint8_t t8[] { 0x00, 0x0E, 0x15, 0x1C, 0x29, 0x32, 0x44, 0x4E, 0x55, 0x65, 0x72, 0x7E, 0x86, 0x92, 0xA0, 0xAA, 0xB4, 0xBE, 0xC8, 0xD2, 0xDD, 0xE5, 0xEF, 0xF8, 0xFF }; ST7701S_WriteReg(0xE0, t8, 25); ST7701S_WriteReg(0xE1, t8, 25); // 5. 显示相关设置 uint8_t t9[] {0xC0}; ST7701S_WriteReg(0xE9, t9, 1); uint8_t t10[] {0x01}; ST7701S_WriteReg(0xEA, t10, 1); // 6. 关闭寄存器配置模式回到正常显示状态 uint8_t t11[] {0x00}; ST7701S_WriteReg(0xFF, t11, 1); // 7. 退出睡眠开启显示 ST7701S_WriteCmd(0x11); HAL_Delay(120); ST7701S_WriteCmd(0x29); HAL_Delay(20); }需要说明的是Gamma 寄存器组 0xE0/0xE1 里面每一项都是对应灰阶的电压权重不同屏厂会有不同的推荐值。上面这组是我调试某款 4寸 IPS 屏时调出来效果还不错的参数你可以先用起来再微调。如果颜色怪异或者对比度不对优先改这组值。初始化顺序里有一个细节0x11Sleep Out命令之后必须等待至少 120ms让 IC 从睡眠模式完全唤醒。0x29Display On之后也要等 20ms 左右。很多人把 0x11 和 0x29 连着写完不延时屏幕就是不出图或者出图后闪烁。这个延时是硬性要求不是可选项。3.4 MIPI时钟与像素时钟估算屏幕能不能正常显示MIPI DSI 的时钟配置是核心。这里我们做一个简单计算。4寸屏分辨率 480x800刷新率 60Hz像素时钟需求大约是 480×800×60约等于 23MHz。实际还要算上 H/V Porch通常在 30MHz 左右。如果采用 2-lane MIPI DSI每个 lane 的数据率就是 30MHz × 24bitRGB888÷ 2约等于 360Mbps。再算上 MIPI DSI 协议开销实际每 lane 数据率建议配在 400Mbps 到 500Mbps 左右。具体到主控配置MIPI DSI 的时钟 PLL 和 lane 数、像素格式、刷新率都要匹配。比如用 i.MX 或全志平台屏幕的 device tree 里 dsi 时钟就按这个速率去填。如果设得太低可能屏幕闪屏或者显示内容有噪点设得太高又可能超过屏模组 DSI 接口的极限速率导致信号质量下降。最稳妥的做法是照着模组厂商给的初始化代码里的时钟参数配不要自己随便改。一个非常常见的现象是初始化代码正常背光亮了但屏幕显示花屏、条纹、图像撕裂。这种大概率就是 MIPI 时钟和 Porch 参数不匹配。Porch 参数在 0xB0 寄存器里如果有问题图像会偏移、错位表现为花屏。这种情况查寄存器参数和时钟配置比你反复改 SPI 初始化有用得多。4. 屏幕不亮的常见问题排查实录4.1 黑屏、白屏、花屏分别是什么原因把现象分类排查效率会高很多。我遇到过的 ST7701S 点不亮问题基本可以归为三类现象可能原因优先排查顺序全黑连背光都不亮背光供电、BL_EN 引脚、LED 灯串损坏检查 LED / LED-BL_EN 电平背光亮但屏幕完全没图像白屏MIPI 数据没送入、初始化未生效、0x11/0x29 未执行查 VGH/VGL、查 MIPI 波形、查 0xFF 解锁花屏 / 条纹 / 重影MIPI 时钟速率不对、Porch 参数错误、lane 数不匹配查时钟配置、0xB0 Porch 寄存器、DSI lane 配置半个屏亮 / 半个屏暗栅极驱动电压异常、FPC 排线接触不良检查 VGH/VGL、重新压排线这三种现象里最迷惑的是白屏。背光亮说明模组的背光电路完全正常白屏说明 TFT 面板处于无信号驱动的稳定状态也就是要么 MIPI 没送数据要么 ST7701S 内部没有正常开始扫描。这时候先别急着重写初始化代码先把万用表拿出来量 VGH/VGL。VGH 正常应该有 15V 左右的正压VGL 是负压。如果 VGH 是 0V说明 ST7701S 内部的电荷泵没有启动问题一定出在电源配置寄存器或者上电时序上。黑屏问题则要分清是“黑得一点光没有”还是“隐隐约约有背光但不显示”。完全无背光的话回路线检查背光使能引脚很多模组的 BL_EN 内部有上拉悬空时可能默认开启也可能关闭以规格书为准。我当时遇到过 BL_EN 引脚没接背光完全不亮的情况飞线接上之后屏幕立刻有了状态变化。花屏大概率是数据链路的问题。MIPI DSI 是一条高速差分链路如果 lane 数配错了比如模组是 2-lane 但主控配成了 4-lane或者时钟频率偏差过大都会导致花屏。另外也要检查 MIPI 的极性D0P/D0N 接反了直接不显示或者画面全乱。有的屏模组标注的 D0P/D0N 跟主控端的定义有差异画原理图时最容易出这种错。4.2 用万用表和逻辑分析仪快速定位排查顺序很重要。我的习惯是先量电源再量复位再抓 SPI最后看 MIPI。电源部分VCI 和 VDDIO 必须稳定在规格范围内允许的纹波不能太大。VGH/VGL 如果引出来了就量一下有没有电压如果没引出可以通过测量 IC 附近的电容引脚间接判断。逻辑分析仪在 SPI 阶段非常有用。把 CS、SCL、SDA、DC 四根线挂上逻辑分析仪触发条件设置成 CS 下降沿然后跑一遍初始化代码就能看到完整的 SPI 时序。对照 datasheet 检查CS 是否在整个传输期间保持有效SCL 的边沿和数据是否对齐DC 在命令字节和数据字节之间有没有正确切换SDA 上的字节内容是否跟代码一致。很多人初始化失败是焊接虚焊或者接线错误导致的逻辑分析仪一抓问题立刻暴露。还有一个重要技巧读 ID。ST7701S 支持通过 SPI 读寄存器你可以写一个读函数读取 Product ID 寄存器。如果 ID 读出来是 0x00 或者 0xFF说明芯片响应异常要么没复位成功要么供电有问题要么 SPI 时序不满足。如果 ID 能读出来比如常见的 0x77 或 0x01 这种说明芯片已经正常通信了问题大概率在 MIPI 端。这里补充一句写读寄存器传输时序的时候注意发送完命令后立即切换方向ST7701S 在 MDDI/MIPI 模式下的 SPI 读时序跟普通 SPI Flash 略有不同按 datasheet 图示操作。uint8_t ST7701S_ReadReg(uint8_t cmd) { uint8_t val 0; LCD_DC_CLR; LCD_CS_CLR; SPI_SendByte(cmd); LCD_DC_SET; val SPI_ReceiveByte(); // 读取期间 SCL 继续产生时钟 LCD_CS_SET; return val; }4.3 初始化代码常见“写了等于没写”的原因写 ST7701S 的初始化代码容易出现一个非常隐蔽的情况SPI 波形完全正常寄存器全部发送成功但屏幕一点反应都没有。这种“写了等于没写”的问题我总结下来常见原因有这几个。第一个就是寄存器组没解锁0xFF 命令没写或者写错了。前面已经强调过这是 ST7701S 跟传统 SPI 屏最大的差异点。每次切换寄存器 Bank 都要重新写 0xFF有些模组的厂商代码甚至会连续写两次 0xFF就是为了彻底切换 Bank。如果你用的是厂家提供的初始化数组一定要原样保留 0xFF 的位置和参数不要觉得它只是“命令头”随便改或者省略。第二个是 RESX 复位时序不合适。复位脉冲太短IC 没有真正复位内部状态还停留在上电初始化的某个中间态。如果代码里 GPIO 配置成开漏且没有上拉也可能导致复位信号释放后处于不确定电平。我的做法是配置成推挽输出初始化前先把 RESX 拉低 20ms再拉高延时 120ms等芯片稳定后再写 SPI。第三个是命令 0x11 和 0x29 的执行顺序不对。有的初始化数组里厂商把 0x11 放在最前面把 0x29 放在最后如果你在中间插入了自己的寄存器配置可能会打断 Sleep Out 的流程。所以最稳妥的做法是先写完所有寄存器配置最后统一执行 0x11、延时 120ms、0x29、延时 20ms然后开启背光。不要在自己添加的寄存器后面乱加 Sleep Out 命令否则某些 Bank 配置可能被覆盖。第四个是背光使能的问题。有的模组背光 PWM 引脚默认是关闭的初始化代码本身不会去开背光需要主控额外把 BL_EN 拉高。如果你没拉高白屏是必然的。把背光控制放到初始化最后一步判断“屏幕亮没亮”的时候要区分“背光亮但没图像”和“背光不亮”这是完全不同的两条排查路径。4.4 关于SPI DMA和工具链的一个补充我在开头提到了热词里有 STM32F103 SPI DMA 和 CubeMX这里再展开说一下。很多人在配置 SPI 初始化时会遇到 DMA 接收数据相关问题。对于 ST7701S 这类驱动 ICSPI 的职责只有初始化寄存器数据量非常少也就几百字节这个场景下 DMA 是完全多余的。DMA 的好处是节约 CPU但初始化本来就是一次性操作CPU 占用几十毫秒根本无所谓。如果非得要 DMA 传输一定要在 DMA 传输完成回调里再拉高 CS 和切换 DC否则会有字节丢失的风险。我建议在使用 CubeMX 生成初始化代码时SPI 速率先降低比如配置成 1MHz等屏幕稳定点亮之后再往上提。这样可以排除时钟太快导致的信号质量问题。CubeMX 生成的 SPI 初始化代码里注意 SPI_Mode 设置为 Mode 0方向设置成 Tx 为主。如果之前配置过双向模式读数据和写数据的方向切换可能造成 CS 状态异常。工具链方面如果遇到动态库加载类错误优先把驱动重装干净再继续调屏驱动问题不至于卡住点屏逻辑。最后一句话的体会屏幕不亮的时候最容易让人上头代码改了一版又一版其实是憋着一股劲在碰运气。我踩过 ST7701S 的坑之后现在点屏有了固定套路先量电压再查复位再抓 SPI最后才碰初始化代码。尤其记住 0xFF 解锁、0x11 延时、RESX 脉冲宽度这三件事ST7701S 这类的屏会好伺候很多。这条经验有时候也能推到你后面所有 MIPI 屏项目上调过一轮之后再遇到不亮的屏你就知道该从哪里下手了。