2)摘自《正点原子STM32F4 开拓指南(HAL 库版》关注官方微旗子暗记"大众年夜众号,获取更多资料:正点原子
第二十五章 TFTLCD 显示实验

前几章的实例均没有涉及到液晶显示,这一章我们将向大家先容 1.3 寸 TFTLCD 显示屏模块。该显示屏不像 OLED 模块只能显示单色/双色,不能显示彩色,而这款 TFTLCD 可以显示16 位色的真彩图片,同时在上一章中学习了 SPI,在本章中,我们将通过 SPI 来驱动点亮 TFTLCD显示屏,并实现 ASCII 字符(12/16/24/32 号字体)、图片和彩色显示等功能,本章将分为如下

几个部分进行讲解:
25.1 TFTLCD 先容
25.2 硬件设计
25.3 实验准备
25.4 实验验证
25.1 TFTLCD 简介
TFT-LCD 即薄膜晶体液晶显示器。其英文全称为:Thin Film Transistor-Liquid Crystal Display。TFT-LCD 与无源 TN-LCD、STN-LCD 的大略矩阵不同,它在液晶显示屏的每一个像素上都设置有一个薄膜晶体管(TFT),可有效地战胜非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。TFT-LCD 也被叫做真彩液晶显示器。
1.3’TFTLCD 模块紧张有以下特点:
1、屏幕尺寸为 1.3 寸
2、分辨率为:240240
3、支持 16 位真彩色显示
这里要提醒大家的是,该模块反面 5.0V 接口兼容,以是请大家在利用的时候一定要小心,别直接接到 5V 的系统上去,否则可能烧坏模块。该模块的外不雅观图如图 25.1.1 所示:
图 25.1.1 ALIENTEK 1.3’ TFTLCD 模块外不雅观图
ATK-1.3’TFTLCD 模块通过 8(24)个引脚同外部连接,对外接口事理图如图 25.1.2 所示:
图 25.1.2 模块对外接口事理图
对应引脚功能详细描述如表 25.1.3 所示:
表 25.1.3 ATK-1.3’TFTLCD 模块引脚解释
特殊把稳:模块出厂是默认选择四线 SPI,例子是利用四线 SPI 进行通信的。
ATK-1.3’TFTLCD 在四线 SPI 通讯模式下 ,最少须要四线就可以 与 LCD 通讯:
CS/SCL/SDA/WR(DC),该模块出厂默认利用四线 SPI 通讯,也便是默认焊接 R7 和 R10 电阻。
四线 SPI 接口时序如图 25.1.4 所示:
图 25.1.4 四线 SPI 接口时序图
图中各个韶光参数见表 25.1.5 所示:
表 25.1.5 四线 SPI 韶光参数
从表中可以看出,模块的写周期是非常快的,写周期为:16ns,而模块的读周期相对较慢,
读周期为:150ns。
LCD 四线 SPI 的详细读写时序,请看 ST7789V2 数据手册第 56 页和 60 页。
模块采取 ST7789V2 作为 LCD 驱动器,显示数据可以直接存储在 24032018 位片上的
RAM 中,它可以在没用外部操作时钟的情形下实行显示数据 RAM 读/写操作,以最小化功耗。
该驱动芯片采取 SPI 接口与外部连接,须要利用的旗子暗记线如下:
CS:LCD 的片选旗子暗记线
SCK:SPI 的时钟旗子暗记线
SDA:SPI 的数据旗子暗记线
WR(RC):命令/数据标志(0:写命令:1:写数据)
除了以上旗子暗记,我们一样平常还须要用到这 2 个旗子暗记:RESET 和 PWR,个中:RST 是 LCD 的
硬复位脚,低电平有效,用于复位 ST7789V2 芯片,实现液晶的复位,在每次初始化之前,我
们强烈建议大家先实行硬复位,再做初始化。而 PWR 则是 LCD 的背光掌握引脚,高电平有效,
这个引脚自带了下拉电阻,以是如果这个引脚悬空,背光是不会亮的。必须接高电平背光才会
亮,其余可以用 PWM 掌握 PWR 脚,从而掌握背光的亮度。
ST7789V2 自带 LCD RAM(2403203 字节),并且最高支持 18 位颜色深度(262K 色),
不过我们一样平常利用 16 位颜色深度(65K 色),RGB565 格式,这样可以在 16 位模式下达到最
快的速率。在 16 位模式下,ST7789V2 采取 RGB565 格式存储颜色数据,此时 MCU 的 16 位数
据与 LCD RAM 的对应关系如图 25.1.6 所示:
图 25.1.6. 16 位数据与 LCD RAM 的对应关系
图示 MCU 的 16 位数据中,最低 5 位代表蓝色,中间 6 位绿色,最高 5 位为赤色,数值越
大,表示该颜色越深。
接下来,就来先容一下 ST7789V2 的几条主要指令,由于该芯片的命令有很多,我们这里
就不全部先容了,有兴趣的可以找数据手册看看,里面对命令有详细先容。
首先来看一下指令:0x36,这是存储访问掌握指令,可以掌握 ST7789V2 存储器的读写方
向,大略的来说,便是在连续写 LCD RAM 数据的时候,可以掌握 RAM 指针的增长方向,从
而掌握显示办法(读操作也是一样)。该指令如图 26.1.7 所示:
图 26.1.7 0x36 指令描述
从上图可以看出。0x36 指令下可以配置 6 个参数,这里我们紧张关心:MY、MX 和 MV
这 3 位,通过这三个位的设置,我们可以掌握全体 ST7789V2 的全部扫描方向。如表 26.1.8 所
示:
表 26.1.8 MX、MY、MV 设置与 LCD 扫描方向关系表
这样,我们在利用 ST7789V2 显示内容的时候,就有很大灵巧性了,比如显示 BMP 图片,
BMP 数码数据,便是丛图片的左下角开始,逐步显示到右上角,如果设置 LCD 扫描办法(默
认)下面,该指令用于设置横坐标(x 坐标),该指令如图 26.1.9 所示:
图 26.1.9 0x2A 指令描述
这里指令用于 x 坐标,x 坐标有两个坐标值:XS 和 XE(XS 和 XE 都是 16 位的,由 2 个 8
位组成),即列地址的起始值和结束值,当“MV=0”时,0<XS<XE<239,当“MV=1”时,
0<XS<XE<319。
一样平常 TFTLCD 模块的利用流程如图 26.1.10 所示:
图 26.1.10 TFTLCD 利用流程
任何 LCD,利用流程都可以大略的用以上流程图表示。个中硬复位和初始化序列,只须要
实行一次即可。而画点流程便是:坐标->写 GRAM 指令->写入颜色数据,然后在 LCD 上面,
我们就可以看到对应的点显示我们写入的颜色了。读点流程为:设置坐标->读 GRAM 指令->
读取颜色数据,这样就可以获取对应的颜色数据了。
25.2 硬件设计
本实验功能简介:开机时先初始化 LCD,然后开始显斧正点原子 LOGO,12/16/24/32 号字
体等信息,同时利用 LED 灯来指示程序正在运行。
本章须要用到的硬件资源如下:
1、指示灯 LED
2、1.3’TFTLCD 模块
3、NANO STM32F4 开拓板
ATK-1.3’TFFLCD 模块与 NANO STM32F4 开拓板对应的关系如下:
25.3 软件设计
本实验我们利用四线 SPI 来驱动 ATK-1.3’TFTLCD 模块,以是我们通过 WR(DC)旗子暗记线
来掌握是发送命令还是发送数据到 LCD。代码如下所示:
/
@brief
写命令到 LCD
@param
cmd
须要发送的命令
@return void
/
static void LCD_Write_Cmd(u8 cmd)
{
LCD_WR = 0;
LCD_SPI_Send(&cmd, 1);
}
/
@brief
写数据到 LCD
@param
cmd
须要发送的数据
@return void
/
static void LCD_Write_Data(u8 data)
{
LCD_WR = 1;
LCD_SPI_Send(&data, 1);
}
LCD 的 SPI 通讯时序大家可以通过 ST7789V2 数据手册进行学习,这里就不多先容了。
下面我们来重点关注一下上面我们提到的 0x36 指令(存储访问掌握指令,即 RAM 指针增
长方向),这里只粘贴了部分代码。
/ Memory Data Access Control /
LCD_Write_Cmd(0x36);
LCD_Write_Data(0x00);
从以上代码可以看到,LCD 的 RAM 指令增长方向被设置成了从左到右,从上到下的办法,
这个办法决定了字库取模办法和图片显示等问题。如果方向设置的好,我们只须要将字库和图
片数据一直的往 LCD 添补就好了,就可以大大提高显示速率。
下面我们就来看看画点函数,该函数的实当代码如下:
/
设置数据写入 LCD 缓存区域
@param
x1,y1
出发点坐标
@param
x2,y2
终点坐标
@return void
/
void LCD_Address_Set(u16 x1, u16 y1, u16 x2, u16 y2)
{
LCD_Write_Cmd(0x2a);
LCD_Write_Data(x1 >> 8);
LCD_Write_Data(x1);
LCD_Write_Data(x2 >> 8);
LCD_Write_Data(x2);
LCD_Write_Cmd(0x2b);
LCD_Write_Data(y1 >> 8);
LCD_Write_Data(y1);
LCD_Write_Data(y2 >> 8);
LCD_Write_Data(y2);
LCD_Write_Cmd(0x2C);
}
/
@brief
写半个字的数据到 LCD
@param
cmd
须要发送的数据
@return void
/
void LCD_Write_HalfWord(const u16 da)
{
u8 data[2] = {0};
data[0] = da >> 8;
data[1] = da;
LCD_WR = 1;
LCD_SPI_Send(data, 2);
}
/
画点函数
@param
x,y
画点坐标
@return void
/
void LCD_Draw_Point(u16 x, u16 y)
{
LCD_Address_Set(x, y, x, y);
LCD_Write_HalfWord(POINT_COLOR);
}
该函数实现比较大略,便是先设置了坐标,然后往坐标写颜色数据。个中 POINT_COLOR
是我们定义的一个全局变量,用于存放画笔颜色,顺便先容一下其余一个全局变量
BACK_COLOR,该变量代表 LCD 的背景颜色。LCD_Draw_Point 函数虽然大略,但是至关重
要,其他函数都可以调用这个函数实现。在例程源码中,为了提高显示速率,很少用到画点函
数来实现上层函数功能,由于画点函数的效率有点低。但是可以供到大家学习利用。
由于 ATK-1.3’TFTLCD 模块是 SPI 通讯接口的,在速率上肯定会比不上那些利用 8080 等
并口的 TFTLCD 显示屏,为了提高显示速率,增加了一个 LCD 缓存,以提高显示效果,这个
缓存会影响清屏函数 LCD_Clear、添补函数 LCD_Fill 和画线函数 LCD_DrawLine,修正缓存大
小时,请把稳!
!
!
//LCD 缓存大小设置,修正此值时请把稳!
!
!
!
修正这两个值时可能会影响以下函数
LCD_Clear/LCD_Fill/LCD_DrawLine
#define LCD_TOTAL_BUF_SIZE(2402402)
#define LCD_Buf_Size 1152
static u8 lcd_buf[LCD_Buf_Size];
末了就来看一下字符显示函数 LCD_ShowChar,该函数可以显示 12/16/24/32 号字体,如果
大家须要其他字体的话可以直接修正这个函数。特殊要把稳字符取模方向!
/
@brief
显示一个 ASCII 码字符
@param
x,y
显示起始坐标
@param
chr
须要显示的字符
@param
size 字体大小(支持 16/24/32 号字体)
@return void
/
void LCD_ShowChar(u16 x, u16 y, char chr, u8 size)
{
u8 temp, t1, t;
u8 csize;
//得到字体一个字符对应点阵集所占的字节数
u16 colortemp;
u8 sta;
chr = chr - ' '; //得到偏移后的值(ASCII 字库是从空格开始取模,以是-' '便是对应字符
的字库)
if((x > (LCD_Width - size / 2)) || (y > (LCD_Height - size)))
return;
LCD_Address_Set(x, y, x + size / 2 - 1, y + size - 1);//(x,y,x+8-1,y+16-1)
if((size == 16) || (size == 32) )
//16 和 32 号字体
{
csize = (size / 8 + ((size % 8) ? 1 : 0)) (size / 2);
for(t = 0; t < csize; t++)
{
if(size == 16)temp = asc2_1608[chr][t];//调用 1608 字体
else if(size == 32)temp = asc2_3216[chr][t]; //调用 3216 字体
else return;
//没有的字库
for(t1 = 0; t1 < 8; t1++)
{
if(temp & 0x80) colortemp = POINT_COLOR;
else colortemp = BACK_COLOR;
LCD_Write_HalfWord(colortemp);
temp <<= 1;
}
}
}
else if (size == 12)
//12 号字体
{
csize = (size / 8 + ((size % 8) ? 1 : 0)) (size / 2);
for(t = 0; t < csize; t++)
{
temp = asc2_1206[chr][t];
for(t1 = 0; t1 < 6; t1++)
{
if(temp & 0x80) colortemp = POINT_COLOR;
else colortemp = BACK_COLOR;
LCD_Write_HalfWord(colortemp);
temp <<= 1;
}
}
}
else if(size == 24)
//24 号字体
{
csize = (size 16) / 8;
for(t = 0; t < csize; t++)
{
temp = asc2_2412[chr][t];
if(t % 2 == 0)sta = 8;
else sta = 4;
for(t1 = 0; t1 < sta; t1++)
{
if(temp & 0x80) colortemp = POINT_COLOR;
else colortemp = BACK_COLOR;
LCD_Write_HalfWord(colortemp);
temp <<= 1;
}
}
}
}
关于 LCD 的驱动代码问题就讲到这里,我们的源码中还供应了画矩形、画圆、显示数字和
显示图片等等函数,大家可以直接对照源码进行学习。
25.4 下载验证
代码编译成功后,直接下载代码到我们的 NANO STM32F4 开拓板上,然后将 ATK-1.3’
TFTLCD 模块连接到开拓板上的引脚就可以测试模块的显示效果了。如图 25.4.1 所示:
图 25.4.1 LCD 显示效果






