摘要: FAMC(灵活的静态存储控制器),是一个万能的总线控制器,不仅可以控制SRAM,NOR FLASH,NAND FLASH,PC Card,还能控制LCD,TFT。手里有STM32F407开发板和NT35510驱动的分辨率320*480彩色TFTLCD屏幕,通过点亮TFTLCD开始FSMC的学习。 学习路线是这样的,先了解TFTLCD有哪些信号线及其功能,然后通过看STM32参考手册弄明白FSMC如果要控制TFTLCD要使用哪些信号线,才能将两者正确连接,弄明白FSMC的控制策略是怎样的进而才能理解编程原理(为啥不用GPIO代替FSMC呢?),FSMC是一个衔接CPU与外部存储的桥梁,它的功能呢就是你往相应的地址里写数据时候,你不需用软件来模拟外部存储芯片的读写时序,你只需在初始化时配置好FSMC相关的时序寄存器,按照TFTLCD的驱动芯片手册写入相关命令,初始化完成后你只需要指定地址指定数据,时序由FSMC自动完成,但是只有理解了FSMC和屏幕驱动芯片的时序才知道如何设置相关寄存器。
一、TFTLCD
概述:我手里的时正点原子的4.3寸TFTLCD,屏幕驱动芯片为NT35510(有参考手册),通过阅读手册了解到这款驱动芯片可以通过8位16位或24位8080并口、SPI、IIC等方式与MCU连接,NT35510也有驱动芯片引脚介绍,但不清楚驱动芯片和屏幕的连接关系,有待深究,5.1.1节有通信接口选择介绍,通过四根线硬件接线来确定的但正点原子没有给出屏幕驱动芯片接线,猜测是处于保密,仅告知是16位8080并口驱动。手册第5.1.2节80并口模式下需要哪些接线及其作用并介绍了在此模式下读写命令与数据的时序(这部分与32参考手册里讲的差不多),第6节有用户命令集,第7.6.1节写的是80并口模式下的交流接口特性,参考这些设置FSMC相关寄存器。以上是DATASHEET重点关注的部分。
1.TFTLCD信号线
因为TFTLCD是80并口的通信方式,那就相当于约定好了通信时序和使用那些线,所以需要用到的引脚包括:
CS: LCD片选信号
WR: LCD**写**信号
RD: LCD**读**信号
DB[15:0]: 16位 《双向》 数据线
RST: 硬复位LCD信号线
RS: 命令/数据标志(0:命令,1:数据)
LCD_BL: 背光控制信号
T_MISO/T_MOSI/T_PEN/T_CS/T_CLK: 触摸屏接口信号(没用到先不管)
模块的 8080 并口读/写的过程为:先根据要写入/读取的数据的类型,设置 DC 为高(数据)/低(命令),然后拉低片选,选中芯片,接着我们根据是读数据,还是要写数据置 RD/WR为低,然后: 在 RD 的上升沿, 使数据锁存到数据线(D[15: 0])上 在 WR 的上升沿,使命令锁存到数据线(D[15: 0])上 注:电源和地线我们千万不要忽略,模块需要双电源供电:5V和3.3V才可以正常工作,5V电源用于背光供电,3.3V用于除背光外的其他电源部分供电。 这些线如何与STM32连接呢? 这就需要了解FSMC是如何工作的了,FSMC可以连接NOR/PXRAM或NAND和PC等,但他内部分两种控制器,故连接不同的设备需要不同的控制信号线,但是数据总线和地址总线共用,因为咱们把TFTLCD当作SRAM来用,根据STM32参考手册32.5.1可知在外部接SRAM时需要哪些接口信号,因为我们不是SRAM,故只需要其中的一部分:
CS: LCD片选信号 PG12 FSMC_NE4
WR: LCD写信号 PD5 FSMC_NWE
RD: LCD读信号 PD4 FSMC_NOE
DB[15:0]: 16位双向数据线 FSMC_D15 ~ FSMC_D0
RST: 硬复位LCD信号线 与板子的复位按键相连
RS: 命令/数据标志(0:命令,1:数据) PF12 FSMC_A6
LCD_BL: 背光控制信号 PB15
因为在32.4节外部设备地址映射中,FSMC将外部存储器划分为大小为256MB的4个存储块,一个块有4个64M的区,存储外设地址,正点原子选择了块4,所以连接FSMC_NE4, 但是LCD没有地址信号,我们选择FSMC_A6连接RS。
2.NT35510指令介绍
1,ID读取指令:0xDA00、0xDB00、0xDC00 2、0x3600,这是存储访问控制指令,可以控制存储器的读写方向,简 单的说,就是在连续写 GRAM 的时候,可以控制 GRAM 指针的增长方向,从而控制显示方式(读 GRAM 也是一样) 3、0x2A00~0x2A03,这是列地址设置指令,详见DataSheet 4、0x2B00~0x2B03,这是行地址设置指令,详见DataSheet 5、0x2C00,该指令是写 GRAM 指令,在发送该指令之后,我们便可以往 LCD 的 GRAM 里面写入颜色数据,该指令支持连续写 6、0x2E00,该指令是读 GRAM 指令,用于读取 ILI9341 的显存(GRAM)
3.TFTLCD使用流程
1、硬件连线,初始化FSMC和相关IO 2、上电复位TFTLCD,执行初始化序列(一些相关寄存器校准操作,由供应商提供,不必深究) 3、通过函数将字符或数字显示到TFLCD,其中对一个点的读写操作见下图: 先设置坐标,由于屏幕分辨率(320*480)限制,X为 0到319,Y为 0到479 。然后写操作的话先往GRAM写0x2C00(命令),再写入 如果想要实现更多字符的显示,要多次进行这个流程。
4.NT35510驱动芯片80并口模式下GRAM读写时序
读写时序只是让你知道需要这几根信号线对应接到FSMC的哪几根线,只要接好线,这些时序由FSMC自动完成,不需要编程。
二、FSMC
1.FSMC内部如何寻址
FSMC只存在于100-144引脚的芯片中,FSMC支持8、16、32位数据宽度,TFTLCD为16位数据宽度,FSMC地址映像如下图: Bank1的不同四个区被选定后HADDR[27:26]会相应变化。 8位数据线与16位数据线时HADDR[25:0]与FSMC[25:0]对应关系不同。 图404,表185,表186 ,记住这几个表号很重要,下文会时不时提起。 “从 FSMC 的角度,外部存储器被划分为 4 个固定大小的存储块,每个存储块又分为4个区,每个区大小为64MB”看到这你肯定有一堆疑问,HADDR跟寻址有啥关系?为啥每个区有64M?我看了好多人都讲的云里雾里,下面请好好听我忽悠!
根据手册可知存在以下规定:
1、FSMC_A[25:0]是FAMC的26根地址线,只有这26跟。
2、不管外部存储器宽度为16位或8位,FSMC_A[0] 都应连接到外部存储器地A[0]。
3、HADDR 是 AHB 内部地址线,但也会参与对外部存储器的寻址。
4、HADDR[25:0] 包含外部存储器地址,HADDR 为*字节*地址。
5、HADDR[27:26] 位用于从表 185 中所示的四个存储区域之中选择其中一个存储区域。
6、如果外部存储器宽度为16位则HADDR[25:1] 对应FSMC_A[24:0]
通过这些信息,我发现FSMC外部地址线与AHB内部地址线HADDR的0到25位可能有连接关系。回顾表186 下面一行小字:“如果外部存储器宽度为16位,FSMC 将使用内部的 HADDR[25:1] 地址来作为对外部存储器的寻址地址FSMC_A[24:0]。”翻译一下就是:
如果有16位数据线,那内部地址线HADDR[25:1]就与FSMC_A[24:0]对应连接,隐含着如果有8位数据线,那内部地址线HADDR[25:0]就与FSMC_A[25:0]对应连接。
所以,对于16位数据线的TFTLCD来说,只要初始化设置好了16位数据传输模式,内部地址线HADDR[25:1]与外部地址线FSMC_A[24:0]就自动对应连接起来。
为了弄清地址线的对应关系,现假设要控制一个有16根数据线19根地址线的SRAM,与FSMC连接就把两者16根数据线对应连接D0与D0连,两者的19根地址线对应连A0与A0连,片选信号选FSMC_NE4(Bank1的4区),当然还有其他控制线与寻址无关先不谈
HADDR如何寻址? HADDR的26根地址线最大可以寻址2^26=67108864=65535K=64M(注:1M=1024K,1K=1024。此时的寻址范围没有单位,数据线宽度和地址线宽度存储容量关系),由规定知HADDR为字节地址,刚好寻址64MB(B:字节b:位)的空间,正好对应 图404 一个存储块的一个存储区,换言之26根地址线最多管理64M空间,如果想管理更多空间,比如想一次性控制两个64M的SRAM,那就只能将这两个SRAM连接到Bank1的不同的区,区不同片选信号也不同,当选择了不同的区的时候表185 中的HADDR[26:27]会自动设置,这就拓展了地址线的数量,我们需要做的就是初始化时设置好对应区的寄存器组。
但这个SRAM有16位数据线,是按16位字寻址的,他寻址跟HADDR寻址啥关系? 按照 规定,FSMC_A[0] 都应连接到外部存储器地A[0],其实也就是连接了SRAM的A0地址线,因为SRAM也是16位数据线,所以内部地址线HADDR[19:1]就与FSMC_A[18:0]对应连接了,那就要遵守HADDR的规则,根据 规定 HADDR为字节地址,也就是说HADDR[19:0]每增加1位,代表指向外部存储器的指针就要增加1字节(8位)。图404 的映射关系是说:当用不同的块时,外部存储器地址在FSMC的映射地址也不同。咱选择的是Bank1的第四区,当HADDR[19:0]全为零时,即外部存储器的首地址在FSMC的映射地址是0x6C000000。 那自然HADDR[19:1]=0x00000时外部存储器的首地址在FSMC的映射地址也是0x6C000000(我们就是通过改变这个映射地址来给相应的SRAM地址读写数据的)。 举几个例子:
FSMC_A[18:0]=0x0000008时映射地址是多少?对应外部地址线FSMC_A[3]=1,对应内部地址线需要左移一位故HADDR[4]=1,就是HADDR[19:0]=0x00010,0x10+0x6C000000=0x6C000010。
FSMC_A[18:0]=0x000003F时映射地址是多少?对应外部地址线FSMC_A[6:0]=0111111,对应内部地址线需要左移一位故HADDR[7:0]=01111110,转化为16进制就是HADDR[19:0]=0x0007E,0x7E+0x6C000000=0x6C00007E。
FSMC_A[18:0]=0x0000040时映射地址是多少?对应外部地址线FSMC_A[6:0]=1000000,对应内部地址线需要左移一位故HADDR[7:0]=10000000,转化为16进制就是HADDR[19:0]=0x00080,0x80+0x6C000000=0x6C000080。
2.FSMC的触发方式介绍
如果选择了 NOR Flash/PSRAM 控制器,那么可选同步触发和异步触发两种。 同步触发:FSMC将HCLK(系统时钟)分频后,给外部存储器做同步时钟信号FSMC_CLK。此时需要设置的时间参数有两个: 1.HCLK 与 FSMC_CLK 的分频系数(CLKDIV),可以为 2~16 分频; 2.同步突发访问中获得第 1 个数据所需要的等待延迟(DATLAT)。 异步突发:FSMC 主要设置 3 个时间参数:地址建立时间(ADDSET)、数据 建立时间(DA TAST)和地址保持时间(ADDHLD)。 FSMC 综合了 SRAM/ROM、 PSRAM 和 NOR Flash 产品的信号特点,定义了 4 种不同的异步时序模型。选用不同的时序模型时,需要设置不同的时序参数(我选模式A,至于为啥选模式A我暂时不明白,呜呜,来个大神讲讲啥时候用其他模式)。 当选定了模式A时,可查看STM32F4数据手册1203页关于模式A时时序的介绍,需要设置哪些寄存器(要设置的参数就是寄存器的某些位),我们来简单讲讲这些寄存器。
3.FSMC的NOR FLASH控制器相关寄存器介绍
在选定Bank1区4时,模式A要设置的寄存器有:
1、FSMC_BCR4:片选控制寄存器。
2、FSMC_BTR4:读操作时序控制寄存器
3、FSMC_BWTR4:写操作时序控制寄存器
其中大部分设置正点原子都有讲解,我只谈需要自己理解和修改的部分,需要按照NT35510手册361页时序自行调整。 FSMC_BTR4的DATAST位:数据保持时间即RD低电平持续时间。ADDSET位:地址建立事件,即RD高电平持续时间。 FSMC_BTR4的DATAST位:数据保持时间即WR低电平持续时间。ADDSET位:地址建立事件,即WR高电平持续时间。 其实说的这些如何修改寄存器的操作只有按寄存器编程时才能用到,我现在还是用的库函数编程,他把对几个寄存器的操作揉一块了,现暂时知道怎样设置库函数就行。
三、FSMC必要程序讲解
1.RS数据命令引脚选择与地址关系
由本文第一张图可知,0x6C000000为选定Bank1的第四区后外部存储器的首地址在FSMC的映射地址。把A0:A6都视为地址线,根据上文举的例子知在16位数据线情况下,当FSMC_A[6:0]=0111111时偏移地址为0x0007E,映射地址为0x6C00007E,此时A6刚好低电平。当FSMC_A[6:0]=1000000时偏移地址为0x00080,映射地址为0x6C000080,此时A6刚好高电平。在这一小段程序中,作者巧妙的利用结构体内部地址自增特性,实现了通过控制外部存储器在FSMC的映射地址来改变A6端口的电平,进而实现数据和命令标志变更的功能。(这里挺绕的)
2.初始化函数
① GPIO,FSMC 时钟使能。 ② GPIO 初始化:GPIO初始化(包括纯GPIO口和FSMC相关的控制和数据端口)。 ③ 设置引脚复用映射(所有涉及FSMC的线)。 ④ FSMC 初始化:FSMC_NORSRAMInit()函数,内部参数根据实际情况调整。 ⑤ FSMC 使能:FSMC_NORSRAMCmd()函数。 ⑥ 不同的 LCD 驱动器的初始化代码(厂家提供)。
3.读点函数与画点函数
需要按照TFTLCD使用流程来进行编程,但对于NT35510来说读点函数与画点函数有些不同,因为画点时按照RGB565的格式一次性写入,而读点时需要都两次才能读出一个点的RGB888数据。 上图为NT35510DataSheet34页16位并口模式写RGB的说明,可以写入不同颜色深度的数据,但我从程序中感觉默认就是RGB565,也可能初始化时设置的??不太清除。 上图为NT35510DataSheet43页26位并口模式写RGB的说明,可以写入不同颜色深度的数据,读出来是RGB888模式还需要转化成RGB565模式,转化方法是取高位关于更多介绍看链接:RGB888与RGB565转换。
此博客写了大概一星期,终于结束,回顾整个学习过程,发现能把实验搞出来跟能把遇到的问题和解决办法写出来还是有巨大差距的,开始一直搞不懂如何通过控制地址线实现读写标志的控制,不知道内部对应关系,当然现在还是有许多疑问没有解决,先列在下面,下次实战再继续深究,如有错误或疑问欢迎大家指正,我定会一一回复。 遗留问题:
1、TFTLCD内部的NT35510是如何跟屏幕连接实现驱动功能的,买了就有?需要了解吗?
2、AHB总线与在STM32总线系统中都与谁连接了,其实就是参考手册2.1.8节总线型系统不明白
3、FSMC如何驱动SRAM,继续在实战中学习
4、TFTLCD还有一些其他引脚没使用,有啥功能?
5、除了8080并口,TFTLCD好像还有其他通信方式,常用吗?
相关优秀博客或文章: 1、4.3寸TFTLCD之NT35510关键指令解析 2、毕业设计论文-触摸式LCD人机接口设计
|