LCD液晶屏驱动详解

  • 开发环境
    • 开发板:JZ2440V3
    • CPU:samsunS3C2440
    • 内核:Linux3.4.2
    • 编译工具:arm-linux-gcc 4.3.2
    • LCD:4.3存液晶屏AT043TN24
  • 参考文献
    • LCD驱动程序详细讲解(一)_weixin_33935505的博客-CSDN博客
    • LCD驱动详解 – Lilto – 博客园 (cnblogs.com)
    • 主题:s3c2440移植linux-3.4.2中的LCD驱动_大白菜的博客-CSDN博客
    • 【第2期】韦东山嵌入式Linux之第2期_驱动大全 (100ask.net)

1、LCD种类、电路连接及显示原理

LCD,即液晶显示器,是一种采用了液晶控制透光技术来实现色彩的显示器。LCD有很多种类型,比如STN、TFT、LTPS、OLED等。各有优缺点。JZ2440V3开发板上面配置的是TFT类型液晶显示器,也是目前最为主流的液晶显示器。

  • TFT-LCD的数据传输方式有2种:

    单扫:对于一整屏的数据,从上到下,从左到右,一个一个地发送出来。

    双扫:将一整屏的数据分为上下两部分,同时的从上到下,从左到右,一个一个的发送出来。

  • LCD的信 种类:

信 名称 描述
VSYNC 垂直同步信
HSYNC 水平同步信
VD[23:0] 数据信
HCLK 时钟信
LEND 行结束信
PWREN 电源开关信
  • 电路模块图

  • LCD控制器原理图

  • 显示原理

我们除了配置一些寄存器告诉LCD控制器图像中像素的格式(RGB565),frameBuffer的首地址之类外,对于TFT LCD的访问还需要用到一些信 ,所以需要通过配置寄存器来告诉LCD控制器这些信 的信息(比如何时发出控制信 ,发出信 的持续时间等),举个例子: 向LCD驱动器发送图片数据时需要时钟控制(VCLK),一个时钟发送一个像素点,那么控制器就需要主动发出时钟信 ,这个时钟是由哪个引脚发出的,发出的频率是多少,这个都是要配置寄存器的, 我们通过时序图来分析需要用到的一些信 以及如何去配置它们,如果是第一次了解LCD控制,直接看时序还是比较困难的,所以先给出一个形象的比喻 :

frame buffer: 显存,用于存放LCD显示数据;frame buffer通过LCD控制器和LCD Panel建立一一映射关系;

LCD控制器: 参考LCD用户手册,配置LCD控制器,用于发出LCD控制信 ,驱动LCD显示;

扫描方式: 如图所示,由start到end的扫描方向是:从左到右,从上到下(扫描方向的一种);

HSYNC: 行同步信 ,用于行切换,一行扫描结束,需要扫描新行时,需要先发送行同步信 ;

VSYNC: 列同步信 ,用于列切换,一帧扫描结束,需要扫描新的一帧时,需要先发送列同步信 ;

时钟信 : 每来一个时钟,扫描的点移位一;

上图中LD驱动器可以比喻成电子枪,LCD控制器就是控制这个电子枪的,它从显示缓存中拿像素数据传给电子枪并发送命令让电子枪发射像素颜色, 上图中,成像过程

  1. LCD控制器发出VSYNC信 ,告诉电子枪,要发出一张新帧了,然后电子枪把枪头调转到LCD屏幕的左上角准备开始发射像素
  2. 发出VSYNC信 的同时,发出HSYNC信 (告诉电子枪新行开始, 从左向右动发射子弹吧)但是电子枪毕竟反应比较慢,过了少许开始发射子弹
    对于上面两个过程,由于电子枪接受了VSYNC信 ,调转枪头后,需要反应一段时间才能正常开始工作, 所以就白白扫射了几行的无效数据,相当于经过了几个HSYNC信 周期的时间, 一个HSYNC周期就是电子枪扫射一行的时间(从HSYNC信 开始扫射第一行直到到一行结束扫射结束所用时间),就出现了上方无效区
  3. 当第一行结束时,LCD控制器又发出HSYNC信 , 电子枪枪头扭转到下一行新行开始发射数据, 但是枪头扭转的比较慢, 所以出现了左右的无效区(即第一行结束后,电子枪由于硬件原因要反应一段时间, 所以在右边出现了无效数据区, 调转枪头后, 也得反应一段时间开始发射子弹,所以出现了左边的无效区),有人会问电子枪如何知道第一行何时结束(其实是我们通过寄存器告诉LCD控制器第一行有多少个数据的,我们的屏幕分辨率是480*272, 即这个信息会设置到寄存器里), 当一行结束时,LCD控制器就不会再发有效像素数据,并且等待电子枪游离一段时间,之后再发下一行的HSYNC信 .
  4. loop第三个过程
  5. 当扫描到最后一行结束时(一帧即将结束),LCD控制器就不会再发有效像素数据,并且等待电子枪游离一段时间,所以会继续往下扫描,出现了下方的无效区, 之后再发下一行的VSYNC信 , 之后回到过程1开始重复。

在工作中的显示器上,可以在四周看见黑色的边框。上方的黑框是因为当发出VSYNC信 时,需要经过若干行之后第一行数据才有效;下方的黑框是因为显示完所有行的数据时,显示器还没有扫描到最下边(VSYNC信 还没有发出),这时数据是无效的;左边的黑框是因为当发出HSYNC信 时,需要经过若干像素之后第一列数据才有效;右边的黑框是因为显示完一行数据时,显示器还没扫描到最右边(HSYNC信 还没有发出),这时数据已经无效。显示器只会依据VSYNC、HSYNC信 来取得、显示数据,并不理会该数据是否有效,何时发出有效的数据由显卡或LCD控制器决定。

VSYNC信 出现的频率表示一秒钟内能显示多少帧图像,称为垂直频率或场频率,这就是我们常说的“显示器频率”;HSYNC信 出现的频率称为水平频率,表示一秒钟能显示多少个像素的数据。
显示器上,一帧数据的存放位置与VSYNC、HSYNC信 的关系如下图所示:

有效数据的行数、列数,即分辨率,它与VSYNC、HSYNC信 之间的距离等,都是可以设置的,这由LCD控制器来完成。

  • 数据组织方式

一幅图像被称为一帧(frame),每帧由多行组成,每行由多个像素组成,每个像素的颜色使用若干位的数据来表示。对于单色显示器,每个像素使用1位来表示,称为1BPP;对于256色显示器,每个像素使用8位来表示,被称为8BPP。

显示器上每个像素的颜色由3部分组成:红(Red)、绿(Green)、蓝(Blue)。它们被称为三基色,这三者的混合几乎可以表示人眼所能识别的所有颜色。比如可以根据颜色的浓烈程度将三基色都分为256个级别,则可以使用255级的红色、255级的绿色、255级的蓝色组合成白色,可以使用0级红色、0级的绿色、0级的蓝色组合成黑色。

LCD控制器可以支持单色(1BPP)、4级灰度(2BPP)、16级灰度(4BPP)、256色(8BPP)的调色板显示模式,支持64K(16BPP)和16M(24BPP)非调色板显示模式。下面介绍64K(16BPP)色显示模式下,图像数据的存储格式。

64K(16BPP)色的显示模式就是使用16位的数据来表示一个像素的颜色。这16位数据的格式又分为两种:5:6:5、5:5:5:1,前者使用高5位来表示红色,中间的6位来表示绿色,低5位来表示蓝色;后者的高15从高到低分成3个5位来表示红、绿、蓝色,最低位来表示透明度。5:5:5:1的格式也被称为RGBA格式(A:Alpha,表示透明度)。

一个4字节可以表示两个16BPP的像素,使用高2字节还是低2字节来表示第一个像素,这也是可以选择的。显示模式为16BPP时,内存数据与像素位置的关系如下:

  1. 当BSWP=0、HWSWP=0时,内存中像素的排列格式:
地址 D[31:16] D[15:0]
00H P1 P2
04H P3 P4
08H P5 P6
  1. 当BSWP=0、HWSWP=1时,内存中像素的排列格式:
地址 D[31:16] D[15:0]
00H P2 P1
04H P4 P3
08H P6 P5
  1. 像素在LCD屏上的排列

  1. 像素色值与VD[23:0]引脚的对应关系
VD 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
RED 4 3 2 1 0 NC NC NC NC NC NC NC NC
GREEN 5 4 3 2 1 0
BLUE 4 3 2 1 0
  • 输出方式

    • 1、通过frame buffer显示(最典型的方式)

    • 2、通过临时调色板显示

    这里要解释几点:

    1. 什么叫临时调色板
      我们根据2440 用户手册的一句话:this register value will be video data at next frame.(在下一帧显示寄存器的值, tips:一帧就一个图像)
      可知:临时调色板是一个寄存器,我们向此寄存器写入颜色,那么LCD屏幕下一次显示图像就会是此寄存器中记录的颜色, 即起到了刷屏的作用(整个屏幕都是一个颜色)
    2. 什么时候起作用以及用途
      当使能此寄存器时, 临时调色板起作用, 这时之前配置的功能(如:通过frame buffer显示)就会无效, 因为使能,LCD屏幕会被迅速刷屏,达到了快速刷屏的目的(不需要通过SDRAM中向frameBuffer中所有元素赋值同一个值来实现刷屏 tips:使用SDRAM,本来就慢),如果要恢复之前的配置功能, 即disable临时调色板功能即可

    • 3、通过调色板显示

上图中, 调色板在控制器内部(注意区别临时调色板)是一块儿内存,首地址为0x4D00400, 一共有256个2字节大小(每两个字节表示一个颜色), 上图中,通过配置寄存器告诉LCD控制器调色板的显示格式为RGB565,之后需要手动将此调色板赋值,比如图00H的位置赋值为”黄色”,之后对于framebuffer来讲,其中的每一项代表一个调色板中的索引, 比如frameBuffer的第一项的值为0,则硬件就会自动找调色板中的第一项值, 即将0xFFE0输出, LCD第一个像素点显示黄色
还有一个问题,如何使能调色板功能呢我们上面介绍”通过frame buffer显示”中提到,配置寄存器显示模式为16BPP,显示方式是5:6:5,那么控制器就会认为frame buffer中的每一个元素代表的就是颜色的值,并且显示方式是5:6:5, 但是如果我们配置显示模式为8BPP,显示方式是5:6:5, LCD控制器就自动认为用的调色板模式,且调色板中颜色的显示方式为(5:6:5)(这里的8Bpp,代表frame buffer中的每个元素都是8位2进制表示,每个元素的值是调色板中的索引值),那么调色板的应用场合是什么样呢们引用 上的一个说明(稍微修改下):

  • TFT-LCD的时序

每个VSYNC信 表示一帧数据的开始;每个HSYNC信 表示一行数据的开始,无论这些数据是否有效;每个VCLK信 表示正在传输一个像素的数据,无论它是否有效。数据是否有效只是对CPU的LCD控制器来说的,LCD根据VSYNC、HSYNC、VCLK不停的读取总线数据并显示。

上图中的时序图,分为两个部分,上面部分是一帧的时序图,下面部分是一行的时序图我们分析下时序图中每个参数的意义(上图中的①->⑩) :

  1. 对应于上述的过程1,2, VSYNC信 (代表一帧的开始)需要持续一段时间②(VSPW+1), 电子枪认为收到了VSYNC信 (即白扫射了VSPW+1行,也可以说白扫射了(VSPW+1)个HSYNC周期时间),收到信 后,还要继续持续时间③(VBPD+1), LCD控制器才开始发送有效数据, 从而电子枪发射有效像素, 即(② + ③)为LCD屏幕上边的无效区, 对于①参数, 这是手册上的数据, 即告我们默认LCD控制器发送HSYNC信 为高电平,但实际LCD接受HSYNC硬件上有可能设计成低电平有效, 所以可以对寄存器进行修改, 让LCD控制器发出HSYNC控制信 为低电平

    tips: VSPW VBPD参数会根据datasheet来具体设置(下文会提到), 设置这些参数的目的是告诉LCD控制器电子枪的反应时间以便发送帧数据(比如电子枪, 发送HSYNC后, 得知道电子枪的反应时间后才开始传送有效数据)

  2. ④为, 即有效数据为(LINEVAL+1)行,我们分辨率为480*272,所以LINEVAL为271 *

  3. ⑤VFPD+1参数对应于过程5, 当扫描到最后一行结束时(即一帧结束了),LCD控制器不会再发送有效像素数据, 此时电子枪会收游离一段时间(会继续往下白扫好几行(VFPD+1行)无效数据), 这个时间需要告诉LCD控制器,以便控制器知道等待多长时间在发送VSYNC信 ,从而进行下一帧的开始

  4. 对于⑥、⑦、⑧、⑩三个参数,对应于上述过程3, 接受到HSYNC信 (表示一行的开始)后,此信 必须持续一段时间⑦(HSPW+1个VCLK周期)后, 电子枪才认为信 有效,接受到HSYNC信 后,电子枪还要反应一段时间⑧(白白扫射HBPD+1个VCLK周期后,也可以说发射HBPD+1个无效像素点)后, LCD控制器才开始传送有效数据给电子枪, 当一行扫描结束后,即LCD控制器不发射有效数据了,此时电子枪要游离一段时间⑩(HFPB+1), 这段时间需要告诉LCD控制器,以便让LCD控制器等待此段时间后在发送HSYNC信 从而进行下一行的扫描, 对于⑨参数来说, 分辨率为480*272,所以HOZVAL = 479, 即一行有480个有效数据, 注意有效数据的开始时机, 即需要经历(⑦、⑧)时间后,LCD控制器才开始发送有效数据 。

参数计算

根据LCDdatasheet确认上述参数的值, 下图为AT043TN24数据手册的时序图, 我们很容易对应上面2440手册中LCD的时序图中的参数

上图中已经标注对应关系,就不细说了,强调一点, VSYNC与HSYNC信 都是低电平有效,但是2440手册中LCD时序是高电平有效,所以在配置寄存器时需要注意,要将这两个VSYNC,HSYNC信 设置成低电平有效(极性反转: 默认为高电平,反转后为低电平)

我们可以看到,上图中左边是具体的参数值,Min(最小值), Typ.(典型值), Max(最大值),我们举个例子,在右图中,我们知道关系 VSPW+1 = tvp, 我们在左图中发现tvp的典型值为10, 单位是H(Hsync), 所以VSPW+1 = 10==> VSPW=9, 其余参数的取值都能通过上述方法确定, 还有个问题,VSPW, VSPD,VFBD的时间都依赖于HSYNC周期时间,那么HSYNC周期时间如何确认呢查看了下寄存器的设置中好像也没找到相关设置,最后在2440手册中找到这句话

其实意思就是说 LCD控制器会根据电子枪发射像素点的个数来确认HSYNC时间的,比如我们LCD屏幕分辨率是480*272, 当发出VSYNC信 后,要经过VSPW+1反应时间,即VSPW+1个HSYNC周期,我们假设VSPW+1的值为10,那么就是10个HSYNC周期,也就是电子枪扫描了10 x 480个像素点后,LCD控制器就认为经历了10个HSYNC周期时间 。

1、VCLK(Hz) = HCLK/[(CLKVAL+1)*2]

2、VSYNC =1/[ {(VSPW+1)+(VBPD+1)+(LIINEVAL+1)+(VFPD+1)} x {(HSPW+1)+(HBPD+1)+(HFPD+1)+(HOZVAL+1)} x {2x (CLKVAL+1) / (HCLK )} ]

3、HSYNC = 1/[{(HSPW+1)+(HBPD+1)+(HFPD+1)+(HOZVAL+1)} x {2x (CLKVAL+1) / (HCLK )}]

将VSYNC、HSYNC、VCLK等信 的时间参数设置好之后,并将帧内存的地址告诉LCD控制器,它即可自动地发出DMA传输从帧内存中得到图像数据,最终在上述信 的控制下出现在数据总线VD[23:0]上。用户只需要把要显示的图像数据写入帧内存中。

2、LCD控制器REGBANK寄存器组介绍

LCD控制器中REGBANK的17个寄存器可以分为6种,如下表所示:

对于TFT-LCD,一般情况下只需要设置前两种寄存器,即LCDCON和LCDSADDR

名称 说明
LCDCON1~LCDCON5 用于选择LCD类型,设置各类控制信 的时间特性等
LCDSADDR1~LCDSADDR5 用于设置帧内存的地址
TPAL 临时调色板寄存器,可以快速的输出一帧单色的图像
LCDINTPND 用于LCD的中断,在一般应用中无需中断
LCDSRCPND 用于LCD的中断,在一般应用中无需中断
LCDINTMSK 用于LCD的中断,在一般应用中无需中断
REDLUT 专用于STN-LCD
GREENLUT 专用于STN-LCD
BLUELUT 专用于STN-LCD
DITHMODE 专用于STN-LCD
TCONSEL 专用于SEC TFT-LCD

2.1、LCD控制寄存器LCDCON1

主要用于选择LCD类型、设置像素时钟、使能LCD信 的输出等,格式如下表所示:

功能 说明
LINECNT [27:18] 只读,每输出一个有效行其值减一,从LINEVAL减到0;
CLKVAL [17:8] 用于设置VCLK(像素时钟);
MMODE [7] 设置VM信 的反转效率,专用于STN-LCD;
PNRMODE [6:5] 设置LCD类型,对于TFT-LCD设置0b11;
BPPMODE [4:1] 设置BPP,对于TFT-LCD:0b1100 = 16BPP;
ENVID [0] LCD信 输出使能位,0:禁止,1:使能;

2.2、LCD控制寄存器LCDCON2

用于设置垂直方向各信 的时间参数,格式如下表所示:

功能 说明
VBPD [31:24] VSYNC信 脉冲之后,还要经过(VBPD+1)个HSYNC信 周期,有效的行数据才出现;
LINEVAL [23:14] LCD的垂直宽度,(LINEVAL+1)行;
VFPD [13:6] 一帧中的有效数据完结后,到下一个VSYNC信 有效前的无效行数目:VFPD+1行;
VSPW [5:0] 表示VSYNC信 的脉冲宽度位(VSPW+1)个HSYNC信 周期,即(VSPW+1)行,这个(VSPW+1)行的数据是无效的;

2.3、LCD控制寄存器LCDCON3

用于设置水平方向各信 的时间参数,格式如下表所示:

功能 说明
HBPD [25:19] HSYNC信 脉冲之后,还要经过(HBPD+1)个VCLK信 周期,有效的像素数据才出现;
HOZVAL [18:8] LCD的水平宽度,(HOZVAL+1)类(像素);
HFPD [7:0] 一行中的有效数据完结后,到下一个HSYNC信 有效前的无效像素个数,HFPD+1个像素;

2.4、LCD控制寄存器LCDCON4

对于TFT-LCD,这个寄存器只用来设置HSYNC信 的脉冲宽度,位[7:0]的数值称为HSPW,表示脉冲宽度位(HSPW+1)个VCLK周期。

2.5、LCD控制寄存器LCDCON5

用于设置各个控制信 的极性,并可从中读到一些状态信息,格式如下表所示:

功能 说明
VSTATUS [16:15] 只读,垂直状态;00:正处于VSYNC信 脉冲期间;01:正处于VSYNC信 结束到行有效之间;10:正处于有效行期间;11:正处于行有效结束到下一个VSYNC信 之间;
HSTATUS [14:13] 只读,水平状态;00:正处于HSYNC信 脉冲期间;01:正处于HSYNC信 结束到像素有效之间;01:正处于像素有效期间;11:正处于像素有效结束到下一个HSYNC信 之间;
BPP24BL [12] 设置TFT-LCD的显示模式为24BPP时,一个4字节中的哪3个字节有效,0:LSB有效,1:MSB有效(高地址的3个字节);
FRM565 [11] 设置TFT-LCD的显示模式为16BPP时,使用的数据格式,0表示5:5:5:1格式,1表示5:6:5格式;
INVVCLK [10] 设置VCLK信 有效沿极性:0表示在VCLK的下降沿读取数据;1表示在VCLK的上升沿读取数据;
INVVLINE [9] 设置VINE/HSYNC脉冲的极性;0表示正常极性,1表示反转的极性;
INVVFRAME [8] 设置VFRAME/VSYNC脉冲的极性;0表示正常极性,1表示反转的极性;
INVVD [7] 设置VD数据线表示数据的极性;0表示正常极性,1表示反转的极性;
INVVDEN [6] 设置VDEN信 的极性;0表示正常进行,1表示反转的极性;
INVPWREN [5] 设置PWREN信 的极性;0表示正常进行,1表示反转的极性;
INVLEND [4] 设置LEND信 的极性;0表示正常进行,1表示反转的极性;
PWREN [3] LCD_PWREN信 输出使能;0表示禁止,1表示使能;
ENLEND [2] LEND信 输出使能;0表示禁止,1表示使能;
BSWP [1] 字节交换使能;0表示禁止,1表示使能;
HWSWP [0] 半字(2字节)交换使能,0表示禁止,1表示使能;

2.6、帧内存地址寄存器LCDSDRR1~LCDSDRR3

帧内存可以很大,而真正要显示的区域被称为视口(view point),它处于帧内存之内,这个3个寄存器用于确定帧内存的起始地址,定位视口在帧内存中的位置。

下图给出了帧内存和视口的位置关系:

下面分别介绍各个帧内存寄存器;

  • LCDSADRR1寄存器格式
功能 说明
LCDBANK [29:21] 用于保存帧内存起始地址A[30:22],帧内存起始地址必须为4MB对齐;
LCDBASEU [20:0] 对于TFT-LCD,用于保存视口所对应的内存起始地址A[21:1],这块内存也被称为LCD的帧缓冲区(frame buffer);

  • LCDSADRR2寄存器格式
功能 说明
LCDBASEL [20:0] 对于TFT-LCD,用来保存LCD的帧缓冲区结束地址A[21:1],其值可如下计算:LCDBASEL=LCDBASEU+(PAGEWIDTH+OFFSIZE)*(LINEVAL+1)

注意:可以修改LCDBASEU、LCDBASEL的值来实现图像的移动,不过不能在一帧图像的结束阶段进行修改;

  • LCDSADRR3寄存器格式
功能 说明
OFFSIZE [21:11] 表示上一行最后一个数据与下一行第一个数据之间地址差值的半字节,即以半字位单位的地址差;0表示两行数据是紧接着的,1表示它们之间相差2个字节,以此类推;
PAGEWIDTH [10:0] 视口的宽度,以半字位为单位;

3、调色板

  • 临时调色板寄存器TPAL

如果要输出一帧单色的图像,可以在TPAL寄存器中设定这个颜色值,然后使能TPAL寄存器,这种方法可以避免修改整个调色板或帧缓冲区。

TPAL寄存器格式:

功能 说明
TPALEN [24] 调色板寄存器使能位,0禁止,1使能;
TPALVAL [23:0] 颜色值;TPALVAL[23:16]:红色TPALVAL[15:8]:绿色TPALVAL[7:0]:蓝色

注意:临时调色板寄存器TPAL可以用在任何显示模式下,并非只能用在8BPP模式下。

4、编写驱动

4.1 lcd.c

  • 搭建整体框架

可参考内核自带的相关lcd驱动(drivers/video/),添加头文件:


  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include
  11. #include
  12. #include
  13. #include
  14. #include
  15. #include
  16. #include
  17. #include
  18. #include
  19. #include
  20. #include
  21. #include
  22. #include
  23. #include
  24. #include
  25. static struct fb_info *s3c_lcd;
  26. static int lcd_init(void)
  27. {
  28. /

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年8月17日
下一篇 2022年8月17日

相关推荐