前言
之前的STM32博客学习了从0新建工程,C语言知识复习,总线时钟等基础知识,现在根据手册开始正式的开发项目,本篇博客主要是理解文档中的TFTLCD部分的学习
学习资料来自:STM32F407最小系统板开发指南-库函数版本_V1.1.pdf
正点原子,感谢原子哥的开源奉献
正点原子资料下载中心
硬件:
STM32F407ZGT6
2.8 LCD MODULE
一个摄像头
注意:
共分为3篇:
如果仅仅想要实现,可以直接去看最后一篇的使用,前边的基础知识可以跳过
STM32单片机学习资料均来自 正点原子 ,仅用于学习,如有侵权请联系我删除
本博客内容原创,创作不易,转载请注明
本文链接
个人博客:https://ronglin.fun/?p=102
PDF链接:见博客网站
CSDN: https://blog.csdn.net/RongLin02/article/details/121445952
基础知识
TFT-LCD 即薄膜晶体管液晶显示器。该模块有如下特点:
- 320×240 的分辨率
- 16 位真彩显示。
- 自带触摸屏,可以用来作为控制输入。
本章,我们以 2.8 寸(其他 3.5 寸/4.3 寸等 LCD 方法类似,请参考 2.8 的即可)的 ALIENTEK TFTLCD 模块为例介绍,该模块支持 65K 色显示,显示分辨率为 320×240,接口为 16 位的 80并口,自带触摸屏。
原理图如下:
ALIENTEK TFTLCD 模块采用 16 位的并方式与外部连接(DB1–DB16)
同时还有其信号线功能如下:
- CS:TFTLCD 片选信号。
- WR:向 TFTLCD 写入数据。
- RD:从 TFTLCD 读取数据。
- D[15:0]:16 位双向数据线。
- RST:硬复位 TFTLCD。
- RS:命令/数据标志(0,读写命令;1,读写数据)
8080并口
8080 并口方式知识补充:
首先先介绍一下模块的 8080 并行接口,8080 并行接口的发明者是 INTEL,该总线也被广泛应用于各类液晶显示器,这种接口,使得 MCU 可以快速的访问模块数据。
模块的 8080 并口读/写的过程为:
先根据要写入/读取的数据的类型,设置 DC 为高(数据)/低(命令),然后拉低片选,选中 SSD1306,接着我们根据是读数据,还是要写数据置 RD/WR为低,然后:
在 RD 的上升沿, 使数据锁存到数据线(D[7:0])上;
在 WR 的上升沿,使数据写入到 SSD1306 里面;
时序图如下:
注意:
在 8080 方式下读数据操作的时候,我们有时候(例如读显存的时候)需要一个假读命(Dummy Read),以使得微控制器的操作频率和显存的操作频率相匹配。在读取真正的数据之前,由一个的假读的过程。这里的假读,其实就是第一个读到的字节丢弃不要,从第二个开始,才是我们真正要读的数据。
同时连接方式还有 4 线串行(SPI)方式 等,不再介绍。
显存说明
需要说明的是,TFTLCD模块的 RST 信号线是直接接到 STM32F4 的复位脚上,并不由软件控制,这样可以省下来一个IO 口。
另外我们还需要一个背光控制线来控制 TFTLCD 的背光。所以,我们总共需要的 IO 口数目为 21 个。这里还需要注意,我们标注的 DB1-DB8,DB10-DB17,是相对于 LCD 控制 IC标注的,实际上大家可以把他们就等同于 D0~D15,这样理解起来就比较简单一点。
不同尺寸的 TFTLCD 模块,其驱动芯片有很多种类型,这里我们仅以 ILI9341 控制器为例进行介绍,其他
的控制基本都类似,我们就不详细阐述了。
ILI9341 液晶控制器自带显存,其显存总大小为 172800(240*320*18/8)
,即 18 位模式(26万色)下的显存量。
在 16 位模式下,ILI9341 采用 RGB565 格式存储颜色数据,此时 ILI9341的 18 位数据线与 MCU 的 16 位数据线以及 LCD GRAM 的对应关系如图
在9341中18位,其中D12和D0没用用上,也就是说,一个色彩的显示,是16位。
在 MCU 的 16 位数据中,最低 5 位代表蓝色,中间 6 位为绿色,最高 5 位为红色。
数值越大,表示该颜色越深。
指令
指令有点像C语言中的函数调用,当读取的时候,输入指令,模块会返回参数,当写入的时候,输入指令,后边跟着参数就可以将数据写入
注意 ILI9341 所有的指令都是 8 位的(高 8 位无效),且参数除了读写 GRAM (色彩数据) 的时候是 16 位,其他操作参数,都是 8 位的。
这个和 ILI9320 等驱动器不一样,必须加以注意。
接下来,我们介绍一下 ILI9341 的几个重要命令,因为 ILI9341 的命令很多,我们这里就不全部介绍了,有兴趣的大家可以找到 ILI9341 的 datasheet 看看。里面对这些命令有详细的介绍。介绍:0XD3,0X36,0X2A,0X2B,0X2C,0X2E
等 6 条指令。
0XD3
0XD3,这个是读 ID4 指令,用于读取 LCD 控制器的 ID,指令功能如图:
从上表可以看出,0XD3 指令后面跟了 4 个参数,最后 2 个参数,读出来是 0X93 和 0X41,刚好是我们控制器 ILI9341 的数字部分,从而,通过该指令,即可判别所用的 LCD 驱动器是什么型号,这样,我们的代码,就可以根据控制器的型号去执行对应驱动 IC 的初始化代码,从而兼容不同驱动 IC 的屏,使得一个代码支持多款 LCD。
参考一下网上的代码:
u16 ILI9341_Read_id(void)
{
u16 id;
LCD_CMD=0xD3; //9341读ID命令
id=LCD_DATA;
id=LCD_DATA; //0x00
id=LCD_DATA; //0x93
id<<=8;
id|=LCD_DATA; //0x41
return id;
}
0X36
0X36,这是存储访问控制指令,可以控制 ILI9341 存储器的读写方向,简单的说,就是在连续写 GRAM 的时候,可以控制 GRAM 指针的增长方向,从而控制显示方式(读 GRAM 也是一样)。该指令如图:
在0X36 指令后面,紧跟一个参数,这里我们主要关注:MY、MX、MV
这三个位,也就是D7 D6 D5
,通过这三个位的设置,我们可以控制整个ILI9341 的全部扫描方向,如表
MY | MX | MV | LCD 扫描方向(GRAM 自增方式) |
---|---|---|---|
0 | 0 | 0 | 从左到右,从上到下 |
1 | 0 | 0 | 从左到右,从下到上 |
0 | 1 | 0 | 从右到左,从上到下 |
1 | 1 | 0 | 从右到左,从下到上 |
0 | 0 | 1 | 从上到下,从左到右 |
0 | 1 | 1 | 从上到下,从右到左 |
1 | 0 | 1 | 从下到上,从左到右 |
1 | 1 | 1 | 从下到上,从右到左 |
这样,我们就可以控制ILI9341的显示方向了,比如显示 BMP 图片,BMP 解码数据,就是从图片的左下角开始,慢慢显示到右上角,如果设置 LCD 扫描方向为从左到右,从下到上,那么我们只需要设置一次坐标,然后就不停的往 LCD 填充颜色数据即可,这样可以大大提高显示速度。
0X2A
0X2A,这是列地址设置指令,在从左到右,从上到下的扫描方式(默认)下面,该指令用于设置横坐标(x 坐标),该指令如表 16.1.1.4 所示:
在默认扫描方式时,该指令用于设置 x 坐标,该指令带有 4 个参数,实际上是 2 个坐标值:SC 和 EC,即列地址的起始值和结束值,SC 必须小于等于 EC,且 0≤SC/EC≤239
。
一般在设置 x 坐标的时候,我们只需要带 2 个参数即可,也就是设置 SC 即可,因为如果 EC 没有变化,我们只需要设置一次即可(在初始化 ILI9341 的时候设置),从而提高速度。
0X2B
0X2B,是页地址设置指令,在从左到右,从上到下的扫描方式(默认)下面,该指令用于设置纵坐标(y 坐标)。该指令如表 16.1.1.5 所示:
在默认扫描方式时,该指令用于设置 y 坐标,该指令带有 4 个参数,实际上是 2 个坐标值:SP 和 EP,即页地址的起始值和结束值,SP 必须小于等于 EP,且 0≤SP/EP≤319
。
一般在设置y 坐标的时候,我们只需要带 2 个参数即可,也就是设置 SP 即可,因为如果 EP 没有变化,我们只需要设置一次即可(在初始化 ILI9341 的时候设置),从而提高速度。
0X2C
0X2C,该指令是写 GRAM 指令,在发送该指令之后,我们便可以往 LCD的 GRAM 里面写入颜色数据了,该指令支持连续写,指令描述如表 16.1.1.6 所示:
从上表可知,在收到指令 0X2C 之后,数据有效位宽变为 16 位,这16位代表的色彩含义见上边的显存说明,我们可以连续写入 LCD GRAM 值,而 GRAM 的地址将根据 MY/MX/MV
设置的扫描方向进行自增。
例如:假设设置的是从左到右,从上到下的扫描方式,那么设置好起始坐标(通过 SC,SP 设置)后,每写入一个颜色值,GRAM 地址将会自动自增 1(SC++),如果碰到 EC,则回到 SC,同时 SP++,一直到坐标:EC,EP 结束,其间无需再次设置的坐标,从而大大提高写入速度。
0X2E
0X2E,该指令是读 GRAM 指令,用于读取 ILI9341 的显存(GRAM),该指令在 ILI9341 的数据手册上面的描述是有误的,真实的输出情况如表 16.1.1.7 所示:
该指令用于读取 GRAM,如表 16.1.1.7 所示,ILI9341 在收到该指令后,第一次输出的是dummy 数据,也就是无效的数据,第二次开始,读取到的才是有效的 GRAM 数据(从坐标:SC,SP 开始),输出规律为:每个颜色分量占 8 个位,一次输出 2 个颜色分量。
比如:第一次输出是 R1G1,随后的规律为:B1R2 G2B2 R3G3 B3R4 G4B4 R5G5… 以此类推。如果我们只需要读取一个点的颜色值,那么只需要接收到参数 3 即可,如果要连续读取(利用 GRAM地址自增,方法同上),那么就按照上述规律去接收颜色数据。
以上,就是操作 ILI9341 常用的几个指令,通过这几个指令,我们便可以很好的控制 ILI9341显示我们所要显示的内容了。
使用流程
任何 LCD,使用流程都可以简单的用以上流程图表示。
其中硬复位和初始化序列,只需要执行一次即可。
画点流程是:设置坐标 ->写 GRAM 指令 -> 写入颜色数据
,然后在 LCD 上面,我们就可以看到对应的点显示我们写入的颜色了。
读点流程为:设置坐标 ->读 GRAM 指令 -> 读取颜色数据
,这样就可以获取到对应点的颜色数据了。
以上只是最简单的操作,也是最常用的操作,有了这些操作,一般就可以正常使用 TFTLCD了。
接下来我们将该模块用来来显示字符和数字,通过以上介绍,我们可以得出 TFTLCD 显示
步骤
需要的相关设置步骤如下:
- 设置 STM32F4 与 TFTLCD 模块相连接的 IO
这一步,先将我们与 TFTLCD 模块相连的 IO 口进行初始化,以便驱动 LCD。这里用到的是 FSMC,FSMC详解在下部分。 - 初始化 TFTLCD 模块
即上图中的初始化序列,初始化序列,就是向 LCD 控制器写入一系列的设置值(比如伽马校准),这些初始化序列一般 LCD 供应商会提供给客户,我们直接使用这些序列即可,不需要深入研究。在初始化之后,LCD 才可以正常使用。 - 通过函数将字符和数字显示到 TFTLCD 模块上
这一步则通过上图左侧的流程,即:设置坐标 -> 写 GRAM 指令 -> 写 GRAM
来实现,但是这个步骤,只是一个点的处理,我们要显示字符/数字,就必须要多次使用这个步骤,从而达到显示字符/数字的目的,所以需要设计一个函数来实现数字/字符的显示,之后调用该函数,就可以实现数字/字符的显示了。
总结
这一部分主要介绍TFTLCD的基础知识,下一篇介绍FSMC,最后就是代码部分,未完待续,=w=