您所在的位置: 首页 显示器知识

LCD屏幕

热度:100 ℃ 日期:2024-11-19 09:52:18

在嵌入式开发行业,屏幕的开发是必不可少的,最常见的屏幕就是TFT_LCD屏幕,也就是常说的液晶显示屏,当然还有IPS屏和OLED屏,这些都是生活中常见的一些屏幕类型。咱们就以最常见的LCD屏幕来讲一下STM32驱动LCD屏幕的原理。这里采用2.8寸的电容触摸屏为例。

LCD屏幕的成像原理

LCD屏幕一般由背光灯、偏光片、液晶层、滤光片等基本部分组成,所以这也决定了LCD屏幕无法做的其他材质的屏幕一样薄。屏幕的每个像素点都由对应的液晶控制背光是否导通,从而显示各种各样的图案。

TFT LCD薄膜液晶屏显示原理,直观动画,一目了然,科学,科普,好看视频 (baidu.com)

屏幕的结构

一个完整的LCD屏幕除了上述的基础物理显示部分之外,还包含有相应的驱动芯片来负责控制屏幕进行内容的显示,显示的内容存储在对应的显存中,不同的驱动芯片显存不一样,显存越大芯片就越贵。这里我们采用的是ILI9341这款驱动芯片,支持240*320分辨率的屏幕。

从硬件接口,通信方式去学习LCD屏幕

颜色深度:26万色2^18

RGB565:红色数据5位,绿色5位,蓝色5位 红色: 1111 1000 0000 0000

屏幕的驱动接口

接口分类

常见接口有MCU接口,RGB接口和VSYNC接口三种模式。

MCU接口模式:

使用屏幕自带驱动芯片内部自带的内存,MCU先将数据写入到驱动IC自带GRAM,然后再显示到屏幕上。

优点:驱动简单,不需要时钟和同步信号

缺点:由于自带显存,成本高,耗费GRAM,很难做到较大屏幕上

RGB接口模式:

大屏采用较多的接口,屏幕不带显存,需要MCU准备充足的显存空间(因为RGB565,480*272分辨率的屏幕就需要显存230*240*2=168KB,一般的MCU都没有这么大的RAM,所以要加外置的SRAM或SDRAM),对于RGB接口的屏幕,主机输出的直接是每个象素的RGB数据,不需要进行变换(GAMMA校正等除外),对于这种接口,需要在主机部分有个LCD控制器,以产生RGB数据和点、行、帧同步信号。

优点:RGB屏数据不写入显存,直接写屏,读写速度更快

缺点:耗费单片机内存,一般单片机主频较低,不能驱动更大的屏幕,适用于高性能单片机

VSYNC接口模式:

该模式其实就是在MCU模式上加了一个VSYNC信号,应用于运动画面更新,这样就与上述两个接口有很大的区别。该模式支持直接进行动画显示的功能,它提供了一个对MCU接口最小的改动,实现动画显示的解决方案。

在这种模式下,内部的显示操作与外部VSYNC信号同步。可以实现比内部操作更高的速率的动画显示。但由于其操作方式的不同,该模式对速率有一个限制,那就是对内部SRAM的写速率一定要大于显示读内部SRAM的速率。

MCU接口模式下的8080并行接口

对于STM32F1系列的单片机来说,自身主频为72Mhz,性能相对来说较低,所以在驱动屏幕的时候一般选择MCU接口模式,并且为了提高屏幕的刷新速度,常采用8080并行接口的方式驱动。在这里我们就着重来讲一下MCU模式下的8080接口。

屏幕的接口选择由驱动芯片决定:

对于ILI9341驱动芯片来说,接口的选择由IM[3:0]这4个引脚决定,一般在硬件工程师设计电路板时就已经规定好,其具体的接口模式和引脚关系如下:

本次使用的为8080-I接口,8080-Ⅰ和8080-Ⅱ两种接口在屏幕的引脚的选用上有所不同,通讯时序上基本一致。接下来我们就来看一下8080对应的通讯时序。

对于8080时序,在这里我们需要注意的有以下几个时间,这几个时间是保证我们的MCU和屏幕能够顺利通信的核心,太短可能无法通信,太长会导致屏幕刷新变慢。

  1. 地址建立时间Tast:RS(数据命令选择线)变化开始,WR/RD变化 之间的时间
  2. 数据建立时间Tdst:WR/RD(写使能/读使能)变为低电平之后,到WR/RD变为高电平之间的时间(用户/LCD屏来修改总线的状态)
  3. 数据保持时间Tdht:当WR/RD由低变高时,LCD屏读取总线的状态(数据),这段时间称为数据保持时间。

STM32驱动LCD屏幕

对于STM32F1系列来说,芯片一般没有8080接口,如果使用IO口来模拟8080时序,由于引脚较多,会导致模拟起来比较复杂。所以我们一般使用FSMC(灵活静态存储器控制器)来模拟8080时序。

FSMC灵活存储器控制器

FSMC在控制存储器时分为两类一个是NOR存储器控制器另一个是NAND/PC卡存储器控制器,两块功能公用一个地址信号和数据引号以及读写使能信号。控制信号互相独立,所以FSMC在控制多个外部存储器时在同一时间只能和一个设备通信。

NOR存储和NAND存储器两者之间的操作方式不同NOR存储器,NAND存储器和NOR存储器在读取内容时都可以随机读取任意字节,但那是在写入时NOR存储器可以随机写入一个字节,NAND存储器的写以page 为单位。

FSMC管理的空间

FSMC一共管理了1G地址空间,这1G地址空间由分为了4个块区,BANK1用看来管理NOR/PSRAM类型的存储器。在BANK1内部又细分为了四个扇区,每个扇区64M的空间。这里要注意的是FSMC中每一个地址,对应的是存储器中的一个字节。Bank1的256M字节空间由28(2^28/1024/1024)根地址线(ADDR[27:0])寻址。这里ADDR 是内部AHB地址总线,其中ADDR[25:0]对应外部存储器地址FSMC_A[25:0],而HADDR[26:27]对4个区进行寻址。

FSMC在操作时存储器是支持不同位宽的数据,也就是说,写入数据可以是8位、16位、32位。也就是默认情况下存储器地址数据为8位,可以正常读取,但是如果存储器地址数据为16位,32位,就是两个字节一个地址,四个字节一个地址,那么控制16位,32位宽度的存储设备,且不支持单字节访问就比较麻烦了。比如16位宽度的NOR Flash,写入仅支持16位或者32位(通过写入两次16位),写入8位数据是不支持的 。这样的话,我们本来对应64M的字节地址,就变成了32M的双字节地址,也就是最后一位无效了,因为地址一次要加2。

为了方便操作,FSMC在硬件设计上就提供了一种解决办法,将内部数据总线ADDR[25:0]措位后接到FMC_A地址引脚上,“丢弃”地址的bit-0,从bit-1开始对地址计数(相当于只计算偶数地址,总共有32M个地址)FSMC在实际输出地址时,将地址的值右移一位(相当于除以2,变成了偶数地址),输出到实际的地址线上。

FSMC的工作模式: 外设支持输出多种不同的时序以便于控制不同的存储器, 综合了 SRAM/ROM、PSRAM 和 NOR Flash 产品的信号特点,定义了 ABCD 四种不同的异步时序模型。选用不同的时序模型时,需要设置不同的时序参数

模式A支持独立的读写时序控制,这个对我们驱动TFTLCD来说非常有用,因为 TFTLCD在读的时候,一般比较慢,而在写的时候可以比较快,如果读写用一样的时序,那么只能以读 的时序为基准,从而导致写的速度变慢,或者在读数据的时候,重新配置 FSMC的延时,在读操作完成的时候,再配置回写的时序,这样虽然也不会降低写的速度,但是频繁配置,比较麻 烦。而如果有独立的读写时序控制,那么我们只要初始化的时候配置好,之后就不用再配置, 既可以满足速度要求,又不需要频繁改配置。

FSMC驱动SRAM的过程

在驱动外部SRAM时我们需要将地址线、数据线、控制线按照要求连接到对应的存储芯片上,在使用外部存储时,通过地址线来确定要写入数据的位置,通过数据来讲数据写入对应的地址。

涉及到的引脚有ADDR[18:0]18个引脚,数据线DATA[15:0],16个引脚,以及控制信号,写信号(WE)、读信号(OE)、片选信号(CS)。

为什么可以用FSMC来驱动LCD屏幕

对于FSMC来操作LCD屏幕首先我们可以从硬件连接上来看,对于屏幕的引脚,我们可以在FSMC控制器里找到对应的引脚与之一一对应。TFTLCD就是用的FSMC_NE4做片选,其实就是将TFTLCD当成SRAM来控制。在控制SRAM时,一般有:地址线(如A0~A18)、数据线(如D0~D15)、写信号(WE)、读信号(OE)、片选信号(CS)。LCD屏幕在控制时包括:RS、D0~D15、WR、RD、CS、RST和BL等,其中真正在操作LCD的时候需要用到的就只有:RS、D0~D15、WR、RD和CS。其操作时序和SRAM的控制完全类似,唯一不同就是TFTLCD有RS信号,但是没有地址信号。所以我么们选取地址信号中的一个作为RS信号。然后我们只需要配置FSMC的时序和LCD屏幕时序一致即可。我们在像屏幕写入时据时和SRAM不同的就是我们不需要考虑地址了,只需要写入数据就行了,使用地址线的目的就是用来区分你发的数据是命令还是数据。

关键代码分析

在代码中我们定义了一个结构体用来区分写入的数据时指令还是数据。我们在硬件连接时将屏幕的数据命令选择线连接到了FSMC地址线的A10引脚上。所以我们需要控制A10是0 还是1来区分数据和命令。

具体分析:

屏幕选用的是FSMC的BANK1的NE4扇区,对应的起始地址:0x6C00 0000

如果想要地址线A10可控,我们需要找一个适当的数也就是偏移地址:0x0000 07FE

转换为二进制就是:

我们会发现此时的第10位数也就是说地址线A10为1,但是由于我们的屏幕数据是RGB565格式是16位的数据,所以我们需要将地址线向右偏移1位,然后就变成了如下所示的情况:

此时对应的A10地址线为0。然后我们只需要地址线上加2,正好是两个8字节数据16为数,结果就可以将地址线A10由0变为了1。就实现了数据命令的选择。

然后我们将BANK1的扇区4基地址,或上偏移地址得到的结果就是我们LCD屏幕的基地址,这个地址并没有实际意义,其目的只是为了让我们方便操作数据命令选择线A10,然后我们通过一个结构体(结构体地址连续)实现数据自行加2操作。

LCD_REG的地址就是0x6C00 07FE 此时A10 在偏移之后为0,表示命令

LCD_RAM的地址就是0x6C00 0800 此时A10在偏移之后为1,表示命令

我们向这两个地址写数据,FSMC就会自动将数据通过数据线发送出去。

写:

*(uint32_t *)0x6C00 07FE=VAL LCD->LCD_REG =VAL

读:

VAL=*(uint32_t *)0x6C00 07FE VAL=LCD->LCD_REG

思考问题?如果地址线是A9应该怎么设置偏移量

ILI9341驱动芯片

在操作ILI9341时,常用的指令有以下几个:

读取驱动ID指令:0XD3

设置屏幕显示列地址指令:0X2A

设置屏幕显示行地址:0X2B

向屏幕显存写入数据指令:0X2C

设置屏幕显示方向指令:0X36

显示方向控制:

LCD屏幕的初始化流程:

代码移植