41.1 初学者重要提示
学习本章节前,务必优先学习第40章,需要对LTDC的基础知识和HAL库的几个常用API有个认识。
本章的第4小节LCD驱动设计非常重要。
如果自己观察的话,LCD上电会有一个瞬间高亮的问题,在此贴进行了描述:http://www.armbbs.cn/forum.php?mod=viewthread&tid=82619 。这个解决方案已经应用到本章配套的例子上。
本章节用到的汉字方案会在下章专门为大家讲解,下面是小字库的制作方法:http://www.armbbs.cn/forum.php?mod=viewthread&tid=202 。
调试状态或者刚下载LCD的程序到里面,屏幕会抖动,这个是正常现象,之前F429就有这个问题,详情看此贴:http://www.armbbs.cn/forum.php?mod=viewthread&tid=16892 。
41.2 LCD相关的基础知识
41.2.1 显示屏相关知识
显示屏的结构有必要给大家普及下,这里我们通过如下三种类型的显示屏进行说明,基本已经涵盖我们常用的方式了。
RA8875 + RGB接口裸屏
首先RA8875是一个显示屏控制器,自带显存,它的作用就是让不支持RGB接口的MCU也可以使用RGB接口的大屏。这起到了一个桥接的作用,可以将RGB接口屏转换成8080总线接口、SPI接口或者I2C接口方式。这种情况下,甚至低速的51单片机都可以外接大屏了。另外像SSD1963也是同样的作用。
ili9488类显示屏
这种类型是把显示控制器和显示屏都集成好了,支持8080总线接口,有些还支持SPI或者I2C接口,而且显存也都集成了,不过主要是驱动一些小屏。像ili9341,ili9326,SPFD5420等也是一样的。此外还要注意,部分这种类型显示屏也是支持RGB接口的,像ST官方的STM32F429探索板外接的ili9431就是用的RGB接口。
STM32F429 + SDRAM + RGB接口裸屏
这个是我们本章节要讲解的,STM32F429是自带LCD控制器的,再配合SDRAM作为显示屏的显存,整体作用跟RA8875是一样的,可以直接外接RGB接口的屏了。
有了这些认识后,对于裸屏还有些知识点需要了解。首先,裸屏本身不是什么控制芯片都没有,其构成也是比较复杂的,有兴趣了解的话,可以搜索关键字“TFT结构”进行学习。其次,TFT裸屏中主要的两个IC是Gate Driver IC和Source Driver IC,这两个IC的引脚都超级多,基本都是几百个引脚。最后,不管使用的哪种裸屏,一般都有规格书,会给出时序参数,这个在配置STM32H7的LTDC时要用到,如果规格书没有直接给出时序参数,则会给出使用的Driver IC型号,用户可以搜索此Driver IC的手册,在手册中会给出。
为了让大家有个感性认识,我们来看一看TFT裸屏的实际效果,下面是SPDF5420显示屏,400*240分辨率:
下面是TFT裸屏,480*272分辨率:
下面是TFT裸屏,800*480分辨率:
41.2.2 电阻触摸和电容触摸相关知识
有了TFT裸屏后还要配套电阻触摸板或者电容触摸板才可以获取触摸信息。触摸板是贴到TFT屏上面的,然后再通过电阻触摸芯片就可以获取电阻触摸板的信息,通过电容触摸芯片采集电容触摸板的信息。教程配套开发板的显示屏使用了三种触摸IC,电阻触摸IC是STMPE811,电容触摸IC是GT811和FT5X06。其中,电阻触摸和电容触摸两者的区别是初学者务必要知道的:
电阻触摸芯片STMPE811其实就是ADC,返回的是ADC数值,而电容触摸芯片GT811,GT911和FT5X06返回的是显示屏实际的坐标值。
使用电阻触摸芯片STMPE811需要做触摸校准,而使用电容触摸芯片GT811,GT911和FT5X06是自动校准的,无需手动校准。
下面是四线电阻触摸板的效果:
下面是电容触摸板的效果:
了解了这些知识,基本已经够我们本章节使用了,更多电阻触摸和电容触摸的相关知识可以看这个文档,讲解比较全面:http://www.armbbs.cn/forum.php?mod=viewthread&tid=14898 。
41.3 LCD硬件设计
下面是RGB888硬件接口的原理图,STM32-V6开发板制作了三个硬件接口。
加高2层的双排母接口
2.54mm的排针接口
FPC软排线接口方式
了解了原理图后,再来看下实际的接口效果:
通过上面的原理图,我们要了解以下几个问题:
V6开发板采用的是RGB888硬件接口,也许大家会问ARGB8888这种颜色格式怎么用于这种接口?Alpha通道是软件编程的时候用的,用于设置透明度,透明度会反应到RGB颜色值上。
STM32F429支持的8种颜色格式都可以在RGB888硬件接口上实现。
如果大家用的是16位色的RGB565颜色格式,那么仅需用到LCD_R[7:3]、LCD_G[7:2] 和 LCD_B[7:3]引脚即可,没有用到的引脚可以继续用作其它功能。
41.4 LCD驱动设计
下面将程序设计中的相关问题逐一为大家做个说明。
41.4.1 第1步,LTDC显存使用SDRAM
设计LTDC驱动前,要先保证显存可以正常使用,V6开发板用的外部SDRAM作为显存。所以一定要保证SDRAM大批量读写数据时是正常的,SDRAM的测试可以自己专门做一个工程测试下。对于SDRAM的驱动实现,可以学习本教程第39章。不管你使用的是镁光的,海力士的,三星的,ISSI的或者华邦的,实现方法基本都是一样的。
V6开发板使用镁光的32位带宽、16MB的SDRAM,如果想最大限度的发挥STM32F429驱动SDRAM的性能,强烈建议使用32位带宽的SDRAM,或者两个16位SDRAM组成32位带宽的SDRAM也是可以的。那SDRAM主要起到什么作用呢?作用有二:
用作显示屏的显存
STM32F429的LTDC外接RGB接口屏是没有显存的,所以需要SDRAM用作显存。如果用户选择STM32F429 LTDC的颜色格式是32位色ARGB8888,那么所需要显存大小(单位字节)是:显示屏宽 * 显示屏高 * (32/8), 其中32/8是表示这种颜色格式的一个像素点需要4个字节来表示。又比如配置颜色格式是16位色的RGB565,那么需要的显存大小是:显示屏宽 * 显示屏高 * (16/8),其中16/8是表示这种颜色格式的一个像素点需要2个字节来表示。其它的颜色格式,依此类推。
用作GUI动态内存
如果想要实现炫酷效果,GUI是极其消耗动态内存的,所以用户可以将SDRAM除了用于显存以外的所有内存全部用作GUI动态内存。
如果SDRAM的驱动测试已经没有问题了,就可以将其添加到工程里面了,V6使用的SDRAM驱动文件是bsp_fmc_sdram.c。图层1占用2MB,图层2占用2MB,最后12MB可做其它使用。也许会有初学者会问,每个图层分配2MB是不是有些多了?实际上不多的,因为我们要让不同的颜色格式都通用,这里分配2MB的话,教程实例使用很方便。大家实际项目中的使用可以配置成实际大小。具体的配置如下,详情见bsp_fmc_sdram.h文件:
#define EXT_SDRAM_ADDR ((uint32_t)0xC0000000)
#define EXT_SDRAM_SIZE (16 * 1024 * 1024)
/* LCD显存,第1页, 分配2M字节 */
#define SDRAM_LCD_BUF1 EXT_SDRAM_ADDR
/* LCD显存,第2页, 分配2M字节 */
#define SDRAM_LCD_BUF2 (EXT_SDRAM_ADDR + SDRAM_LCD_SIZE)
#define SDRAM_LCD_SIZE (2 * 1024 * 1024) /* 每层2M */
#define SDRAM_LCD_LAYER 2 /* 2层 */
/* 剩下的12M字节,提供给应用程序使用 */
#define SDRAM_APP_BUF (EXT_SDRAM_ADDR + SDRAM_LCD_SIZE * SDRAM_LCD_LAYER)
#define SDRAM_APP_SIZE (EXT_SDRAM_SIZE - SDRAM_LCD_SIZE * SDRAM_LCD_LAYER)
41.4.2 第2步,LTDC涉及到的引脚配置
本章第3小节用到了哪些引脚,这些引脚全部要做初始化,初始化时别忘了初始化引脚对应的时钟:
static void LCDF4_ConfigLTDC(void)
{
/* 配置LCD相关的GPIO */
{
/* GPIOs Configuration */
/*
+------------------------+-----------------------+----------------------------+
+ LCD pins assignment +
+------------------------+-----------------------+----------------------------+
| LCD429_TFT R0 <-> PI.15 | LCD429_TFT G0 <-> PJ.07 | LCD429_TFT B0 <-> PJ.12 |
| LCD429_TFT R1 <-> PJ.00 | LCD429_TFT G1 <-> PJ.08 | LCD429_TFT B1 <-> PJ.13 |
| LCD429_TFT R2 <-> PJ.01 | LCD429_TFT G2 <-> PJ.09 | LCD429_TFT B2 <-> PJ.14 |
| LCD429_TFT R3 <-> PJ.02 | LCD429_TFT G3 <-> PJ.10 | LCD429_TFT B3 <-> PJ.15 |
| LCD429_TFT R4 <-> PJ.03 | LCD429_TFT G4 <-> PJ.11 | LCD429_TFT B4 <-> PK.03 |
| LCD429_TFT R5 <-> PJ.04 | LCD429_TFT G5 <-> PK.00 | LCD429_TFT B5 <-> PK.04 |
| LCD429_TFT R6 <-> PJ.05 | LCD429_TFT G6 <-> PK.01 | LCD429_TFT B6 <-> PK.05 |
| LCD429_TFT R7 <-> PJ.06 | LCD429_TFT G7 <-> PK.02 | LCD429_TFT B7 <-> PK.06 |
-------------------------------------------------------------------------------
| LCD429_TFT HSYNC <-> PI.12 | LCDTFT VSYNC <-> PI.13 |
| LCD429_TFT CLK <-> PI.14 | LCD429_TFT DE <-> PK.07 |
-----------------------------------------------------
*/
GPIO_InitTypeDef GPIO_Init_Structure;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* 使能LTDC时钟 */
__HAL_RCC_LTDC_CLK_ENABLE();
/* 使能GPIO时钟 */
__HAL_RCC_GPIOI_CLK_ENABLE();
__HAL_RCC_GPIOJ_CLK_ENABLE();
__HAL_RCC_GPIOK_CLK_ENABLE();
/* GPIOI 配置 */
GPIO_Init_Structure.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP;
GPIO_Init_Structure.Pull = GPIO_NOPULL;
GPIO_Init_Structure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_Init_Structure.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOI, &GPIO_Init_Structure);
/* GPIOJ 配置 */
GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 |
GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 |
GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP;
GPIO_Init_Structure.Pull = GPIO_NOPULL;
GPIO_Init_Structure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_Init_Structure.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOJ, &GPIO_Init_Structure);
/* GPIOK 配置 */
GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP;
GPIO_Init_Structure.Pull = GPIO_NOPULL;
GPIO_Init_Structure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_Init_Structure.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOK, &GPIO_Init_Structure);
}
/* 其它省略未写 */
}
41.4.3 第3步,LTDC时钟和时序配置
LTDC时序配置主要分三步就可以完成:
行同步,场同步和DE的极性配置。
CLK时钟配置。
时序参数配置。
下面将这三点分别做个说明:
行同步,场同步和DE的极性配置
这里以V6开发板7寸RGB屏使用的source driver ic OTA7001为例进行说明(手册下载地址:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=18528)。
这几项配置要看OTA7001手册上面的时序图,对于DE模式,行同步和场同步的极性配置为高或者为低均可。因为我们这里使用的就是DE模式,所以主要配置DE的极性。这里要特别注意一个小问题,看时序图是DE高电平时数据有效,但是配置的时候要设置为低电平才可以。
下面的是V6开发板配套的7寸裸屏使用的source driver ic OTA7001的时序图:
上一篇:第42章 STM32F429的LTDC应用之点阵字体和字符编码(重要)
下一篇:第40章 STM32F429的LCD控制器LTDC基础知识和HAL库API
推荐阅读





推荐帖子
- 参与HELPER2416开发板助学计划的疑问...
- 板子到了第三天....按照《君益兴Helper2416_V2开发板使用手册》到3.2.2SD卡不能烧写LINUX到ANADflsh....3.2.1完全正确到3.2.2插上SD卡和串口线软件是SecureCRT7.2跳线帽选择SD卡启动....拨通电源开关....串口没显示屏也不亮,是什么原因呢?还有现在我想点亮一个LED灯....要怎么写程序或者说怎么下载程序。 参与HELPER2416开发板助学计划的疑问...
-
Xy201207
嵌入式系统
- DB SDK移动短信应用引擎针对基金公司管理应用案例
- 提供不同的客户端应用系统,和基金公司的高标准需求,DB-SDK(http://sdk.emay.cn/)短信应用引擎可以实现,客户端系统不仅可以直接与运营商通道相连接,同时还可以提供“运营商网关监控”的功能。即:如果直连的运营商网络通讯出现故障,可以通过DB-SDK(http://sdk.emay.cn/)短信应用引擎发送预警短信。 具体解决方案: 下行短信发送 功能:实现对中国移动、中国联通、中国电信的下行短信发送。 1、能够支持不同优先级短信的发送,优先级高的短信先发送到短信平台。
-
27018352
RF/无线
- 有源模拟滤波器的快速设计指南
- 引言 几乎所有电子电路中都能看到有源模拟滤波器的身影。音频系统使用滤波器进行频带限制和平衡。通信系统设计师使用滤波器调谐特定频率并消除其它频率。为了使高频信号衰减,所有数据采集系统都在模数转换器(ADC)前面有一个抗锯齿(低通)滤波器,或者在数模转换器(DAC)后面有一个抗镜像(低通)滤波器。这种模拟滤波还可以在信号到达ADC之前或者离开DAC之后,消除叠加在信号上面的高频噪声。如果ADC的输入信号超出转换器采样频率的一半,则该信号的大小被可靠地转换;但是,在其变回数字输出时,频率也发生改变。
-
wstt
模拟与混合信号
- 大连某企业急招WinCE开发人员
- 大连某大型企业招WinCE驱动与应用软件开发人员,采用x86硬件平台. 要求:有搭建WinCE6.0x86联机开发环境&系统订制&驱动开发&应用程序开发经历,熟炼常握C语言和VS2005开发环境. 2008.5.1日以前有效. 另招Linux开发工程师,要求有RTLinux+2410开发经验,熟炼掌握C语言. 2008.12.31日前有效. 有意者请以文本文件格式发简历到:wgy@dmtg.com 大连某企业急招WinCE开发人员
-
tule2006
WindowsCE
- 嵌入式问题
- 题目如下:设计一个针对某一具体应用的嵌入式系统 要求:1有完整的系统设计方案 2对系统方案有完整说明 3有相应的印制版图 4有完整的系统调试方案 5软件流程及其说明 急麻烦高手指点迷津谢谢嵌入式问题
-
weiaa1911
嵌入式系统
- LED驱动电路设计
- 《LED驱动电路设计》以LED光源及其驱动技术为主线,全面系统地介绍了LED的特性、LED驱动电路及其相关技术,并结合实例介绍了各种LED驱动电路的详细设计方法,加深读者对LED驱动电源设计过程的理解。《LED驱动电路设计》兼顾了不同读者的需要,由浅入深,层次清晰,通俗易懂,实用性强,可作为电气工程类专业本科生及研究生的入门教材,也可供从事LED驱动电源设计的工程技术人员参考。http://download.eeworld.com.cn/detail/%E5%A4%AA%E7%99%BD
-
arui1999
下载中心专版