1.FSMC是什么?
FSMC,即灵活的静态存储控制器,能够与同步或异步存储器和16位PC存储器卡连接,STM32的FSMC接口支持包括SRAM、NAND FLASH、NOR FLASH和PSRAM等存储器。(不支持SDRAM(F4支持))
存储控制器,一个NOR和一个NAND/PC,有四个信号,一个公用
2.FSMC如何控制SRAM?FSMC控制TFTLCD的原理是什么?
FSMC驱动外部SRAM时,外部SRAM的控制一般有:
地址线(如A0~A25)(RS)
数据线(如D0~D15)
写信号(WE,即WR)
读信号(OE,即RD)
片选信号(CS)
如果SRAM支持字节控制,那么还有UB/LB信号
而TFTLCD的信号我们在前面介绍过,包括:RS、D0~D15、WR、RD、CS、RST和BL等,其中真正在操作LCD的时候需要用到的就只有:RS、D0~D15、WR、RD和CS。
其操作时序和SRAM的控制完全类似,唯一不同就是TFTLCD有RS信号,但是没有地址信号。
所以我们要把RS当作一个地址线来用
TFTLCD通过RS信号来决定传送的数据是数据还是命令,本质上可以理解为一个地址信号
比如我们把RS接在A0上面,那么当FSMC控制器写地址0的时候,会使得A0变为0,对TFTLCD来说,就是写命令。
而FSMC写地址1的时候,A0将会变为1,对TFTLCD来说,就是写数据了。
这样,就把数据和命令区分开了,他们其实就是对应SRAM操作的两个连续地址。当然RS也可以接在其他地址线上,战舰V3和精英板开发板都是把RS连接在A10上面,而探索者STM32F4把RS接在A6上面。
因此,可以把TFTLCD当成一个SRAM来用,只不过这个SRAM有2个地址,这就是FSMC可以驱动LCD的原理。
把LCD当成一个sram来用就可以用NOR控制器驱动LCD
3.FSMC如何快速的访问硬件?
FSMC(Flexible Static Memory Controller)能够将外部存储器映射到微控制器的地址空间中,这种映射称为存储块映射。
FSMC将外部存储器分为四个固定大小为256MB的存储块(Bank),每个存储块可以独立配置为连接不同类型的存储器或外部设备。
STM32的FSMC有四个存储块,每个存储块的大小为256MB,具体的映射如下
-
固定地址范围:每个存储块的地址范围是固定的,且每个存储块的大小为256MB。这意味着,不管你连接的外部存储器实际容量是多少,它在STM32的地址空间中都会占用256MB的地址空间。
-
灵活配置:每个存储块可以独立配置,支持不同类型的存储器。例如,你可以在Bank 1连接一个NOR闪存,同时在Bank 2连接一个NAND闪存。FSMC允许你独立设置每个存储块的时序、数据宽度、操作模式等参数。
-
内存映射访问:一旦存储器通过FSMC映射到STM32的地址空间中,你就可以像访问内存那样访问这些外部设备。这种内存映射的方式使得与外部设备的数据交换非常高效,适合高速数据传输需求。
STM32的FSMC支持8/16/32位数据宽度,我们这里用到的LCD是16位宽度的,所以在设置的时候,选择16位宽就OK了。FSMC的外部设备地址映像,STM32的FSMC将外部存储器划分为固定大小为256M字节的四个存储块
4.如何配置存储块?
STM32的FSMC存储块1(Bank1)用于驱动NOR FLASH/SRAM/PSRAM,被分为4个区,每个区管理64M字节空间,每个区都有独立的寄存器对所连接的存储器进行配置。
Bank1的256M字节空间由28根地址线(HADDR[27:0])寻址
- HADDR[27:26]:用于选择 Bank1 的四个子区域(每个子区域 64MB)
- HADDR[25:0]:用于在每个子区域内进行寻址
这里HADDR,是内部AHB地址总线,其中,HADDR[25:0]来自外部存储器地址FSMC_A[25:0],而HADDR[26:27]对4个区进行寻址。如下表所示:
当Bank1接的是16位宽度存储器的时候:HADDR[25:1]→ FSMC_A[24:0](右移一位)
这里HADDR一个地址对应的是一个字节,而十六位相当于两个字节,所以需要除以2
当Bank1接的是8位宽度存储器的时候:HADDR[25:0]→FSMC_A[25:0]
不论外部接8位/16位宽设备,FSMC_A[0]永远接在外部设备地址A[0]
STM32的FSMC存储块1 支持的异步突发访问模式包括:模式1、模式A~D等多种时序模型,驱动SRAM时一般使用模式1或者模式A,这里我们使用模式A来驱动LCD(当SRAM用),其他模式说明详见:STM32中文参考手册-FSMC章节。
模式A读时序图 模式A写时序图
要用到LCD上这里就是一一对应关系,两者的时序是类似的
模式A支持读写时序分开设置!
对STM32F4仅写时序DATAST需要+1
5.怎么配置FSMC
对于NOR FLASH/PSRAM控制器(存储块1),通过FSMC_BCRx、FSMC_BTRx和FSMC_BWTRx寄存器设置(其中x=1~4,对应4个区)。
通过这3个寄存器,可以设置FSMC访问外部存储器的时序参数,拓宽了可选用的外部存储器的速度范围。
①SRAM/NOR闪存片选控制寄存器(FSMC_BCRx)
EXTMOD:扩展模式使能位,控制是否允许读写不同的时序,需设置为1(否则会降低写入速度)
WREN:写使能位。我们需要向TFTLCD写数据,故该位必须设置为1
MWID[1:0]:存储器数据总线宽度。00,表示8位数据模式;01表示16位数据模式;10和11保留。我们的TFTLCD是16位数据线,所以设置WMID[1:0]=01。
MTYP[1:0]:存储器类型。00表 示SRAM、ROM;01表示PSRAM;10表示NOR FLASH;11保留。我们把LCD当成SRAM用,所以需要设置MTYP[1:0]=00。
MBKEN:存储块使能位。需设置为1
②SRAM/NOR闪存片选时序寄存器(FSMC_BTRx)
ACCMOD[1:0]:访问模式。00:模式A;01:模式B;10:模式C;11:模式D。
DATAST[7:0]:数据保持时间,等于: DATAST(+1)个HCLK时钟周期,DATAST最大为255。对ILI9341来说,其实就是RD低电平持续时间,最大为355ns。对STM32F1,一个HCLK=13.8ns (1/72M),设置为15;对STM32F4,一个HCLK=6ns(1/168M) ,设置为60。
ADDSET[3:0]:地址建立时间。表示:ADDSET (+1)个HCLK周期,ADDSET最大为15。对ILI9341来说,这里相当于RD高电平持续时间,为90ns。STM32F1的FSMC性能存在问题,即便设置为0,RD也有190ns的高电平,我们这里设置为1。而对STM32F4,则设置为15。
如果未设置EXTMOD位,则读写共用这个时序寄存器!
③SRAM/NOR闪存写时序寄存器(FSMC_BWTRx)
ACCMOD[1:0]:访问模式。00:模式A;01:模式B;10:模式C;11:模式D。
DATAST[7:0]:数据保持时间,等于: DATAST(+1)个HCLK时钟周期,DATAST最大为255。对ILI9341来说,其实就是WR低电平持续时间,为15ns,不过ILI9320等则需要50ns。考虑兼容性,对STM32F1,一个HCLK=13.8ns (1/72M),设置为3;对STM32F4,一个HCLK=6ns(1/168M) ,设置为9。
ADDSET[3:0]:地址建立时间。表示:ADDSET+1个HCLK周期,ADDSET最大为15。对ILI9341来说,这里相当于WR高电平持续时间,为15ns。同样考虑兼容ILI9320,对STM32F1,这里即便设置为1,WR也有100ns的高电平,我们这里设置为1。而对STM32F4,则设置为8。
在ST官方库提供的的寄存器定义里面,并没有定义FSMC_BCRx、FSMC_BTRx,FSMC_BWTRx等这个单独的寄存器,而是将他们进行了一些组合。
规律如下:
FSMC_BCRx和FSMC_BTRx,组合成BTCR[8]寄存器组,他们的对应关系如下:
BTCR[0]对应FSMC_BCR1,
BTCR[1]对应FSMC_BTR1
BTCR[2]对应FSMC_BCR2,
BTCR[3]对应FSMC_BTR2
BTCR[4]对应FSMC_BCR3,
BTCR[5]对应FSMC_BTR3
BTCR[6]对应FSMC_BCR4,
BTCR[7]对应FSMC_BTR4
FSMC_BWTRx则组合成BWTR[7],他们的对应关系如下:
BWTR[0]对应FSMC_BWTR1,
BWTR[2]对应FSMC_BWTR2,
BWTR[4]对应FSMC_BWTR3,
BWTR[6]对应FSMC_BWTR4,
BWTR[1]、BWTR[3]和BWTR[5]保留,没有用到。