(一)为什么要扩展外部SRAM
内存是芯片工作的重要基础,众所周知,内存更大的芯片,其运行能力和性能往往也会更高。
但是当程序较大,导致芯片内部的内存空间不足以保存该程序时,便可以选择通过外扩存储器,解决内存不足的问题。在实际应用中,可以选择SRAM或者SDRAM作为外部的扩展内存,但由于本次使用的芯片不支持SDRAM的扩展功能,所以选择SRAM作为扩展的对象。
(二)什么是SRAM
简介
SRAM的英文全称为Static Random Assess Memory,译为静态随记存储器。与内存的特性一样,SRAM也属于易失性存储器,当掉电之后,存储器中的内容便会丢失。
存储器型号
本次使用的SRAM的型号为:IS62WV51216
其中,IS表示该芯片的生产公司为ISSI,即芯成半导体有限公司;512表示该芯片的容量为512K word;16则表示数据传输时的数据最小长度为16-Bits。另外,该芯片支持两种不同的高速访问时间,分别为45ns和55ns,该时间表示进行一次数据读写的最短时间要求,本文选择55ns的模式。
容量
512*16Bits = 1MB
原理框图
该SRAM芯片的内部原理图如下:
引脚配置
引脚数量为48Pin,TSOP引脚封装方式的引脚图及其说明如下:
本次使用的SRAM芯片可以选择两种不同的时序进行数据的读取,本文使用下面的一种:
读取数据的时序要求
读取数据时的时序要求如下图所示:
写入数据时序图
本次使用的SRAM芯片可以选择四种不同的时序进行数据的读取,本文选择下面的一种方式:
写入数据的时序要求
对时序的要求如下:
(三)什么是FSMC外设
简介
FSMC的英文全称为Flexible Static Memory Controller,译为静态存储控制器。是STM32F1系列芯片中用于扩展外部存储器的一种外设。通过其名称便可以得知,FSMC外设仅能扩展无须刷新的存储器,比如SRAM、Nor Flash等,而不支持扩展如SDRAM之类需要动态刷新的存储器。
FSMC支持扩展的存储器
按照STM32F1系列的官方文档中的介绍,FSMC支持扩展的存储器包括SRAM、Nor Flash、Nand Flash以及PC卡。
FSMC支持的数据宽度
FSMC支持8-Bits或者16-Bits的数据宽度,但实际使用的数据宽度需要根据存储器的要求进行配置。而我们本次使用的存储器的数据宽度为16-Bits,所以也应该将FSMC的数据宽度配置为16-Bits。
FSMC的内部原理图
由上图可知,在利用FSMC扩展外部存储设备时,有一些引脚是不同类型的设备共用的,但有一些是独有的,所以应该按照本身使用的存储器类型进行配置。由于本次我们扩展的是外部SRAM,所以只需要使用到上图中的红色标记中的引脚即可。其余引脚功能不再赘述。
FSMC的时钟配置
由于SRAM是异步通讯的方式,所以并不需要使用时钟信号。但是,如果扩展的是同步通讯的外部存储器,那么便需要配置该时钟信号。由上图可知,FSMC外设是直接与AHB总线连接的,根据STM32F1系列的时钟树,得知FSMC外设的时钟与系统时钟是相同的,以72MHz为例。
FSMC的存储空间映射
我们回到SRAM的数据读写特性部分,为什么扩展SRAM的主机可以直接通过地址对SRAM中的数据进行读写呢?最根本的原因就是STM32F1系列芯片为FSMC外设预留了专门用于扩展外部存储器的内存空间,且该空间的容量高达1GB。
另外,为了满足扩展不同类型存储器的需求,STM又将这1GB的空间划分为4个BANK,具体的内存分配如下:
由上图可知,SRAM和Nor Flash使用的是内存地址位于0x6000 0000到0x6FFF FFFF之间的Bank1区域。同时,Bank1区域还被分为4个子Bank,分别如下:
并且,对每个子Bank的配置和片选都是相互独立的。片选引脚为FSMC_NE[4:1]。
FSMC的工作模式选择
在实际应用中,可以选择FSMC工作在6种不同的工作模式下。通过FSMC的扩展模式,可以选择不同的模式配置。当使能扩展模式后,可以选择模式A至模式D;如果禁用扩展模式,则可以选择模式1和模式2。不同工作模式下的时序要求是不同的,本文使用的是模式A。
模式A下的时序图
读取数据时序图
写入数据时序图
模式A下的相关配置
STM官方提供了FSMC工作在模式A下的配置要求,如下所示:
1、BCR寄存器配置
2、BTR寄存器配置
3、BTWR寄存器配置
FSMC与SRAM之间的引脚对应关系
为了实现FSMC扩展SRAM的需求,我们需要在设计PCB时,将两者之间的对应引脚进行正确的连接。它们之间的匹配关系如下表所示:
[tr]SRAM引脚FSMC引脚说明[/tr]CLKCLK时钟信号引脚
A[25:0]A[25:0]地址引脚
D[15:0]D[15:0]数据引脚
NE[x] NE[x]
NOENOE输出使能引脚
NWENWE写使能引脚
NL(=NADV)NL(=NADV)地址有效输入(仅PSRAM使用)
NWAITNWAITPSRAM等待FSMC的输入信号引脚
NBL[1]NBL[1]高8-Bits字节有效引脚
NBL[0]NBL[0]低8-Bits字节有效引脚
(四)驱动代码编写
编程时需要使用的工具
1.ST官方提供的库帮助文档,使用起来特别方便,英文名称为《STM32F10x Standard Peripherals Firmware Library》;
2、SRAM的芯片手册,重点是该芯片的时序图以及时序图的要求,由于FSMC操作SRAM不依赖于命令,所以必须严格按照时序图的要求进行编程;
3、STMF1系列的参考手册,重点是寄存器的配置,以及内存分配。
开始进行编程
初始化GPIO
按照STM32参考手册中GPIO章节的描述,需要将FSMC与SRAM之间使用的所有GPIO配置为复用推挽输出。
初始化FSMC
在初始化SRAM时,主要是对FSMC_NORSRAMInitTypeDef和FSMC_NORSRAMTimingInitTypeDef两个结构体进行配置,便可以完成FSMC的初始化。并且,由于上述两个结构体中的信息并非全部都用于FSMC扩展外部SRAM,所以其他无关的信息可以均初始化为默认值即可。下面列出部分代码:
。。.。。.。。.。
//设置存储器类型:SRAM类型
FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;
//设置存储器数据宽度:16位
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
。。.。。.。。.
使能FSMC功能
在使用FSMC外设时,一定要记住使能FSMC外设时钟,以及所选择的Bank区域。比较方便的是,上面两个过程均可以通过库函数实现。
开始进行数据读写
向SRAM指定地址写入数据
上面我们说过,通过直接操作地址,我们便可以实现与SRAM之间的数据交互。但是需要注意的是,访问的地址范围不能超过SRAM允许的地址范围。
比如,我们希望向地址为0x68000000的存储空间中写入数据,此处使用两种方法进行说明:
1、利用地址进行操作:
#define Bank1_SRAM3_START_ADDR (0x68000000)
int main()
{
int * writeData = (int *)Bank1_SRAM3_START_ADDR;
*writeData = 0x12;//向SRAM的0x68000000地址处写入0x12
}
2、利用变量的方式:
#define Bank1_SRAM3_START_ADDR (0x68000000)
int writeData __attribute__((at(Bank1_SRAM3_ADDR)));//必须定义为全局变量
int main()
{
writeData = 0x34;//向SRAM的0x68000000地址处写入0x34
}
结
在利用FSMC扩展外部SRAM时,最重要的便是需要严格按照时序要求进行编程。SRAM本身的工作原理是非常简单的。
(一)为什么要扩展外部SRAM
内存是芯片工作的重要基础,众所周知,内存更大的芯片,其运行能力和性能往往也会更高。
但是当程序较大,导致芯片内部的内存空间不足以保存该程序时,便可以选择通过外扩存储器,解决内存不足的问题。在实际应用中,可以选择SRAM或者SDRAM作为外部的扩展内存,但由于本次使用的芯片不支持SDRAM的扩展功能,所以选择SRAM作为扩展的对象。
(二)什么是SRAM
简介
SRAM的英文全称为Static Random Assess Memory,译为静态随记存储器。与内存的特性一样,SRAM也属于易失性存储器,当掉电之后,存储器中的内容便会丢失。
存储器型号
本次使用的SRAM的型号为:IS62WV51216
其中,IS表示该芯片的生产公司为ISSI,即芯成半导体有限公司;512表示该芯片的容量为512K word;16则表示数据传输时的数据最小长度为16-Bits。另外,该芯片支持两种不同的高速访问时间,分别为45ns和55ns,该时间表示进行一次数据读写的最短时间要求,本文选择55ns的模式。
容量
512*16Bits = 1MB
原理框图
该SRAM芯片的内部原理图如下:
引脚配置
引脚数量为48Pin,TSOP引脚封装方式的引脚图及其说明如下:
本次使用的SRAM芯片可以选择两种不同的时序进行数据的读取,本文使用下面的一种:
读取数据的时序要求
读取数据时的时序要求如下图所示:
写入数据时序图
本次使用的SRAM芯片可以选择四种不同的时序进行数据的读取,本文选择下面的一种方式:
写入数据的时序要求
对时序的要求如下:
(三)什么是FSMC外设
简介
FSMC的英文全称为Flexible Static Memory Controller,译为静态存储控制器。是STM32F1系列芯片中用于扩展外部存储器的一种外设。通过其名称便可以得知,FSMC外设仅能扩展无须刷新的存储器,比如SRAM、Nor Flash等,而不支持扩展如SDRAM之类需要动态刷新的存储器。
FSMC支持扩展的存储器
按照STM32F1系列的官方文档中的介绍,FSMC支持扩展的存储器包括SRAM、Nor Flash、Nand Flash以及PC卡。
FSMC支持的数据宽度
FSMC支持8-Bits或者16-Bits的数据宽度,但实际使用的数据宽度需要根据存储器的要求进行配置。而我们本次使用的存储器的数据宽度为16-Bits,所以也应该将FSMC的数据宽度配置为16-Bits。
FSMC的内部原理图
由上图可知,在利用FSMC扩展外部存储设备时,有一些引脚是不同类型的设备共用的,但有一些是独有的,所以应该按照本身使用的存储器类型进行配置。由于本次我们扩展的是外部SRAM,所以只需要使用到上图中的红色标记中的引脚即可。其余引脚功能不再赘述。
FSMC的时钟配置
由于SRAM是异步通讯的方式,所以并不需要使用时钟信号。但是,如果扩展的是同步通讯的外部存储器,那么便需要配置该时钟信号。由上图可知,FSMC外设是直接与AHB总线连接的,根据STM32F1系列的时钟树,得知FSMC外设的时钟与系统时钟是相同的,以72MHz为例。
FSMC的存储空间映射
我们回到SRAM的数据读写特性部分,为什么扩展SRAM的主机可以直接通过地址对SRAM中的数据进行读写呢?最根本的原因就是STM32F1系列芯片为FSMC外设预留了专门用于扩展外部存储器的内存空间,且该空间的容量高达1GB。
另外,为了满足扩展不同类型存储器的需求,STM又将这1GB的空间划分为4个BANK,具体的内存分配如下:
由上图可知,SRAM和Nor Flash使用的是内存地址位于0x6000 0000到0x6FFF FFFF之间的Bank1区域。同时,Bank1区域还被分为4个子Bank,分别如下:
并且,对每个子Bank的配置和片选都是相互独立的。片选引脚为FSMC_NE[4:1]。
FSMC的工作模式选择
在实际应用中,可以选择FSMC工作在6种不同的工作模式下。通过FSMC的扩展模式,可以选择不同的模式配置。当使能扩展模式后,可以选择模式A至模式D;如果禁用扩展模式,则可以选择模式1和模式2。不同工作模式下的时序要求是不同的,本文使用的是模式A。
模式A下的时序图
读取数据时序图
写入数据时序图
模式A下的相关配置
STM官方提供了FSMC工作在模式A下的配置要求,如下所示:
1、BCR寄存器配置
2、BTR寄存器配置
3、BTWR寄存器配置
FSMC与SRAM之间的引脚对应关系
为了实现FSMC扩展SRAM的需求,我们需要在设计PCB时,将两者之间的对应引脚进行正确的连接。它们之间的匹配关系如下表所示:
[tr]SRAM引脚FSMC引脚说明[/tr]CLKCLK时钟信号引脚
A[25:0]A[25:0]地址引脚
D[15:0]D[15:0]数据引脚
NE[x] NE[x]
NOENOE输出使能引脚
NWENWE写使能引脚
NL(=NADV)NL(=NADV)地址有效输入(仅PSRAM使用)
NWAITNWAITPSRAM等待FSMC的输入信号引脚
NBL[1]NBL[1]高8-Bits字节有效引脚
NBL[0]NBL[0]低8-Bits字节有效引脚
(四)驱动代码编写
编程时需要使用的工具
1.ST官方提供的库帮助文档,使用起来特别方便,英文名称为《STM32F10x Standard Peripherals Firmware Library》;
2、SRAM的芯片手册,重点是该芯片的时序图以及时序图的要求,由于FSMC操作SRAM不依赖于命令,所以必须严格按照时序图的要求进行编程;
3、STMF1系列的参考手册,重点是寄存器的配置,以及内存分配。
开始进行编程
初始化GPIO
按照STM32参考手册中GPIO章节的描述,需要将FSMC与SRAM之间使用的所有GPIO配置为复用推挽输出。
初始化FSMC
在初始化SRAM时,主要是对FSMC_NORSRAMInitTypeDef和FSMC_NORSRAMTimingInitTypeDef两个结构体进行配置,便可以完成FSMC的初始化。并且,由于上述两个结构体中的信息并非全部都用于FSMC扩展外部SRAM,所以其他无关的信息可以均初始化为默认值即可。下面列出部分代码:
。。.。。.。。.。
//设置存储器类型:SRAM类型
FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;
//设置存储器数据宽度:16位
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
。。.。。.。。.
使能FSMC功能
在使用FSMC外设时,一定要记住使能FSMC外设时钟,以及所选择的Bank区域。比较方便的是,上面两个过程均可以通过库函数实现。
开始进行数据读写
向SRAM指定地址写入数据
上面我们说过,通过直接操作地址,我们便可以实现与SRAM之间的数据交互。但是需要注意的是,访问的地址范围不能超过SRAM允许的地址范围。
比如,我们希望向地址为0x68000000的存储空间中写入数据,此处使用两种方法进行说明:
1、利用地址进行操作:
#define Bank1_SRAM3_START_ADDR (0x68000000)
int main()
{
int * writeData = (int *)Bank1_SRAM3_START_ADDR;
*writeData = 0x12;//向SRAM的0x68000000地址处写入0x12
}
2、利用变量的方式:
#define Bank1_SRAM3_START_ADDR (0x68000000)
int writeData __attribute__((at(Bank1_SRAM3_ADDR)));//必须定义为全局变量
int main()
{
writeData = 0x34;//向SRAM的0x68000000地址处写入0x34
}
结
在利用FSMC扩展外部SRAM时,最重要的便是需要严格按照时序要求进行编程。SRAM本身的工作原理是非常简单的。
举报