AMOLED显示屏驱动移植随笔

        驱动IC使用CO5300。按照厂家所给接线图,基于esp32S3 按如下规则接线。

编号ESP32-S3 GPIO模块引脚名称功能说明分类
1GPIO19LCD_RESETLCD 复位LCD 控制
2GNDGND地线电源
3GPIO20LCD_TE撕裂检测,可选LCD 控制
4GPIO21LCD_CSLCD 片选QSPI
5GPIO47SPI_CLKQSPI 时钟QSPI
6GPIO48SPI_SI01QSPI IO1QSPI
7GPIO41SIOO (IO0)QSPI IO0QSPI
8GNDGND地线电源
9NC无连接无需连接
10NC无连接无需连接
113.3V / 5VVBAT主供电电源
123.3V / 5VVBAT主供电(同上)电源
13GNDGND地线电源
14GNDGND地线电源
153.3VVDDIO电压参考电源
163.3VTP_VDD触摸供电电源
17GPIO35TP_INT触摸中断触摸(I2C)
18GPIO36TP_RST触摸复位触摸(I2C)
19GPIO37TP_SDA触摸数据线触摸(I2C)
20GPIO38TP_SCL触摸时钟线触摸(I2C)
21GNDGND地线电源
22GPIO39SPI_SIO3QSPI IO3QSPI
23GPIO40SPI_SI02QSPI IO2QSPI
243.3VVCI_EN电源使能,高电平有效控制

厂家给的屏幕引脚定义如下:

        按硬件接好线,然后进行驱动移植。 首先移植屏幕显示驱动。CO5300 屏幕所用到的是这款驱动IC。先阅读厂家给的代码。

        QUAD SPI 接口中,命令/读写操作用的是 1 根线(串行),而 像素数据的写入用的是 4 根线(并行),能加快数据传输速度。

  • 命令阶段:标准 SPI(MOSI)

  • 像素数据阶段:切换为 QSPI 模式,使用 SIO0~SIO3

依据来源于数据手册这段话:

命令控制SPI,发送一字节函数

对于段中的这句话理解是:

SCL is driven from high to low then pulled back to high during the write cycle.

👉 SPI 的 SCL 时钟线(对应 ESP32 上的 SPI_CLK):

  • 写周期中,时钟信号从高 → 低 → 再回到高,用于时序控制

⚠️ 注意:这与标准 SPI 模式 0(CPOL=0, CPHA=0)相符,CO5300 SPI 时序为:上升沿采样(rising edge)

了解了屏幕是如何写入数据后,我们现在看看SPI具体写入哪些数据。

        QUAD SPI接口包含三种操作模式,标准SPI、双SPI和四SPI。这些模式的结构如下。

   这里展示了如何从上电默认的一线spi 转换到其他模式。其中要RGB为什么会有两组命令,我猜想是为了区分和控制RGB888和RGB565。

使用流程举例(以 QSPI 为例)

  1. MCU 上电后,默认使用标准 SPI

  2. 发送配置命令(如设置分辨率、偏压、帧率等)

  3. 0x38 命令 → 启用 QSPI 模式

  4. 0x32 命令 → 通知屏幕:我要写图像数据了(QSPI,RGB888)

  5. 开始通过 SIO0 ~ SIO3 发像素数据

那么我们看到厂家给的代码

在这里 0x02是什么意思呢?看到数据手册当中的这个表。

是控制或者像素点写入命令!为何代码中又又0x00呢,我猜想是占位符的作用。这个时候我们去看一下一线写入时序图。

        可以看到发送0x02。但是上图还不能确定为什么要写0x00,看下图四线的就知道了,地址实际上是使用到1字节,前后两字节用作填充的。故而在SPI_SendData(i);前后各有一字节的0x00。

接着我们看一下QSPI 4-wire write 是如何实现的:

        SCLK上升沿有效,地址是三字节。一个时钟周期并行发送4个bit。

我们接着看QSPI 4-wire 在代码中如何实现写的,看下图代码(这里由于代码比较长截图不方便我放在代码框中)。 

//这个是四线spi的传输数据 高字节在前
void SPI_WriteData1(unsigned char i)
{
  SPI_CLK=0;_nop_(); _nop_();
	  if(i&0x80) SPI_D3=1;
      	else SPI_D3=0;

		if(i&0x40) SPI_D2=1;
      	else SPI_D2=0;
	
		if(i&0x20) SPI_D1=1;
      	else SPI_D1=0;
	
		if(i&0x10) SPI_DI=1;
      	else SPI_DI=0;
	
      SPI_CLK=1;//_n
	_nop_();_nop_();
		  SPI_CLK=0;_nop_(); _nop_();
		  if(i&0x08) SPI_D3=1;
      	else SPI_D3=0;
		
		if(i&0x04) SPI_D2=1;
      	else SPI_D2=0;
				
		if(i&0x02) SPI_D1=1;
      	else SPI_D1=0;
				
		if(i&0x01) SPI_DI=1;
      	else SPI_DI=0;
	
      SPI_CLK=1;_nop_();_nop_();
}

        除了数据传输,后面我们来研究一下RGB数据是如何传输的,这个主要是图像数据传输。我们这里主要是去看RGB565,先看时序图。

         0x32表示采用四线 ,0x2C/0x3C表示地址选择,地址阶段为 24 个时钟(= 3 字节)随后开始写像素数据。

        0x12表示采用四线 ,地址阶段为 6个时钟(= 0.75 字节)随后开始写像素数据。

这里就有疑问了为什么会有两个写地址呢?原因如下:

0x32 是万能 QSPI 写命令,适用于所有图像传输;
0x12 是轻量快速命令,适用于小区域图像刷新。
二者写的是一样的像素格式(如 RGB565),只是地址阶段不同。

我们继续往下看,上面说的都是写命令,我们接着写读取命令,读取的时候是one-wire SIDO接口输出

通过这个我们可以读取到很多数据。后面在去学习如何读取屏幕数据。

我们先了解一下 TE(Tearing Effect) 这个信号引脚的相关知识。

        这是指 屏幕在绘制一行像素前后,还会有短暂的“空白区域”,就是 HBP 和 HFP。这些区域不会显示内容,是给驱动 IC 做同步用的。

    ↓ 这一帧结了
 ┌───────────────┐
 │    VBP 区域    │   ← 屏幕在这个阶段没有画图(可以安全更新)
 │───────────────│
 │  图像有效区域  │ ← 一行一行地刷图
 │───────────────│
 │    VFP 区域    │
 └───────────────┘
    ↑ 下一帧要开始了

消隐区内更新数据是“安全”的,避免图像撕裂。

        这个芯片当中给了几种模式,那么我在这里就选取其中mode1。

        在 TE 模式 1 下,输出的 TE 信号只包含**垂直同步(V-sync)垂直消隐(V-Blanking)**信息。也就是说,这个信号只告诉你“我现在是不是在消隐期”。也就是:

  • tvdh(高电平):LCD 没有从帧缓存更新内容(处于消隐区)✅ ← 主机可以写数据

  • tvdl(低电平):LCD 正在从帧缓存更新内容(正在刷新)❌ ← 避免写入,防撕裂

其他模式后续再说。

←---------------- 水平方向 ----------------→

| HBP(水平后消隐) | 有效显示像素区 | HFP(水平前消隐) |

模式含义适合用途
Mode 1只含 V-Sync(整帧刷新区间)最基础的防撕裂,同步整帧
Mode 2含 V + H 同步,行和帧都考虑精细同步,适合高帧率动画
Mode 3刷到第 N 行时输出 TE 脉冲(由寄存器设置)自定义同步点,精准控制刷新时机

        

有了上述知识后,我们开始学习CO5300的具体命令。下面这个图就是命令框图,但是是mipi接口

我们用到的是SPI,这个是读取0x3A这个寄存器中显示像素点格式。

这个是读取显示图像的格式。

        为了更好的在ESP32上编写自己的驱动,需要了解一下esp32spi相关函数,这里具体举一下传输函数的例子。

spi_device_queue_trans这个相当于是中断,非阻塞,异步传输

spi_device_transmit这个相比下是中断,阻塞,同步传输

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值