普中stm32开发板tftlcd显示图片_「正点原子STM32Mini板资料连载」第十六章 TFTLCD 显示实验...

1)实验平台:正点原子STM32mini开发板

2)摘自《正点原子STM32 不完全手册(HAL 库版)关注官方微信号公众号,获取更多资料:正点原子

8cd64af0370d1fcbf523d559b78979dc.png

第十六章 TFTLCD 显示实验

上一章我们介绍了 OLED 模块及其显示,但是该模块只能显示单色/双色,不能显示彩色,

而且尺寸也较小。本章我们将介绍 ALIENTEK 2.8 寸 TFT LCD 模块,该模块采用 TFTLCD 面

板,可以显示 16 位色的真彩图片。在本章中,我们将使用 MiniSTM32 开发板上的 LCD 接口,

来点亮 TFTLCD,并实现 ASCII 字符和彩色的显示等功能,并在串口打印 LCD 控制器 ID,同

时在 LCD 上面显示。本章分为如下几个部分:

16.1 TFTLCD 简介

16.2 硬件设计

16.3 软件设计

16.4 下载验证

16.1 TFTLCD 简介

本章我们将通过 STM32 的普通 IO 口模拟 8080 总线来控制 TFTLCD 的显示。

TFT-LCD 即薄膜晶体管液晶显示器。其英文全称为:Thin Film Transistor-Liquid Crystal

Display。TFT-LCD 与无源 TN-LCD、STN-LCD 的简单矩阵不同,它在液晶显示屏的每一个象

素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特

性与扫描线数无关,因此大大提高了图像质量。TFT-LCD 也被叫做真彩液晶显示器。

上一章介绍了 OLED 模块,本章,我们给大家介绍 ALIENTEK TFTLCD 模块,该模块有

如下特点:

1,2.4’/2.8’/3.5’/4.3’/7’ 5 种大小的屏幕可选。

2,320×240 的分辨率(3.5’分辨率为:320*480,4.3’和 7’分辨率为:800*480)。

3,16 位真彩显示。

4,自带触摸屏,可以用来作为控制输入。

本章,我们以 2.8 寸的 ALIENTEK TFTLCD 模块为例介绍,该模块支持 65K 色显示,显示

分辨率为 320×240,接口为 16 位的 80 并口,自带触摸屏。

该模块的外观图如图 16.1.1 所示:

639a556f8e96924d6917bb878bc0a1ac.png

图 16.1.1 ALIENTEK 2.8 寸 TFTLCD 外观图

模块原理图如图 16.1.2 所示:

3c4e1c44fbe95f16e4f52c666a5357b3.png

图 16.1.2 ALIENTEK 2.8 寸 TFTLCD 模块原理图

TFTLCD 模块采用 2*17 的 2.54 公排针与外部连接,接口定义如图 16.1.3 所示:

9f83f9f4cde2d028008ee7c0983c93cf.png

图 16.1.3 ALIENTEK 2.8 寸 TFTLCD 模块接口图

从图 16.1.3 可以看出,ALIENTEK TFTLCD 模块采用 16 位的并方式与外部连接,之所以不采用 8 位的方式,是因为彩屏的数据量比较大,尤其在显示图片的时候,如果用 8 位数据线,

就会比 16 位方式慢一倍以上,我们当然希望速度越快越好,所以我们选择 16 位的接口。图 16.1.3还列出了触摸屏芯片的接口,关于触摸屏本章我们不多介绍,后面的章节会有详细的介绍。该模块的 80 并口有如下一些信号线:

CS:TFTLCD 片选信号。

WR:向 TFTLCD 写入数据。

RD:从 TFTLCD 读取数据。

D[15:0]:16 位双向数据线。

RST:硬复位 TFTLCD。

RS:命令/数据标志(0,读写命令;1,读写数据)。

80 并口在上一节我们已经有详细的介绍了,这里我们就不再介绍,需要说明的是,TFTLCD

模块的 RST 信号线是直接接到 STM32 的复位脚上,并不由软件控制,这样可以省下来一个 IO

口。另外我们还需要一个背光控制线来控制 TFTLCD 的背光。所以,我们总共需要的 IO 口数

目为 21 个。这里还需要注意,我们标注的 DB1~DB8,DB10~DB17,是相对于 LCD 控制 IC 标

注的,实际上大家可以把他们就等同于 D0~D15(按从小到大顺序),这样理解起来简单点。

ALIENTEK 提供 2.8/3.5/4.3/7 寸等不同尺寸的 TFTLCD 模块,其驱动芯片有很多种类型,

比如有:ILI9341/ILI9325/RM68042/RM68021/ILI9320/ILI9328/LGDP4531/LGDP4535/SPFD5408

/SSD1289/1505/B505/C505/NT35310/NT35510/SSD1963 等(具体的型号,大家可以通过下载本章

实验代码,通过串口或者 LCD 显示查看),这里我们仅以 ILI9341 控制器为例进行介绍,其他

的控制基本都类似,我们就不详细阐述了。

ILI9341 液晶控制器自带显存,其显存总大小为 172800(240*320*18/8),即 18 位模式(26

万色)下的显存量。在 16 位模式下,ILI9341 采用 RGB565 格式存储颜色数据,此时 ILI9341

的 18 位数据线与 MCU 的 16 位数据线以及 LCD GRAM 的对应关系如图 16.1.4 所示:

2ea44dac54bf4d4ee63608c934274a13.png

图 16.1.4 16 位数据与显存对应关系图

从图中可以看出,ILI9341 在 16 位模式下面,数据线有用的是:D17~D13 和 D11~D1,D0

和 D12 没有用到,实际上在我们 LCD 模块里面,ILI9341 的 D0 和 D12 压根就没有引出来,这

样,ILI9341 的 D17~D13 和 D11~D1 对应 MCU 的 D15~D0。

这样 MCU 的 16 位数据,最低 5 位代表蓝色,中间 6 位为绿色,最高 5 位为红色。数值越

大,表示该颜色越深。另外,特别注意 ILI9341 所有的指令都是 8 位的(高 8 位无效),且参数

除了读写 GRAM 的时候是 16 位,其他操作参数,都是 8 位的,这个和 ILI9320 等驱动器不一

样,必须加以注意。

接下来,我们介绍一下 ILI9341 的几个重要命令,因为 ILI9341 的命令很多,我们这里就

不全部介绍了,有兴趣的大家可以找到 ILI9341 的 datasheet 看看。里面对这些命令有详细的介

绍。我们将介绍:0XD3,0X36,0X2A,0X2B,0X2C,0X2E 等 6 条指令。

首先来看指令:0XD3,这个是读 ID4 指令,用于读取 LCD 控制器的 ID,该指令如表 16.1.1

所示:

61c76d2232f25809b4bf919a67b12780.png

表 16.1.1 0XD3 指令描述

从上表可以看出,0XD3 指令后面跟了 4 个参数,最后 2 个参数,读出来是 0X93 和 0X41,

刚好是我们控制器 ILI9341 的数字部分,从而,通过该指令,即可判别所用的 LCD 驱动器是什

么型号,这样,我们的代码,就可以根据控制器的型号去执行对应驱动 IC 的初始化代码,从而

兼容不同驱动 IC 的屏,使得一个代码支持多款 LCD。

接下来看指令:0X36,这是存储访问控制指令,可以控制 ILI9341 存储器的读写方向,简

单的说,就是在连续写 GRAM 的时候,可以控制 GRAM 指针的增长方向,从而控制显示方式

(读 GRAM 也是一样)。该指令如表 16.1.2 所示:

a045708eb49dce1958f589a4e6d3c4da.png

表 16.1.2 0X36 指令描述

从上表可以看出,0X36 指令后面,紧跟一个参数,这里我们主要关注:MY、MX、MV

这三个位,通过这三个位的设置,我们可以控制整个 ILI9341 的全部扫描方向,如表 16.1.3 所

示:

b91f677d9753d94a1ca37215523add7b.png

表 16.1.3 MY、MX、MV 设置与 LCD 扫描方向关系表

这样,我们在利用 ILI9341 显示内容的时候,就有很大灵活性了,比如显示 BMP 图片,

BMP 解码数据,就是从图片的左下角开始,慢慢显示到右上角,如果设置 LCD 扫描方向为从

左到右,从下到上,那么我们只需要设置一次坐标,然后就不停的往 LCD 填充颜色数据即可,

这样可以大大提高显示速度。

接下来看指令:0X2A,这是列地址设置指令,在从左到右,从上到下的扫描方式(默认)

下面,该指令用于设置横坐标(x 坐标),该指令如表 16.1.4 所示:

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于正点原子STM32F103ZET6开发,使TFTLCD液晶屏能显示图片的驱动函数的例程,驱动函数定义在`lcd.c`文件中: ``` // lcd.c 文件 #include "lcd.h" void LCD_WriteCommand(uint8_t cmd) { LCD_DC_LOW; LCD_CS_LOW; spi_write(cmd); LCD_CS_HIGH; } void LCD_WriteData(uint8_t data) { LCD_DC_HIGH; LCD_CS_LOW; spi_write(data); LCD_CS_HIGH; } void LCD_Init(void) { // 初始化SPI接口 spi_init(); // 复位LCD LCD_RST_LOW; delay_ms(100); LCD_RST_HIGH; delay_ms(100); // 初始化LCD LCD_WriteCommand(0x01); //软件复位 delay_ms(50); LCD_WriteCommand(0x11); //休眠解除 delay_ms(120); LCD_WriteCommand(0x3A); //设置像素格式 LCD_WriteData(0x55); LCD_WriteCommand(0xC2); //电源控制设置 LCD_WriteData(0x44); LCD_WriteData(0x00); LCD_WriteCommand(0xC5); //VCOM控制设置 LCD_WriteData(0x00); LCD_WriteData(0x00); LCD_WriteCommand(0xE0); //设置Gamma表 LCD_WriteData(0x0F); LCD_WriteData(0x1F); LCD_WriteData(0x1C); LCD_WriteData(0x0C); LCD_WriteData(0x0F); LCD_WriteData(0x08); LCD_WriteData(0x48); LCD_WriteData(0x98); LCD_WriteData(0x37); LCD_WriteData(0x0A); LCD_WriteData(0x13); LCD_WriteData(0x04); LCD_WriteData(0x11); LCD_WriteData(0x0D); LCD_WriteData(0x00); LCD_WriteCommand(0xE1); //设置Gamma表 LCD_WriteData(0x0F); LCD_WriteData(0x32); LCD_WriteData(0x2E); LCD_WriteData(0x0B); LCD_WriteData(0x0D); LCD_WriteData(0x05); LCD_WriteData(0x47); LCD_WriteData(0x75); LCD_WriteData(0x37); LCD_WriteData(0x06); LCD_WriteData(0x10); LCD_WriteData(0x03); LCD_WriteData(0x24); LCD_WriteData(0x20); LCD_WriteData(0x00); LCD_WriteCommand(0x20); //显示开启 LCD_WriteCommand(0x36); //设置扫描方向 LCD_WriteData(0xC8); LCD_WriteCommand(0x2A); //设置X方向坐标 LCD_WriteData(0x00); LCD_WriteData(0x00); LCD_WriteData(0x00); LCD_WriteData(0xEF); LCD_WriteCommand(0x2B); //设置Y方向坐标 LCD_WriteData(0x00); LCD_WriteData(0x00); LCD_WriteData(0x01); LCD_WriteData(0x3F); LCD_WriteCommand(0x29); //显示开始 } void LCD_DrawImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* image_data) { uint32_t size = width * height * 2; LCD_SetWindow(x, y, x + width - 1, y + height - 1); for (uint32_t i = 0; i < size; i += 2) { uint16_t color = (image_data[i] << 8) | image_data[i+1]; LCD_WriteData(color); } } void LCD_SetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { LCD_WriteCommand(0x2A); //设置X方向坐标 LCD_WriteData(x0 >> 8); LCD_WriteData(x0 & 0xFF); LCD_WriteData(x1 >> 8); LCD_WriteData(x1 & 0xFF); LCD_WriteCommand(0x2B); //设置Y方向坐标 LCD_WriteData(y0 >> 8); LCD_WriteData(y0 & 0xFF); LCD_WriteData(y1 >> 8); LCD_WriteData(y1 & 0xFF); LCD_WriteCommand(0x2C); //开始写数据 } ``` 这个例程中,`LCD_Init()`函数用于初始化LCD屏幕,`LCD_DrawImage()`函数用于在指定的位置显示图片,`LCD_SetWindow()`函数用于设置LCD屏幕上的窗口区域。需要注意的是,这里的图片数据是一个二进制数组,需要在主程序中定义好并传入函数中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值