外部SRAM介绍
STM32F407ZGT6内置192K SRAM,通常足够,但对内存要求高如算法或GUI应用可能不足。因此,探索者STM32F4开发板增设了1M SRAM芯片XM8A51216以满足需求。
这里51216代表512*16位的存储单元,也就是 1024B大小的存储单元,也即 1M字节(Byte)。

电路包含19根地址线(A0~18),支持 512K地址空间;
16根数据线(DQ0~15)用于数据传输;
CEn为芯片使能信号,低电平有效。
OEn为输出(读)使能信号,低电平有效。
WEn为写使能信号,低电平有效。
BLEn和 BHEn控制高、低字节。
探索者 STM32F4 开发板使用的是 TSOP44 封装的 XM8A51216 芯片,该芯片直接接在STM32F4 的 FSMC 上。
TSOP44代表薄贴片封装,封装类型44个引脚用于外部连接。

从原理图可以看出,XM8A51216 同 STM32F4 的连接关系:
A[0:18]接 FMSC_A[0:18](不过顺序错乱了)
D[0:15]接 FSMC_D[0:15]
BHEn 接 FSMC_NBL1
BLEn 接 FSMC_NBL0
OEn 接 FSMC_OE
WEn 接 FSMC_WE
CEn 接 FSMC_NE3
上面的连接关系,XM8A51216 的 A[0:18]并不是按顺序连接 STM32F4 的 FMSC_A[0:18],不过这并不影响我们正常使用外部 SRAM,因为地址具有唯一性。所以,只要地址线不和数据线混淆,就可以正常使用外部 SRAM。
FSMC配置步骤
开启FSMC时钟与配置IO:
使能FSMC时钟:
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);//使能FSMC时钟
把 FSMC_D0~15,FSMCA0~18 等相关 IO 口,全配置为复用输出,并使能各 IO 组的时钟。
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用输出
GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC);//PD0,AF12,IO引脚复用配置
设置FSMC BANK1区域3:
包括设置区域 3 的存储器的工作模式、位宽和读写时序等。本章我们使用模式 A、16 位宽,读写共用一个时序寄存器。
关于FSMC的部分名词解释:、
数据地址复用:
在数据地址复用模式下,FSMC通过地址有效信号(NADV)来区分数据线和地址线。
当NADV信号为低时,复用的信号线(ADx,x=0至15)上传输的是地址信号Ax;而当NADV信号变高时,同一信号线上则传输数据信号Dx。
存储器类型(对于模式A):
当你将FSMC_MemoryType设置为FSMC_MemoryType_SRAM时,并且注释中提到“对于模式A”,这是指你正在配置FSMC以模式A工作,该模式特别适用于SRAM类型的存储器。在这种配置下,FSMC将期望外部存储器按照SRAM的规范来响应其控制信号。
FSMC提供了多种工作模式,以适应不同类型的外部存储器,如SRAM、PSRAM、NOR Flash等。
设置数据宽度为16位:。
禁用突发访问模式:
突发访问模式是一种在存储器访问中提高数据传输效率的技术。
突发访问模式允许在一次存储器访问中连续传输多个数据字(burst data),从而减少了每次传输的地址和控制开销。
在突发访问模式下,FSMC首先发送起始地址,并指定要传输的数据字数量(称为突发长度,burst length)。然后,FSMC会连续传输指定长度的数据字,而不需要在每次传输后都重新发送地址信号。这样,FSMC可在一次存储器访问中传输多个数据字,减少地址和控制的信号发送次数。
等待信号极性为低:
外部存储器的访问速度可能与STM32的AHB总线速度不匹配,因此使用等待信号来协调两者之间的通信时序。
当STM32向外部存储器发送一个访问请求(如读或写请求)时,外部存储器可能需要一定的时间来准备数据或完成访问操作。在等待信号有效期间,STM32会暂停当前的访问操作,直到等待信号变为无效状态,再继续执行后续的访问操作。
等待信号在等待状态之前有效:
等待信号的有效时机有两种配置:
等待前有效:等待信号在等待状态开始前就变有效,STM32检测到后立即进入等待状态。
等待中有效:等待信号在等待状态开始后变有效,STM32在等待信号失效后进入等待状态。
禁用回绕模式:
启用回绕模式时,如果访问的地址超出了存储器的物理地址范围,FSMC会自动将地址回绕到存储器的起始地址,继续执行读写操作。
使能等待信号:。
禁用扩展模式:
扩展模式下,FSMC可以为读写操作分别配置不同的时序参数,如地址建立时间、数据建立时间、数据保持时间等。。
禁用异步等待:
在异步通信中,STM32与外部存储器无需同步时钟。为避免数据访问错误,FSMC提供异步等待功能:当外部存储器未准备好时,通过NWAIT信号通知STM32等待,直至存储器准备好并撤销信号,STM32才继续操作。
禁用写突发:。
使能BANK1区域3:
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);//使能BANK1的区域3。
使用BANK1的区域3,因此外部内存首地址为0X68000000。
软件设计
//在指定地址(WriteAddr+Bank1_SRAM3_ADDR)开始,连续写入 n 个字节.
//pBuffer:字节指针
//WriteAddr:要写入的地址
//n:要写入的字节数
void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 n)
{
for(;n!=0;n--)
{
//volatile unsigned 8
*(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer;
WriteAddr++;
pBuffer++;
}
}
//在指定地址((WriteAddr+Bank1_SRAM3_ADDR))开始,连续读出 n 个字节.
//pBuffer:字节指针
//ReadAddr:要读出的起始地址
//n:要写入的字节数
void FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddr,u32 n)
{
for(;n!=0;n--)
{
*pBuffer++=*(vu8*)(Bank1_SRAM3_ADDR+ReadAddr);
ReadAddr++;
}
}
虽然FSMC可能配置为支持16位访问,但实际使用中的数据宽度是8位。
这意味着每次访问只涉及一个字节。由于使用了UB(Upper Byte,高字节)和LB(Lower Byte,低字节)控制来分别访问16位数据中的高字节或低字节,所以在这种情况下,地址只需要按字节(即每次加1)来增加,而不是按16位单元(即每次加2)来增加。
另外,因为我们使用的是 BANK1,区域 3,所以外部 SRAM 的基址为:0x68000000。