1. 高通SDX35平台LCD驱动开发概述
在嵌入式系统开发中,显示驱动调试是硬件适配的关键环节。高通SDX35作为一款广泛应用于物联网和边缘计算设备的芯片平台,其显示驱动开发具有典型的参考价值。ST7735SV是一款常见的1.8英寸128x160分辨率SPI接口LCD屏,成本低廉且易于集成,非常适合作为SDX35平台的显示输出设备。
我在最近一个车载HMI项目中实际调试过这套组合,发现虽然官方文档提供了基础框架,但实际开发中仍有不少需要特别注意的技术细节。本文将基于UEFI阶段的驱动实现,详细解析从硬件连接到软件绘制的完整流程,特别是那些容易踩坑的关键点。
2. 硬件接口与初始化配置
2.1 物理连接方案
ST7735SV与SDX35主要通过SPI接口通信,典型连接方式如下:
- SDX35 GPIO12 → LCD SCL(时钟线)
- SDX35 GPIO13 → LCD SDA(数据线)
- SDX35 GPIO14 → LCD RS(寄存器选择)
- SDX35 GPIO15 → LCD RESET(复位线)
- SDX35 GPIO16 → LCD CS(片选)
特别注意:SDX35的SPI控制器默认时钟频率可能高达50MHz,而ST7735SV最高只支持15MHz。务必在初始化时通过CLOCK_CONTROL_REGISTER将频率降至10MHz左右,否则会出现显示错乱。
2.2 电源时序要求
ST7735SV对电源序列有严格要求:
- 先提供VCC(3.3V)和LED背光电压
- 保持RESET低电平至少10ms
- 释放RESET后延迟120ms再发送初始化命令
- 初始化命令全部发送完成后,再开启背光
我在实际调试中发现,如果违反这个时序,屏幕可能出现局部显示异常或根本无法启动。建议用示波器捕获各信号线的时序关系,确保符合下图要求:
| 信号线 | 相对时序要求 | 典型值 |
|---|---|---|
| VCC | 最先上电 | t0 |
| RESET | VCC稳定后拉低 | t0+10ms |
| 命令 | RESET释放后 | t0+130ms |
| 背光 | 初始化命令完成后 | t0+200ms |
3. UEFI驱动框架实现
3.1 EFI_GRAPHICS_OUTPUT_PROTOCOL集成
SDX35的UEFI固件已经实现了图形输出协议框架,我们需要做的是填充ST7735SV的特定操作:
c复制typedef struct {
VENDOR_DEVICE_PATH VendorDevicePath;
EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
} ST7735SV_DEVICE_PATH;
typedef struct {
UINT32 Signature;
EFI_HANDLE Handle;
EFI_GRAPHICS_OUTPUT_PROTOCOL Gop;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo;
// ...其他成员变量
} ST7735SV_PRIVATE;
关键是要正确实现以下函数指针:
- QueryMode:返回支持的显示模式
- SetMode:切换显示模式
- Blt:执行图形块传输(核心绘制函数)
3.2 SPI通信层实现
ST7735SV使用SPI的Mode3(CPOL=1, CPHA=1),数据位宽8bit。每个命令传输包含:
- 拉低CS片选信号
- 拉低RS表示发送命令,拉高RS表示发送数据
- 发送1字节命令码
- 发送N字节参数(视具体命令而定)
典型命令发送函数实现:
c复制EFI_STATUS SendCommand(
ST7735SV_PRIVATE *Private,
UINT8 Command,
UINT8 *Params,
UINT8 ParamCount)
{
SPI_SET_CS(0); // 选中设备
// 发送命令阶段
SPI_SET_RS(0);
SPI_WRITE(&Command, 1);
// 发送参数阶段
if(ParamCount > 0) {
SPI_SET_RS(1);
SPI_WRITE(Params, ParamCount);
}
SPI_SET_CS(1); // 释放设备
return EFI_SUCCESS;
}
4. 显示初始化序列详解
ST7735SV需要严格按照手册要求的顺序发送初始化命令,以下是关键步骤:
- 软件复位:发送0x01命令,延迟5ms
- 退出睡眠模式:发送0x11命令,延迟120ms
- 设置颜色模式:发送0x3A命令,参数0x05(16位RGB565)
- 设置显示方向:发送0x36命令,参数0xA0(横屏模式)
- 设置GRAM区域:发送0x2A命令,参数0x00,0x00,0x00,0x9F(X方向)
- 开启显示:发送0x29命令
调试技巧:建议在每个命令后添加10-100ms的延迟,方便用逻辑分析仪捕获信号。确认初始化正常后,再逐步减少延迟优化启动速度。
5. 图形绘制优化实践
5.1 高效Blt实现
EFI_GRAPHICS_OUTPUT_PROTOCOL的Blt函数需要处理多种操作:
- 缓冲区到屏幕的拷贝(EfiBltBufferToVideo)
- 屏幕到缓冲区的拷贝(EfiBltVideoToBuffer)
- 屏幕内区域拷贝(EfiBltVideoToVideo)
以最常用的EfiBltBufferToVideo为例:
c复制EFI_STATUS BltBufferToVideo(
ST7735SV_PRIVATE *Private,
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
UINTN DstX, UINTN DstY,
UINTN Width, UINTN Height)
{
// 1. 设置GRAM窗口
SetWindow(DstX, DstY, Width, Height);
// 2. 准备像素数据
UINT16 *PixelBuf = AllocatePool(Width * sizeof(UINT16));
for(UINTN y=0; y<Height; y++) {
for(UINTN x=0; x<Width; x++) {
PixelBuf[x] = RGB888ToRGB565(BltBuffer[y*Width + x]);
}
// 3. 批量写入一行像素
SendPixels(PixelBuf, Width);
}
FreePool(PixelBuf);
return EFI_SUCCESS;
}
5.2 双缓冲机制
为避免画面撕裂,建议实现双缓冲机制:
- 在内存中维护一个与屏幕分辨率相同的后备缓冲区
- 所有绘制操作先在后备缓冲区完成
- 垂直同步时通过Blt一次性更新到物理屏幕
6. 常见问题排查指南
6.1 屏幕无显示
- 检查电源电压(3.3V±5%)
- 用逻辑分析仪确认SPI信号是否正常
- 测量背光电压(通常需要5-15V)
- 检查复位时序是否符合要求
6.2 显示颜色异常
- 确认颜色模式设置(0x3A命令)
- 检查RGB565/RGB888转换函数
- 验证SPI时钟极性设置(Mode3)
6.3 显示内容错位
- 检查GRAM窗口设置(0x2A/0x2B命令)
- 验证显示方向参数(0x36命令)
- 确认像素坐标计算是否正确
7. 性能优化技巧
- SPI时钟优化:在确保稳定的前提下,逐步提高时钟频率(最高15MHz)
- 批量写入:尽量使用整屏更新而非单像素操作
- DMA传输:启用SPI控制器的DMA功能减少CPU占用
- 部分刷新:只更新屏幕中变化的部分区域
我在实际项目中通过这几种优化手段,将界面刷新率从最初的12fps提升到了35fps,完全满足车载仪表盘的流畅度要求。
调试这类显示驱动时,逻辑分析仪和示波器是必不可少的工具。建议在关键信号线上添加测试点,方便随时测量波形。另外,高通提供的QPST工具可以实时监控SPI控制器状态,对排查通信问题很有帮助。
