LV10-01-LCD驱动-02-LCD时序分析

来学习一下LCD的时序?若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
PC端开发环境 Windows Windows11
Ubuntu Ubuntu20.04.2的64位版本
VMware® Workstation 17 Pro 17.6.0 build-24238078
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
Win32DiskImager Win32DiskImager v1.0
Linux开发板环境 Linux开发板 正点原子 i.MX6ULL Linux 阿尔法开发板
uboot NXP官方提供的uboot,使用的uboot版本为U-Boot 2019.04
linux内核 linux-4.19.71(NXP官方提供)
点击查看本文参考资料
分类 网址 说明
官方网站 https://www.arm.com/ ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档
https://www.nxp.com.cn/ NXP官方网站
https://www.nxpic.org.cn/NXP 官方社区
https://u-boot.readthedocs.io/en/latest/u-boot官网
https://www.kernel.org/linux内核官网
点击查看相关文件下载
分类 网址 说明
NXP https://github.com/nxp-imx NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库
nxp-imx/linux-imx/releases/tag/v4.19.71 NXP linux内核仓库tags中的v4.19.71
nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0 NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0
I.MX6ULL i.MX 6ULL Applications Processors for Industrial Products I.MX6ULL 芯片手册(datasheet,可以在线查看)
i.MX 6ULL Applications ProcessorReference Manual I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网)
Source Code https://elixir.bootlin.com/linux/latest/source linux kernel源码
kernel/git/stable/linux.git - Linux kernel stable tree linux kernel源码(官网,tag 4.19.71)
https://elixir.bootlin.com/u-boot/latest/source uboot源码

一、我使用的LCD屏

1. 硬件原理图

ALPHA 底板载了 RGB LCD 接口,此部分电路如图 :

image-20250410112827564

RGBLCD 就是 RGB LCD 接口,采用 RGB888 数据格式,并支持触摸屏(支持电阻屏和电容屏)。该接口仅支持 RGB 接口的液晶(不支持 MCU 接口的液晶),目前正点原子的RGB 接口 LCD 模块有: 4.3 寸(ID:4342, 480*272 和 ID:4384, 800*480)、 7 寸(ID:7084, 800*480和 ID:7016, 1024*600)和 10 寸(ID:1018, 1280*800)等尺寸可选。

2. ATK-MD0430R 模块

2.1 模块简介

我使用的是800*480的4.3寸屏:

image-20250410113333002

该模块不带控制器,所以只能用于那些自带显示控制器的 MCU 或者 CPU,比如 ST 的 STM32F4x9, STM32F7x6 和 STM32H7x3等。该模块没显存,所以在使用的时候需要提供外部 RAM 来作为显示屏的显存。模块采用电容触摸屏,支持 5 点同时触摸,具有非常好的操控效果。ATK-MD0430R 模块还提供了背光控制功能。各项参数如下:

项目 说明
接口类型 LCD:并行 24 位 RGB 接口 触摸屏: IIC
颜色格式 RGB888(也可以用 RGB565)
颜色深度 最大 24 位
显存容量 无显存 1
LCD 分辨率 480*272 或 800*480
触摸屏类型 电容触摸
触摸点数 最多 5 点同时触摸
工作温度 -20℃~70℃
存储温度 -30℃~80℃
外形尺寸 68mm*118mm

在使用的时候需要提供外部 RAM 来作为 LCD 的显存!

项目 说明
电源电压 5± 0.5V
IO 口电平 3.3V LVTTL
功耗 ATK-DM0430R-480232: 40~165mA; ATK-DM0430R-800480: 120~320mA

注 1: 3.3V 系统,可以直接接本模块(供电必须 5V),如果是 5V 系统,建议串接 100R 左右电阻,做限流处理。

注 2: 40mA 和 120mA 对应背光关闭时的功耗, 165mA 和 320mA 对应背光最亮时的功耗,此数据是在电源电压为 5V 时测出的,实际应用中功耗会由于电源电压的波动而略微变化。

2.2 引脚说明

模块通过 40P FPC 接口同外部连接,各引脚的详细描述如表 :

序号 名称 说明
1,2 VCC5 5V 电源输入引脚。
3~10 R0~R7 8 位 RED 数据线。
11 GND 地线。
12~19 G0~G7 8 位 GREEN 数据线。
20 GND 地线
21~28 B0~B7 8 位 BLUE 数据线。
29 GND 地线。
30 CLK 像素时钟。
31 HSYNC 水平同步信号。
32 VSYNC 垂直同步信号。
33 DE 数据使能信号。
34 BL 背光控制信号。
35 CS 电容触摸屏复位信号(CT_RST)
36 MOSI 电容触摸屏 IIC_SDA 信号(CT_SDA)
37 MISO NC,电容触摸屏未用到
38 SCK 电容触摸屏 IIC_SCL 信号(CT_SCL)
39 PEN 电容触摸屏中断信号(CT_INT)
40 RESET LCD 复位信号(低电平有效)

从上表可以看出, LCD 控制器总共需要 29 个 IO 口驱动(RGB888 格式),电容触摸屏需要 4 个 IO 口驱动,这样整个模块需要 33 个 IO 口驱动。注意:该模块的数据线 R7、 G7 和 B7 可以用于区分 RGB 屏的类型(可以看做是 ID)。MCU 在初始化 RGB 屏参数之前,先读取 R7/G7/B7 的状态,从而判断 RGB 屏类型,对应关系如表 :

M2(B7) M1(G7) M0(R7) RGBLCD 模块参数
0 0 0 4.3 寸, 480*272 分辨率(RGB)
0 0 1 7 寸, 800*480 分辨率(RGB)
0 1 0 7 寸, 1024*600 分辨率(RGB)
0 1 1 7 寸, 1280*800 分辨率(RGB)
1 0 0 4.3 寸, 800*480 分辨率(RGB)
1 0 1 10.1 寸 1280*800 分辨率(RGB)
X X X 暂时未用到

由表可知,我们可以通过读取 R7/G7/B7 来判断 LCD 的尺寸和分辨率,从而使得 MCU可以在同一个程序里面,兼容不同尺寸和分辨率的 RGB 屏。 从表可知, ATK-MD0430R-480272 屏幕 ID 为 000,而 ATK-MD0430R-800480 屏幕 ID 为 100。

2.3 接口时序表

ATK-MD0430R-800480 模块采用 24 位并行 RGB 接口, 该接口的时序如表 :

image-20250410151200644

fclk、 Tvb、 Tvfp、 Thbp、 Thfp 这五个参数很重要, 在写驱动程序的时候会使用其配置 RGBLCD 的时序。ATK-MD0430R-800480 模块的输入信号特性如表 :

image-20250410151224900

最重要的两个参数就是 Thwh 和 Tvwh,这两个就是 hsw 和 vsw, 在写程序的时候需要用到。

3. 芯片手册

这个模块的裸屏规格书是这个WKS43235。这里有个在线的:4.3寸800480裸屏规格书.pdf-原创力文档(或者看我的仓库:WKS43235_SPEC_V0.0.doc)。规格书里面没有写这个LCD屏幕使用的驱动IC:

image-20250410150118893

不过模块资料里面给了 ST7262的芯片手册,这里有一个在线的芯片手册: ST7262(或者看我的仓库:ST7262)。这个应该是用于驱动裸屏的把。时序也可以在这个芯片手但是册中找到(但是吧,上面的时序相关的表和这个芯片的手册貌似有点对不上,我也不搞不懂了,但是提供的资料里面的裸屏IC驱动芯片的芯片手册就是这个,反正原理都类似)。

二、LCD时序分析

1. 时间参数

先来看一下下面的一张图:

image-20210109154234559

如果将 LCD 显示一帧图像的过程想象成绘画,那么在显示的过程中就是用一根“笔”在不同的像素点画上不同的颜色。这根笔按照从左至右、从上到下的顺序扫描每个像素点,并且在像素画上对应的颜色,当画到最后一个像素点的时候一幅图像就绘制好了。 我们来看一下 LCD 是怎么扫描显示一帧图像的。

1.1 水平同步信号HSYNC

一帧图像也是由一行一行组成的。 HSYNC 是水平同步信号,也叫做行同步信号,当产生此信号的话就表示开始显示新的一行了,所以此信号都是在图的最左边。它表示液晶屏一行像素数据的传输结束,每传输完成液晶屏的一行像素数据时, HSYNC会发生电平跳变,如分辨率为800x480的显示屏(800列,480行),传输一帧的图像HSYNC的电平会跳变480次。

1.2 垂直同步信号VSYNC

VSYNC 信号是垂直同步信号,也叫做帧同步信号,当产生此信号的话就表示开始显示新的一帧图像了 。垂直同步信号VSYNC(Vertical Sync)用于表示液晶屏一帧像素数据的传输结束,每传输完成一帧像素数据时, VSYNC会发生电平跳变。其中“帧”是图像的单位,一幅图像称为一帧,在液晶屏中,一帧指一个完整屏液晶像素点。 我们常常用“帧/秒”来表示液晶屏的刷新特性,即液晶屏每秒可以显示多少帧图像,如液晶屏以60帧/秒的速率运行时, VSYNC每秒钟电平会跳变60次。

1.3 HBP、 HFP、 VBP 和 VFP

接下来看这四个参数。其实上面的那张图不是很明显,我们看下这张:

image-20250410141911816

和上面是一样的,只是,多了一圈“黑边”。真正有效的显示区域是中间的白色部分。那这一圈“黑边”是什么东西呢?这就要从显示器的“祖先” CRT 显示器开始说起了, CRT 显示器就是以前很常见的那种大屁股显示器,在现在应该很少见了,如果在农村有可能应该还是可以见到的。

CRT 显示器屁股后面是个电子枪,这个电子枪就是我们上面说的“画笔”,电子枪打出的电子撞击到屏幕上的荧光物质使其发光。只要控制电子枪从左到右扫完一行(也就是扫描一行),然后从上到下扫描完所有行,这样一帧图像就显示出来了。也就是说,显示一帧图像电子枪是按照‘Z’形在运动,当扫描速度很快的时候看起来就是一幅完成的画面了。

当显示完一行以后会发出 HSYNC 信号,此时电子枪就会关闭,然后迅速的移动到屏幕的左边,当 HSYNC 信号结束以后就可以显示新的一行数据了,电子枪就会重新打开。在 HSYNC信号结束到电子枪重新打开之间会插入一段延时,这段延时就是图中的 HBP

当显示完一行以后就会关闭电子枪等待 HSYNC 信号产生,关闭电子枪到 HSYNC 信号产生之间会插入一段延时,这段延时就是图中的 HFP 信号。

同理,当显示完一帧图像以后电子枪也会关闭,然后等到 VSYNC 信号产生,期间也会加入一段延时,这段延时就是图中的 VFP

VSYNC 信号产生,电子枪移动到左上角,当 VSYNC 信号结束以后电子枪重新打开,中间也会加入一段延时,这段延时就是图中的 VBP

HBP、 HFP、 VBP 和 VFP 就是导致图中黑边的原因,但是这是 CRT 显示器存在黑边的原因,现在是 LCD 显示器,不需要电子枪了,那么为何还会有黑边?这是因为 RGB LCD屏幕内部是有一个 IC 的,发送一行或者一帧数据给 IC, IC 是需要反应时间的。通过这段反应时间可以让 IC 识别到一行数据扫描完了,要换行了,或者一帧图像扫描完了,要开始下一帧图像显示了。因此,在 LCD 屏幕中继续存在 HBP、 HFP、 VPB 和 VFP 这四个参数的主要目的是为了锁定有效的像素数据

这四个时间是 LCD 重要的时间参数,后面编写 LCD 驱动的时候要用到的,至于这四个时间参数具体值是多少,那要需要去查看所使用的 LCD 数据手册了。

1.4 RGB LCD屏幕时序

1.4.1 行显示时序

上面了解了行显示和帧显示,我们来看一下行显示对应的时序图

image-20250410142908317

上图就是 RGB LCD 的行显示时序,我们来分析一下其中重要的几个参数:

  • HSYNC:行同步信号,当此信号有效的话就表示开始显示新的一行数据,查阅所使用的LCD 数据手册可以知道此信号是低电平有效还是高电平有效,假设此时是低电平有效。
  • HSPW: 有些地方也叫做 thp,是 HSYNC 信号宽度,也就是 HSYNC 信号持续时间。 HSYNC信号不是一个脉冲,而是需要持续一段时间才是有效的,单位为 CLK。
  • HBP: 有些地方叫做 thb,前面已经学习过了,术语叫做行同步信号后肩,单位是 CLK。
  • HOZVAL:有些地方叫做 thd,显示一行数据所需的时间,假如屏幕分辨率为 1024*600,那么 HOZVAL 就是 1024,单位为 CLK。
  • HFP:有些地方叫做 thf,前面已经学习过了, 术语叫做行同步信号前肩,单位是 CLK。
  • CLK:同步时钟信号CLK,液晶屏与外部使用同步通讯方式,以CLK信号作为同步时钟,在同步时钟的驱动下,每个时钟传输一个像素点数据。
  • DE:数据使能信号DE(Data Enable)用于表示数据的有效性,当DE信号线为高电平时,RGB信号线表示的数据有效。

当 HSYNC 信号发出以后,需要等待 HSPW+HBP 个 CLK 时间才会接收到真正有效的像素数据。当显示完一行数据以后需要等待 HFP 个 CLK 时间才能发出下一个 HSYNC 信号。

所以显示一行所需要的时间就是: HSPW + HBP + HOZVAL + HFP

1.4.2 帧显示时序 

一帧图像就是由很多个行组成的, RGB LCD 的帧显示时序 :

image-20250410143325033

上图就是RGB LCD 的帧显示时序,我们来分析一下其中重要的几个参数:

  • VSYNC:帧同步信号,当此信号有效的话就表示开始显示新的一帧数据,查阅所使用的LCD 数据手册可以知道此信号是低电平有效还是高电平有效,假设此时是低电平有效。
  • VSPW: 有些地方也叫做 tvp,是 VSYNC 信号宽度,也就是 VSYNC 信号持续时间,单位为 1 行的时间。
  • VBP: 有些地方叫做 tvb,前面已经学习过了,术语叫做帧同步信号后肩,单位为 1 行的时间。
  • LINE: 有些地方叫做 tvd,显示一帧有效数据所需的时间,假如屏幕分辨率为 1024*600,那么 LINE 就是 600 行的时间。
  • VFP: 有些地方叫做 tvf,前面已经学习过了,术语叫做帧同步信号前肩,单位为 1 行的时间。

显示一帧所需要的时间就是: VSPW+VBP+LINE+VFP 个行时间,最终的计算公式:

1
T = (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP)

2. 像素时钟

2.1 怎么计算?

像素时钟就是 RGB LCD 的时钟信号,以 ATK7016 这款屏幕为例:

image-20250410155353414

显示一帧图像所需要的时钟数就是:

1
2
3
4
CLK_NUM = (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP)
= (3 + 20 + 600 + 12) * (20 + 140 + 1024 + 160)
= 635 * 1344
= 853440

显示一帧图像需要853440个时钟数,那么显示60帧就是: 853440 * 60 = 51206400≈51.2M,所以像素时钟就是 51.2MHz。

2.2 时钟怎么来的?

I.MX6U是可以通过eLCDIF来控制LCD, 这个eLCDIF控制器后面再说,想先来看一下eLCDIF 接口时钟图:

image-20250410165527136

①、此部分是一个选择器,用于选择哪个 PLL 可以作为 LCDIF 时钟源,由寄存器CCM_CSCDR2 的位 LCDIF1_PRE_CLK_SEL(bit17:15)来决定, LCDIF1_PRE_CLK_SEL 选择设置如表

时钟源
0 PLL2 作为 LCDIF 的时钟源。
1 PLL3_PFD3 作为 LCDIF 的时钟源。
2 PLL5 作为 LCDIF 的时钟源。
3 PLL2_PFD0 作为 LCDIF 的时钟源。
4 PLL2_PFD1 作为 LCDIF 的时钟源。
5 PLL3_PFD1 作为 LCDIF 的时钟源。

②、 此部分是 LCDIF 时钟的预分频器,由寄存器 CCM_CSCDR2 的位 LCDIF1_PRED 来决定预分频值。 可设置值为 07,分别对应 18 分频。

③、 此部分进一步分频,由寄存器 CBCMR 的位 LCDIF1_PODF 来决定分频值。 可设置值为 07,分别对应 18 分频。

④、此部分是一个选择器,选择 LCDIF 最终的根时钟,由寄存器 CSCDR2 的位LCDIF1_CLK_SEL 决定, LCDIF1_CLK_SEL 选择设置如表所示:

时钟源
0 前面复用器出来的时钟,也就是前面 PLL5 出来的时钟作为 LCDIF 的根时钟。
1 ipp_di0_clk 作为 LCDIF 的根时钟。
2 ipp_di1_clk 作为 LCDIF 的根时钟。
3 ldb_di0_clk 作为 LCDIF 的根时钟。
4 ldb_di1_clk 作为 LCDIF 的根时钟。

里肯定选择 PLL5 出来的那一路时钟作为 LCDIF 的根时钟,因此 LCDIF1_CLK_SEL 设置为 0。 LCDIF 既然选择了 PLL5 作为时钟源,那么还需要初始化 PLL5, LCDIF 的时钟是由PLL5 和图 24.1.1.8 中的②、③这两个分频值决定的,所以需要对这三个进行合理的设置以搭配出所需的时钟值,我们就以 ATK7016 屏幕所需的 51.2MHz 为例,看看如何进行配置。

PLL5 频率设置涉及到四个寄存器: CCM_PLL_VIDEO、 CCM_PLL_VIDEO_NUM、CCM_PLL_VIDEO_DENOM 、 CCM_MISC2 。 其 中 CCM_PLL_VIDEO_NUM 和CCM_PLL_VIDEO_DENOM 这两个寄存器是用于小数分频的,我们这里为了简单不使用小数分频,因此这两个寄存器设置为 0。

PLL5 的时钟计算公式如下:

1
PLL5_CLK = OSC24M * (loopDivider + (denominator / numerator)) / postDivider

不使用小数分频的话 PLL5 时钟计算公式就可以简化为 :

1
PLL5_CLK = OSC24M * loopDivider / postDivider

OSC24M 就是 24MHz 的有源晶振,现在的问题就是设置 loopDivider 和 postDivider。先来看一下寄存器 CCM_PLL_VIDEO,此寄存器结构如图:

image-20250410165950626

寄存器 CCM_PLL_VIDEO 用到的重要的位如下:

  • POST_DIV_SLECT(bit20:19): 此位和寄存器 CCM_ANALOG_CCMSC2 的 VIDEO_DIV 位共同决定了 postDivider,为 0 的话是 4 分频,为 1 的话是 2 分频,为 2 的话是 1 分频。本章设置为 2,也就是 1 分频。
  • ENABLE(bit13): PLL5(PLL_VIDEO)使能位,为 1 的话使能 PLL5,为 0 的话关闭 PLL5。
  • DIV_SELECT(bit6:0): loopDivider 值,范围为 27~54,这里需要设置为 32。寄存器 CCM_ANALOG_MISC2 的位 VIDEO_DIV(bit31:30)与寄存器 CCM_PLL_VIDEO 的位 POST_DIV_SLECT(bit20:19)共同决定了 postDivider,通过这两个的配合可以获得 2、 4、 8、16 分频。

这里将 VIDEO_DIV 设置为 0,也就是 1 分频,因此 postDivider 就是 1, loopDivider设置为 32, PLL5 的时钟频率就是:

1
2
3
PLL5_CLK = OSC24M * loopDivider / postDivider
= 24M * 32 / 1
= 768MHz。

PLL5 此时为 768MHz,在经过图中的②和③进一步分频,设置②中为 3 分频,也就是寄存器 CCM_CSCDR2 的位 LCDIF1_PRED(bit14:12)为 2。设置③中为 5 分频,就是寄存器CCM_CBCMR 的位 LCDIF1_PODF(bit25:23)为 4。设置好以后最终进入到 LCDIF 的时钟频率就是: 768/3/5 =51.2MHz,这就是我们需要的像素时钟频率。

3. LCD时序参数总结

如下图所示(左右两张图中HSYNC和VSYNC有效电平是可配置的,具体看手册,高低都有可能,左右两张图对比参考):

image-20250411111347791

时序 时间参数 其他名称 参数说明
行显示 HSYNC
(Horizontal Sync)
- 行同步信号,一行像素数据的传输结束
HSW
(horizontal sync width)
HSPW、thp HSYNC 信号宽度,就是水平同步信号的宽度,单位为同步时钟CLK的个数
HBP
(horizontal back porch)
thb 表示从水平同步信号开始到一行的有效数据开始之间的CLK的个数(在 HSYNC 信号结束到电子枪重新打开之间插入的一段延时)
HOZVAL thd 显示一行数据所需的时间,假如屏幕分辨率为 1024*600,那么 HOZVAL 就是 1024,单位为 CLK。
HFP
(horizontal front porth)
thf 表示一行的有效数据结束到下一个水平同步信号开始之间的CLK的个数(显示完一行以后就会关闭电子枪等待 HSYNC 信号产生,关闭电子枪到 HSYNC 信号产生之间插入的一段延时)。
帧显示 VSYNC
(Vertical Sync)
- 帧同步信号,一帧像素数据的传输结束
VSW
(vertical sync width)
VSPW、tvp VSYNC 信号宽度,就是垂直同步信号的宽度,单位为 1 行的时间
VBP
(vertical back porch)
tvb 表示在一帧图像开始时,垂直同步信号以后的无效的行数,单位为 1 行的时间。(VSYNC 信号产生,电子枪移动到左上角,VSYNC 信号结束以后电子枪重新打开,中间加入的一段延时)
LINE tvd 显示一帧有效数据所需的时间,假如屏幕分辨率为 1024*600,那么 LINE 就是 600 行的时间。
VFP
(vertical front porch)
tvf 表示在一帧图像结束后,垂直同步信号以前的无效的行数(当显示完一帧图像以后电子枪也会关闭,然后等到 VSYNC 信号产生,期间也会加入的一段延时)。