STM32 FSMC/FMC原理保姆级讲解(一)

STM32 FSMC/FMC原理保姆级讲解(二)

FSMC( Flexible static memory controller)全称“灵活的静态存储器控制器”,是 STM32中一个很有特色的外设,通过 FSMC,STM32可以通过FSMC与SRAM、ROM、PSRAM、Nor Flash和NandFlash存储器的引脚相连,从而进行数据的交换。

要注意的是,FSMC 只能扩展静态的内存,即名称里面的 S:static,不能是动态的内存,比如 SDRAM 就不能扩展。

关于DRAM跟SRAM等内存存储,如果不懂请看这篇:
SDRAM、DRAM及DDR FLASH ROM概念详解

FSMC通俗讲解

既然我们知道FMC是可以方便的跟内存存储,那么到底方便到什么地方了呢?

我们用DRAM做一个最简单的举例,让你最直观的了解FMC的用处和便捷之处。

首先我们想一下,你想要在自己的电脑中查找一个文档文件的数据 ,然后拷到U盘里,需要的步骤是什么呢?

  1. 找到该文档在电脑中的位置(地址)
  2. 复制该文档(数据)
  3. 将文档粘贴到U盘中(数据传输)

在这里插入图片描述

一共需要三步,而我们的DRAM和NOR FLASH 都是存储器,把它们想成电脑 ,U盘是我们的STM32

扫描二维码关注公众号,回复: 13752645 查看本文章

单片机跟外部存储器通信,也需要知道数据的地址(电脑中的位置),然后把数据的内容传递(复制粘贴)过来。 那这样的话,存储器就需要地址传输线数据传输线,还要加上一些控制时序引脚 比方说复位 写数据 读数据 等等

  • 1、地址线:是用来传输地址信息用的。举个简单的例子:cpu在内存或硬盘里面寻找一个数据时,先通过地址线找到地址,然后再通过数据线将数据取出来。 如果有32根.就可以访问2的32次方的字节,也就是4GB。

  • 2、数据线(data cable),来传递数据或通信。通俗点说,就是单片机发送指令给存储器,和存储器发送数据给单片机这两个功能

我们来看一个DRAM存储器的原理图:
在这里插入图片描述

图中A0 ~ 18为地址线,总共19根地址线(即2^19=512K,1K=1024);DQ0 ~ 15为数据线,总共16根数据线。CEn是芯片使能信号,低电平有效;OEn是输出使能信号,低电平有效;WEn是写使能信号,低电平有效;BLEnBHEn分别是高字节控制和低字节控制信号;


假设我们不用FSMC,直接跟DRAM通信,那么代码应该这样写:

CEn=0;
WEn=0;
....
省略的控制时序
//确定地址线
A0=1;
A1=0;
A2=1;
A3=1;
A4=1;
A5=0;
A6=1;
A7=1;
A8=1;
A9=0;
A10=1;
A11=1;
A12=1;
A13=0;
A14=1;
A15=1;
A16=1;
A17=1;
A18=1;

//地址线确定好了,假设是写数据,那么就要开始发送数据了
CEn=0;
....
省略的控制时序
//数据总线发送数据
D0=1;
D1=0;
D2=1;
D3=1;
D4=1;
D5=0;
D6=1;
D7=1;
D8=1;
D9=0;
D10=1;
D11=1;
D12=1;
D13=0;
D14=1;
D15=1;

....
省略的控制时序

通过上面最基本的演示,你就会发现,正常通过IO口的时序逻辑跟DRAM通信是非常繁琐的

那么有没有简单的方法呢? 有的! STM32自带的FSMC功能,就是专门为这类存储器设计的,在STM32上,有一些引脚被专门设计成地址线,还有一些被专门设计成数据线,还有一些被设计成控制线,然后这些地址线和数据线对应着固定的地址,只要外部的DRAM等存储器将对应的数据线连接到STM32这些对应的引脚上,引脚功能设置为复用模式,通过配置FSMC ,你可以直接给上面那个固定的地址赋值 ,其他操作STM32都会自动给你完成,就可以把数据存储到SRAM中!


我们来看下使用FSMC读写数据的流程:

定义FSMC数据线对应的地址


//FSMC_Bank1_NORSRAM  
#define      FSMC_Addr_DATA        ( ( uint32_t ) 0x60020000 )

如果要写数据,直接给这个地址赋值就可以:

/**
  * @brief  SRAM写入数据
  * @param  usData :要写入的数据
  * @retval 无
  */	
 void SRAM_Write_Data ( uint16_t usData )
{
    
    
	* ( __IO uint16_t * ) ( FSMC_Addr_DATA ) = usData;
	
}

如果要从存储器中读取数据,直接读取这个地址就可以:


/**
  * @brief  从SRAM读取数据
  * @param  无
  * @retval 读取到的数据
  */	
 uint16_t SRAM_Read_Data ( void )
{
    
    
	return ( * ( __IO uint16_t * ) ( FSMC_Addr_DATA ) );	
}

uint16_t usR=0;

usR = SRAM_Read_Data (); 	/* READ DATA*/

是不是傻瓜式操作,极大的方便了我们的程序编写,其实这就好比软件IIC SPI 跟硬件IIC SPI 一样 我们不需要关心协议本身的时序,这些都由STM32内部来设置,我们只需要发送和读取数据就可以,STM32跟外部存储器通信,使用硬件方式就是FMC,这样就很容易理解了


那么,在你了解了什么是FSMC之后,我们就要来详细的讲解FSMC了,它在STM32中到底要怎么配置呢,他又有那些特性呢? 我们接下来将一一阐述。

STM32F1系列的芯片不支持扩展SDRAM (STM32F4跟H7支持),它仅支持使用FSMC外设扩展SRAM,由于引脚数量的限制,只有STM32F103ZE 或以上型号的芯片才可以扩展外部SRAM

FSMC 框图

FSMC 的框图如图所示:
在这里插入图片描述
F1的FSMC包含四个主要模块:AHB总线(包含FSMC配置寄存器);HCLK时钟;NOR闪存和PSRAM控制器;NAND闪存和PC卡控制器;

FMC引脚说明

1、在框图的右侧是FSMC外设相关的控制引脚,控制不同类型存储器的时候会有一些不同的引脚,其中地址线FSMC_A和数据线FSMC_D是所有控制器都共用的

NOR/SRAM信号 :这部分是NOR 和SRAM这类存储器的控制信号,其中:

  • FSMC_CLK是时钟信号
  • FSMC_NE[4:0]是片选信号 选择SRAM的不同存储区域
  • FSMC_NBL[1:0] 是数据掩码
  • FSMC_NL是输入地址是否有效

再加上下面的公共信号,组成了SRAM的控制引脚:
在这里插入图片描述

FMC地址映射

2、FSMC 连接好外部的存储器并初始化后,就可以直接通过访问地址来读写数据 其中这部分在内存中有着固定的存储地址,存储单元是映射到 STM32 的内部寻址空间的;在程序里,定义一个指向这些地址的指针,然后就可以通过指针直接修改该存储单元的内容,FSMC 外设会自动完成数据访问过程,读写命令之类的操作不需要程序控制,具体如下:

在这里插入图片描述

也就是从0x6000 0000 到0x9FFF FFFF 这1.0GB大小的空间被作为FMC的地址

如果从内核看的话中,左侧的是 Cortex-M3 内核的存储空间分配,右侧是 STM32 FSMC 外设的地址映射。可以看到 FSMC 的 NOR/PSRAM/SRAM/NAND FLASH 以及 PC 卡的地址都在 External RAM 地址空间内。正是因为存在这样的地址映射,使得访问 FSMC 控制的存储器时,就跟访问 STM32 的片上外设寄存器一样(片上外设的地址映射即图中左侧的“Peripheral”区域)

也就是访问FSMC其实就是访问固定的地址,跟寄存器操作异曲同工。

在这里插入图片描述

FSMC 把整个 存储区域分成了 4 个 Bank 区域,NOR 及 SRAM 存储器只能使用 Bank1 的地址,在每个 Bank 的内部又分成了 4 个小块,每个小块有相应的控制引脚用于连接片选信号FSMC_NE1/2/3/4

当 STM32 访问0x6C000000-0x6FFFFFFF 地址空间时,其实就是访问FSMC BANK1的第一块区域

,FSMC_NE1 引脚会自动设置为低电平
在这里插入图片描述

具体是选择那个小快,由地址线(ADDR[27:26])寻址确定
在这里插入图片描述

Bank1的256M字节空间由28根地址线(ADDR[27:0])寻址。这里ADDR 是内部AHB地址总线,其中ADDR[25:0]对应外部存储器地址FSMC_A[25:0],而HADDR[26:27]对4个区进行寻址

在这里插入图片描述

也就是ADDR 28位地址线的头两位,是选择那个分区,后26位是选择对应64M个byte地址

四个区对应二进制:

Bank1:0110-0000 0000-0000 0000-0000 0000-0000 ,即 60 00 00 00;

Bank2:0110-0100 0000-0000 0000-0000 0000-0000 ,即 64 00 00 00;

Bank3:0110-1000 0000-0000 0000-0000 0000-0000 ,即 68 00 00 00;

Bank4:0110-1100 0000-0000 0000-0000 0000-0000 ,即 6c 00 00 00;

FSMC不同位宽操作

FSMC总线除了复用到具体引脚上的FSMC_A[25:0],共计26路地址以外,还有两条内部总线ADDR[27:26]。通过这两路线才区分出了FMC_NE1,FMC_NE2,FMC_NE3和FMC_NE4。即0x60xx xxxx,0x64xx xxxx,0x68xx xxx和0x6Cxx xxxx。

这里要注意的是FSMC中每一个地址,对应的是存储器中的一个字节

假设我们用BANK1的区1,那么0x6000 0000-0x63ff ffff (共64M个字节byte地址) 对应的就是存储器的地址就是64Mx8=512M地址

也就是FSMC的64M个bit地址映射着存储器64M个字节byte地址

那也就是默认情况下存储器地址数据为8位,可以正常读取,但是如果存储器地址数据为16位,32位,就是两个字节一个地址,四个字节一个地址,那么控制16位,32位宽度的存储设备,且不支持单字节访问就比较麻烦了。比如16位宽度的NOR Flash,写入仅支持16位或者32位(通过写入两次16位),写入8位数据是不支持的 。

这样的话,我们本来对应64M的字节byte地址,就变成了32M的双字节byte地址,也就是最后一位无效了,因为地址一次要加2

这个时候,为了方便操作,FMC在硬件设计上就提供了一种解决办法,将内部数据总线ADDR[25:0]措位后接到FMC_A地址引脚上,“丢弃”地址的bit-0,从bit-1开始对地址计数(相当于只计算偶数地址,总共有32M个地址)

FSMC在实际输出地址时,将地址的值右移一位(相当于除以2,变成了偶数地址),输出到实际的地址线上。F103的文档上是这么写的:

在这里插入图片描述

如果是存储器宽度是32位的话,就是4个字节一个地址,就是右移两位

在这里插入图片描述

最终就是配置外部存储器的宽度为16位, FMC将使用内部的ADDR[25:1]地址来作为对外部存储器的寻址地址FMC_A[24:0]。如果存储器宽度为32位, FMC将使用内部的ADDR[25:2]地址进行外部寻址



FSMC寄存器

上图中的第三部分,FSMC是由AHB总线控制配置寄存器来设置的,

NOR/PSRAM/SRAM 设备使用相同的控制器,NAND/PC 卡设备使用相同的控制器,不同的控制器有专用的寄存器用于配置其工作模式。

  • 控制 NOR FLASH 的有 FSMC_BCR1/2/3/4 控制寄存器、FSMC_BTR1/2/3/4 片选时序寄存器以及 FSMC_BWTR1/2/3/4 写时序寄存器。

每种寄存器都有 4 个,分别对应于 4 个不同的存储区域,各种寄存器介绍如下:

  • FSMC_BCR 控制寄存器可配置要控制的存储器类型、数据线宽度以及信号有效极性能参数。
  • FMC_BTR 时序寄存器用于配置 SRAM 访问时的各种时间延迟,如数据保持时间、地址保持时间等。
  • FMC_BWTR 写时序寄存器与 FMC_BTR 寄存器控制的参数类似,它专门用于控制写时序的时间参数

FSMC时钟

FSMC 外设挂载在 AHB 总线上,时钟信号来自于 HCLK(默认 72MHz),控制器的同步时钟输出就是由它分频得到。
它的时钟频率可通过 FSMC_BTR 寄存器的 CLKDIV 位配置,HCLK 与 FSMC_CLK 的分频系数(CLKDIV),可以为 2~16 分频

  • 它可用于与同步类型的 NOR FLASH 芯片通过FSMC_CLK 引脚输出进行同步通讯

  • 对于异步类型的存储器,不使用同步时钟信号,所以时钟分频配置不起作用

FSMC 四种模式

对于存储器来说,可以分为带时钟信号的同步存储器和不带时钟信号的异步存储器

  • 同步突发访问中获得第 1 个数据所需要的等待延迟(DATLAT)
  • 异步突发访问方式,FSMC 主要设置 3 个时间参数:地址建立时间(ADDSET)、数据建立时间(DATAST)和地址保持时间(ADDHLD)。

FSMC 外设支持输出多种不同的时序以便于控制不同的存储器, 综合了 SRAM/ROM、PSRAM 和 NOR Flash 产品的信号特点,定义了 ABCD 四种不同的异步时序模型。选用不同的时序模型时,需要设置不同的时序参数
在这里插入图片描述

FSMC参数设置

我们知道NOR FLASH跟SRAM等存储器除了地址线跟数据线还有其他的控制线跟读写时序,在STM32中,这些时序都很贴心的为我们提供了设置方式,可以很好地匹配不同型号的存储器。
在这里插入图片描述

下面我们来看下不同模式的时序图,通过时序图来看下FSMC具体的流程:

模式1读操作
在这里插入图片描述

  • NOE 是存储器的读信号线,N表示低电平有效,O表示output,E表示enable,

  • NWE 是存储器的写信号线,N表示低电平有效,W表示write,E表示enable,

写存储器时,用NWE输出一个低电平,NOE保持高电平,读存储器时,用NOE输出一个低电平,NWE保持高电平

模式1写操作

在这里插入图片描述

模式A与模式1的区别是NOE的变化和相互独立的读写时序

FSMC 控制异步 NOR FLASH 的时序

下面我们以控制异步 NOR FLASH 使用的模式 B 进行讲解

FSMC 读 NOR FLASH 的时序图:
在这里插入图片描述
在这里插入图片描述

以读时序为例,该图表示一个存储器读操作周期由地址建立周期(ADDSET)数据建立周期(DATAST)以及 2 个 HCLK 周期组成。

  • 在地址建立周期中,地址线发出要访问的地址,数据掩码信号线指示出要读取地址的高、低字节部分,片选信号使能存储器芯片;
  • 地址建立周期结束后读使能信号线发出读使能信号,接着存储器通过数据信号线把目标数据传输
    给 FSMC,FSMC 把它交给内核

FSMC 写 NOR FLASH 的时序图:
在这里插入图片描述

写时序类似,区别是它的一个存储器操作周期仅由地址建立周期(ADDSET)和数据建
立周期(DATAST)组成,且在数据建立周期期间写使能信号线发出写信号,接着 FSMC 把
数据通过数据线传输到存储器中。

当 FSMC 外设被配置成正常工作,并且外部接了 NOR FLASH 时,若向 0x60000000 地址写入数据如 0xABCD,FSMC 会自动在各信号线上产生相应的电平信号,写入数据。FSMC 会控制片选信号 NE1 输出低电平选择相应的 NOR 芯片,然后使用地址线 A[25:0]输出0x60000000,在 NWE 写使能信号线上发出低电平的写使能信号,而要写入的数据信号0xABCD 则从数据线 D[15:0]输出,然后数据就被保存到 NOR FLASH 中了。

FSMC的功能

FSMC的功能总结:将AHB传输信号转换到适当的外部设备协议;满足访问外部设备的时序要求。
所有的外部存储器共享控制器输出的地址、数据和控制信号,每个外部设备可以通过一个唯一的片选信号加以区分。FSMC在任一时刻只访问一个外部设备。

FSMC的特点

1、 FSMC的一大特点是支持不同位宽的异步读写操作。

2、 FSMC的映射地址空间中,不同的BANK是独立的,可用于扩展不同类型的存储器。当FSMC同时使用多个外部存储器时,FSMC会通过总线悬空延时时间参数,来防止访问冲突发生。

3、 支持代码从FSMC扩展的外部存储器中直接运行。不需要首先调入内部SRAM。


关于FSMC的基本原理就说到这里,下一篇我们将讲解下如何使用HAL库来对FSMC进行初始化
请添加图片描述

请添加图片描述

猜你喜欢

转载自blog.csdn.net/as480133937/article/details/123740365