FSMC详解

1、FSMC简介:
FSMC,即灵活的静态存储控制器,能够与同步或异步存储器和 16 位 PC 存储器卡连接,STM32 的 FSMC 接口支持包括 SRAM、NAND FLASH、NOR FLASH 和 PSRAM 等存储器。
2、FSMC 的框图:
在这里插入图片描述
从上图我们可以看出,STM32 的 FSMC 将外部设备分为 3 类:NOR/PSRAM 设备、NAND设备、PC 卡设备。他们共用地址数据总线等信号,他们具有不同的 CS 以区分不同的设备, TFTLCD 可以用 FSMC_NE4 做片选,其实就是将 TFTLCD 当成 SRAM 来控制。
3、FSMC 的外部设备地址映像
STM32 的 FSMC将外部存储器划分为固定大小为 256M 字节的四个存储块,如图所示:
在这里插入图片描述

FSMC 总共管理 1GB 空间,拥有 4 个存储块(Bank)
4、 FSMC 存储块 1(Bank1)
STM32 的 FSMC 存储块 1(Bank1)被分为 4 个区,每个区管理 64M 字节空间,每个区都有独立的寄存器对所连接的存储器进行配置。Bank1 的 256M 字节空间由 28 根地址线(HADDR[27:0])寻址。
这 里 HADDR 是内 部 AHB 地址总 线,其 中 HADDR[25:0]来自外部存储器地址FSMC_A[25:0],而 HADDR[26:27]对 4 个区进行寻址。
在这里插入图片描述
说明:
(1)当Bank1接的是16位宽度存储器的时候:HADDR[25:1]–>FSMC_A[24:0]
(2)当Bank1接的是8位宽度存储器的时候:HADDR[25:0]–>FSMC_A[25:0]
(3)不论外部接8位/16位宽设备,FSMC_A[0]永远接在外部设备地址A[0]
注意:
(1)TFTLCD使用的是 16 位数据宽度,所以 HADDR[0]并没有用到,只有 HADDR[25:1]是有效的,对应关系变为:HADDR[25:1]→ FSMC_A[24:0],相当于右移了一位
(2)HADDR[27:26]的设置,是不需要我们干预的,比如:当你选择使用 Bank1 的第三个区,即使用 FSMC_NE3 来连接外部设备的时候,即对应了 HADDR[27:26]=10,我们要做的就是配置对应第 3 区的寄存器组,来适应外部设备即可。
5、STM32 的 FSMC 各 Bank 配置寄存器如表所示:
在这里插入图片描述
对于 NOR FLASH 控制器,主要是通过 FSMC_BCRx、FSMC_BTRx 和 FSMC_BWTRx 寄存器设置(其中 x=1~4,对应 4 个区)。通过这 3 个寄存器,可以设置 FSMC 访问外部存储器的时序参数,拓宽了可选用的外部存储器的速度范围。
6、FSMC存储块1 支持的访问模式
STM32的FSMC存储块1 支持的异步突发访问模式包括:模式1、模式A~D等多种时序模型,驱动SRAM时一般使用模式1或者模式 A,这里使用模式A来驱动LCD(当SRAM用)
(1)模式A读时序图
在这里插入图片描述
(2)模式A写时序图

在这里插入图片描述
FSMC 的 NOR FLASH 控制器支持同步和异步突发两种访问方式。
(3)选用同步突发访问方式时,FSMC 将 HCLK(系统时钟)分频后,发送给外部存储器作为同步时钟信号 FSMC_CLK。
此时需要的设置的时间参数有 2 个:
1,HCLK 与 FSMC_CLK 的分频系数(CLKDIV),可以为 2~16 分频;
2,同步突发访问中获得第 1 个数据所需要的等待延迟(DATLAT)。

(4)对于异步突发访问方式,FSMC 主要设置 3 个时间参数:地址建立时间(ADDSET)、数据建立时间(DATAST)和地址保持时间(ADDHLD)。
FSMC 综合了 SRAM/ROM、PSRAM 和 NOR Flash 产品的信号特点,定义了 4 种不同的异步时序模型。选用不同的时序模型时,需要设置不同的时序参数,如表所列:
在这里插入图片描述
在这里插入图片描述
在实际扩展时,根据选用存储器的特征确定时序模型,从而确定各时间参数与存储器读/写周期参数指标之间的计算关系;利用该计算关系和存储芯片数据手册中给定的参数指标,可计算出 FSMC 所需要的各时间参数,从而对时间参数寄存器进行合理的配置。
模式 A 支持独立的读写时序控制,这个对驱动 TFTLCD 来说非常有用,因为 TFTLCD在读的时候,一般比较慢,而在写的时候可以比较快,如果读写用一样的时序,那么只能以读的时序为基准,从而导致写的速度变慢,或者在读数据的时候,重新配置 FSMC 的延时,在读操作完成的时候,再配置回写的时序,这样虽然也不会降低写的速度,但是频繁配置,比较麻烦。而如果有独立的读写时序控制,那么我们只要初始化的时候配置好,之后就不用再配置,既可以满足速度要求,又不需要频繁改配置。
从模式 A 的读写时序图可以看出,读操作还存在额外的 2 个 HCLK 周期,用于数据存储,所以同样的配置读操作一般比写操作会慢一点。 ADDSET与 DATAST,是通过不同的寄存器设置的
7、Bank1 的几个控制寄存器
对于NOR FLASH/PSRAM控制器(存储块1),通过FSMC_BCRx、FSMC_BTRx和FSMC_BWTRx寄存器设置(其中x=1~4,对应4个区)。通过这3个寄存器,可以设置FSMC访问外部存储器的时序参数,拓宽了可选用的外部存储器的速度范围。
(1) 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
(2)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位,则读写共用这个时序寄存器!
(3)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。
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]保留,没有用到。
9、为什么可以把 TFTLCD 当成 SRAM 设备用?
外部 SRAM 的控制一般有:地址线(如 A0~A18)、数据线(如 D0~D15)、写信号(WE)、读信号(OE)、片选信号(CS),如果 SRAM 支持字节控制,那么还有 UB/LB 信号。而 TFTLCD的信号包括:RS、D0~D15、WR、RD、CS、RST 和 BL 等,其中真正在操作 LCD 的时候需要用到的就只有:RS、D0~D15、WR、RD 和 CS。其操作时序和 SRAM的控制完全类似,唯一不同就是 TFTLCD 有 RS 信号,但是没有地址信号。
TFTLCD 通过 RS 信号来决定传送的数据是数据还是命令,本质上可以理解为一个地址信号,比如我们把 RS 接在 A0 上面,那么当 FSMC 控制器写地址 0 的时候,会使得 A0 变为 0,对 TFTLCD 来说,就是写命令。而 FSMC 写地址 1 的时候,A0 将会变为 1,对 TFTLCD 来说,就是写数据了。这样,就把数据和命令区分开了,他们其实就是对应 SRAM 操作的两个连续地址。
10、FSMC 相关的库函数:
(1)FSMC 初始化函数
固件库提供了 3 个 FSMC 初始化函数分别为

FSMC_NORSRAMInit()FSMC_NANDInit()FSMC_PCCARDInit()

这三个函数分别用来初始化 4 种类型存储器,用来初始化NOR 和 SRAM 使用同一个函数 FSMC_NORSRAMInit()。
函数定义:

void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct)

这个函数只有一个入口参数,也就是 FSMC_NORSRAMInitTypeDef 类型指针变量

typedef struct
{
 uint32_t FSMC_Bank; 
 uint32_t FSMC_DataAddressMux; 
 uint32_t FSMC_MemoryType; 
 uint32_t FSMC_MemoryDataWidth;
 uint32_t FSMC_BurstAccessMode; 
 uint32_t FSMC_AsynchronousWait; 
 uint32_t FSMC_WaitSignalPolarity; 
 uint32_t FSMC_WrapMode; 
 uint32_t FSMC_WaitSignalActive; 
 uint32_t FSMC_WriteOperation; 
 uint32_t FSMC_WaitSignal; 
 uint32_t FSMC_ExtendedMode; 
 uint32_t FSMC_WriteBurst; 
 FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; 
 FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct;
 }FSMC_NORSRAMInitTypeDef;

从这个结构体我们可以看出,前面有 13 个基本类型(unit32_t)的成员变量,这 13 个参数是用来配置片选控制寄存器 FSMC_BCRx。最后面还有两个SMC_NORSRAMTimingInitTypeDef 指针类型的成员变量。FSMC 有读时序和写时序之分,所以这里就是用来设置读时序和写时序的参数了, 也就是说,这两个参数是用来配置寄存器 FSMC_BTRx 和FSMC_BWTRx,
模式 A下的相关配置参数:
参数 FSMC_Bank 用来设置使用到的存储块标号和区号,前面讲过,我们是使用的存储块 1 区 号 4,所以选择值为 FSMC_Bank1_NORSRAM4。
参数 FSMC_MemoryType 用来设置存储器类型,我们这里是 SRAM,所以选择值为
FSMC_MemoryType_SRAM。
参数 FSMC_MemoryDataWidth 用来设置数据宽度,可选 8 位还是 16 位,这里我们是 16 位数据
宽度,所以选择值为 FSMC_MemoryDataWidth_16b。
参数 FSMC_WriteOperation 用来设置写使能,毫无疑问,我们前面讲解过我们要向 TFT 写数据,
所以要写使能,这里我们选择 FSMC_WriteOperation_Enable。
参数 FSMC_ExtendedMode 是设置扩展模式使能位,也就是是否允许读写不同的时序,这里我
们采取的读写不同时序,所以设置值为 FSMC_ExtendedMode_Enable。
上面的这些参数是与模式 A 相关的,下面我们也来稍微了解一下其他几个参数的意义吧:
参数 FSMC_DataAddressMux 用来设置地址/数据复用使能,若设置为使能,那么地址的低 16
位和数据将共用数据总线,仅对 NOR 和 PSRAM 有效,所以我们设置为默认值不复用,值
FSMC_DataAddressMux_Disable。
参 数 FSMC_BurstAccessMode , FSMC_AsynchronousWait , FSMC_WaitSignalPolarity ,
FSMC_WaitSignalActive , FSMC_WrapMode , FSMC_WaitSignal FSMC_WriteBurst 和
FSMC_WaitSignal 这些参数在成组模式同步模式才需要设置,大家可以参考中文参考手册了解
相关参数的意思。
接下来 我 们 看 看 设 置 读 写 时 序 参 数 的 两 个 变 量 FSMC_ReadWriteTimingStruct 和FSMC_WriteTimingStruct,他们都是 FSMC_NORSRAMTimingInitTypeDef 结构体指针类型,这两个参数在初始化的时候分别用来初始化片选控制寄存器 FSMC_BTRx 和写操作时序控制寄存器 FSMC_BWTRx。
下面我们看看 FSMC_NORSRAMTimingInitTypeDef 类型的定义:

typedef struct
{
 uint32_t FSMC_AddressSetupTime; 
 uint32_t FSMC_AddressHoldTime; 
 uint32_t FSMC_DataSetupTime; 
 uint32_t FSMC_BusTurnAroundDuration; 
 uint32_t FSMC_CLKDivision; 
 uint32_t FSMC_DataLatency; 
 uint32_t FSMC_AccessMode; 
}FSMC_NORSRAMTimingInitTypeDef;

这个结构体有 7 个参数用来设置 FSMC 读写时序。其实这些参数的意思我们前面在讲解 FSMC的时序的时候有提到,主要是设计地址建立保持时间,数据建立时间等等配置,对于我们的实验中,读写时序不一样,读写速度要求不一样,所以对于参数 FSMC_DataSetupTime 设置了不同的值,大家可以对照理解一下。记住,这些参数的意义在前面讲解 FSMC_BTRx 和FSMC_BWTRx 寄存器的时候都有提到
(2)FSMC 使能函数
FSMC 对不同的存储器类型同样提供了不同的使能函数:

void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState);
void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState);
void FSMC_PCCARDCmd(FunctionalState NewState);

SRAM使用的第一个函数

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐