一.SRAM-IS62WV51216芯片介绍
IS62WV51216是ISSI(Integrated Silicon Solution, Inc)公司生产的一颗16位宽512K(512*16,即1M字节)(这1M字节是怎么算的后面会讲)容量的CMOS静态内存(SRAM)芯片。
STM32 控制器芯片内部有一定大小的 SRAM,SRAM相当于我们电脑中的内存当程序运行时那些临时变量就需要暂存在SRAM中,当我们程序很大时导致内存不足就需要进行内存扩展,由于引脚数量的限制(需要很多地址线与数据线),只有 STM32F103ZE 或以上型号的芯片才可以扩展外部 SRAM。
二.SRAM芯片功能框图
1.SRAM 信号线 只要控制信号线使能了访问,从地址线输入要访问的地址,即可从 I/O数据线写入或读出数据。
2.存储器矩阵
SRAM 内部包含的存储阵列,可以把它理解成一张表格,数据就填在这张表格上。和表格查找一样,指定一个行地址和列地址,就可以精确地找到目标单元格,这是 SRAM 芯片寻址的基本原理。这样的每个单元格被称为存储单元,而这样的表则被称为存储矩阵。
2.地址译码器、列 I/O 及 I/O 数据电路
地址译码器把 N 根地址线转换成 2的N次方根信号线,每根信号线对应一行或一列存储单元,通过地址线找到具体的存储单元,实现寻址。如果存储阵列比较大,地址线会分成行和列地址,或者行、列分时复用同一地址总线,访问数据寻址时先用地址线传输行地址再传输列地址
本实例中的SRAM 比较小,没有列地址线,它的数据宽度为 16 位,即一个行地址对应 2 字节空间,框图中左侧的 A0-A18 是19根地址线一共可以表示 2的19次方=2的8次方x1024=512K 行存储单元,所以它一共能访问 512Kx2字节就等于1M字节大小的空间。 #代表低电平有效
访问时,使用 UB# 或 LB# 线控制数据宽度,例如,当要访问宽度为 16 位的数据时,使用行地址线指出地址,然后把 UB# 和 LB# 线都设置为低电平,那么 I/O0-I/O15 线都有效,它们一起输出该地址的 16 位数据 (或者接收 16 位数据到该地址);当要访问宽度为 8 位的数据时,使用行地址线指出地址,然后把 UB# 或 LB# 其中一个设置为低电平,I/O 会对应输出该地址的高 8 位和低 8 位数据,因此它们被称为数据掩码信号。 STM32与SRAM数据交互:直接统统A0~A18信号线输入一个地址,然后数据通过数据线I/O0 ~ I/O15将我们要传输的数据存储在SRAM中或STM32读取出来
3.SRAM 的读写流程 (1) 主机使用地址信号线发出要访问的存储器目标地址,地址需要持续整个读写时序 (2) 控制片选信号 CS1# 及 CS2# 使能存储器芯片; (3) 若是要进行读操作,则控制读使能信号 OE# 表示要读数据,若进行写操作则控制写使能信号WE# 表示要写数据; (4) 使用掩码信号 LB# 与 UB# 指示要访问目标地址的高、低字节部分; (5) 若是读取过程,存储器会通过数据线向主机输出目标数据,若是写入过程,主要使用数据线向存储器传输目标数据。
三.FSMC外设功能框图
前面带N的代表低电平有效 1.AHB接口 AHB接口为内部CPU和其它总线控制设备访问外部静态存储器提供了通道。 AHB操作被转换到外部设备的操作。当选择的外部存储器的数据通道是16或8位时,在AHB上的32位数据会被分割成连续的16或8位的操作。 AHB时钟(HCLK)是FSMC的参考时钟。
一般的操作规则 请求AHB操作的数据宽度可以是8位、16位或32位,而外部设备则是固定的数据宽度,此时需要保障实现数据传输的一致性。 因此,FSMC执行下述操作规则:
- AHB操作的数据宽度与存储器数据宽度相同:无数据传输一致性的问题。
- AHB操作的数据宽度大于存储器的数据宽度:此时FSMC将AHB操作分割成几个连续的较小数据宽度的存储器操作,以适应外部设备的数据宽度(如:我们扩展的SRAM的数据宽度是16位的,如果我们要写入或者读出32位的数据,则FSMC外设会自动读取或写入2次16位的数据)
- AHB操作的数据宽度小于存储器的数据宽度: 依据外部设备的类型,异步的数据传输有可能不一致。
1.与具有字节选择功能的存储器(SRAM、ROM、PSRAM等)进行异步传输时,FSMC执行读写操作并通过它的字节通道BL[1:0]访问正确的数据的。(与我们要扩展的SRAM16数据宽度对应,当我们要只读写一个字节的内容时我们只需通过UB与LB来控制访问高低字节的目的 ) 2.与不具有字节选择功能的存储器(NOR和16位NAND等)进行异步传输时,即需要对16位宽的闪存存储器进行字节访问;显然不能对存储器进行字节模式访问(只允许16位的数据传输),因此: a. 不允许进行写操作(只能写入16位的数据,不能写入8位数据) b. 可以进行读操作(控制器读出完整的16位存储器数据,只使用需要的字节)。
2.FSMC 的地址映射
从FSMC的角度看,可以把外部存储器划分为固定大小为256M字节的四个存储块。 ● 存储块1用于访问最多4个NOR闪存或PSRAM存储设备。这个存储区被划分为4个NOR/PSRAM区并有4个专用的片选。 ● 存储块2和3用于访问NAND闪存设备,每个存储块连接一个NAND闪存。 ● 存储块4用于访问PC卡设备 每一个存储块上的存储器类型是由用户在配置寄存器中定义的。
使用 FSMC 外接存储器时,其存储单元是映射到 STM32 的内部寻址空间的;在程序里,定义一个指向这些地址的指针,然后就可以通过指针直接修改该存储单元的内容,FSMC 外设会自动完成数据访问过程,读写命令之类的操作不需要程序控制。FSMC的地址映射见图 FSMC 的地址映射。
FSMC 把整个 External RAM 存储区域分成了 4 个 Bank 区域,并分配了地址范围及适用的存储器类型,如 NOR 及 SRAM 存储器只能使用 Bank1 的地址。
所以接线接到哪个片选区,读写操作时必须操作该区对应的地址,假设这里SRAM芯片片选接到了区3,则操作的地址范围为:0x6800 0000 – 0x6BFF FFFF。
在每个 Bank 的内部又分成了 4 个小块,每个小块有相应的控制引脚用于连接片选信号,FSMC_NE[4:1] 信号线可用于选择 BANK1 内部的 4 小块地址区域,见图 Bank1 内部的小块地址分配 ,当 STM32 访问 0x68000000-0x6BFFFFFF地址空间时,会访问到 Bank1 的第 3 小块区域,相应的 FSMC_NE3 信号线会输出控制信号(信号线自动拉低(SRAM片选有效此时就可以传输数据了))。
如何选择存储块区域 HADDR[25:0]包含外部存储器地址。HADDR是字节地址,而存储器访问不都是按字节访问,因此接到存储器的地址线依存储器的数据宽度有所不同,如下表: 3.FSMC 控制 SRAM 的时序
FSMC与SRAM读取时序配置 FSMC的时钟等于HCLK=72MHZ,则一个时钟周期为1/72M=13.8ns **根据 FSMC 配置表达式的配置要求把时间单位 1/72 微秒 (即 1000/72 纳秒=13.8ns) 代入, 可求得 ADDSET= 0,DATAST=1 时即可符合要求。 如: tRC=ADDSET+1+DATAST+1+2 =( 0+1+1+1+2 )13.8 = 69 ns > 55 ns tDOE=DATAST+1 = (1+1)13.8 = 27.7 > 25 ns
不过,经实验总结出该配置在连续读取多个数据的时候会出现问题,更正确的配置为 ADDSET=0,DATAST=2
FSMC与SRAM写操作时序配置 其实就是相当于发送数据方产生的时序能确保数据接收方能接收到数据。 **根据 FSMC 配置表达式的配置要求把时间单位 1/72 微秒 (即13.8ns) 代入 可求得 ADDSET= 0,DATAST=2 时即可符合要求。如: tWC = ADDSET+1+DATAST+1 =( 0+1+2+1 )13.8 = 55.2 ns > 55 ns tPWB = DATAST+1 = (2+1) 13.8 = 41.4 > 40 ns
四.初始化结构体
1.SRAM 时序结构体 红框框住的才是用到的,其他成员变量可以不管 这个结构体成员定义的都是 SRAM 读写时序中的各项时间参数,这些成员的的参数都与FSMC_BRT 及 FSMC_BWTR 寄存器配置对应,各个成员介绍如下: (1) FSMC_AddressSetupTime 本成员设置地址建立时间,即 FSMC 读写时序图 FSMC 模式 A 的读时序 中的 ADDSET值,它可以被设置为 0-0xF 个 HCLK 周期数,按 STM32 标准库的默认配置,HCLK 的时钟频率为 72MHz,即一个 HCLK 周期为 13.8ns。
(2) FSMC_DataSetupTime 本成员设置数据建立时间,即 FSMC 读写时序图 FSMC 模式 A 的写时序 中的 DATAST值,它可以被设置为 0-0xF 个 HCLK 周期数。
(3) FSMC_AccessMode 本成员设置存储器访问模式,不同的模式下 FSMC 访问存储器地址时引脚输出的时序不一样,可选 FSMC_AccessMode_A/B/C/D 模式。一般来说控制 SRAM 时使用 A 模式。
下面的成员变量没有用到
(4) FSMC_AddressHoldTime 本成员设置地址保持时间,它可以被设置为 0-0xF 个 HCLK 周期数。 (5) FSMC_BusTurnAroundDuration 本成员设置总线转换周期,在 NOR FLASH 存储器中,地址线与数据线可以分时复用,总线转换周期就是指总线在这两种状态间切换需要的延时,防止冲突。控制其它存储器时这个参数无效,配置为 0 即可。 (6) FSMC_CLKDivision 本成员用于设置时钟分频,它以 HCLK 时钟作为输入,经过 FSMC_CLKDivision 分频后输出到 FSMC_CLK 引脚作为通讯使用的同步时钟。控制其它异步通讯的存储器时 这个参数无效,配置为 0 即可。 (7) FSMC_DataLatency 本成员设置数据保持时间,它表示在读取第一个数据之前要等待的周期数,该周期指同步时钟的周期,本参数仅用于同步 NOR FLASH 类型的存储器,控制其它类型的存储器时,本参数无效。
这个 FSMC_NORSRAMTimingInitTypeDef 时序结构体配置的延时参数,指向该结构体的指针变量将作为下一节的 FSMCSRAM 初始化结构体的一个成员。 对结构体指针不熟的请参考-》《结构体详解》
2.SRAM 初始化结构体
红框框住的才是用到的,其他成员变量可以不管 (1) FSMC_Bank 本成员用于选择 FSMC 映射的存储区域,它的可选参数以及相应的内核地址映射范,其实就是选择对应的寄存器。 (2) FSMC_MemoryType 本成员用于设置要控制的存储器类型,它支持控制的存储器类型为 SRAM、PSRAM以及 NOR FLASH(FSMC_MemoryType_SRAM/PSRAM/NOR)。 (3) FSMC_MemoryDataWidth 本 成 员 用 于 设 置 要 控 制 的 存 储 器 的 数 据 宽 度, 可 选 择 设 置 成 8 或 16 位(FSMC_MemoryDataWidth_8b /16b)。 (4) FSMC_WriteOperation 这个成员用于设置是否写使能 (FSMC_WriteOperation_ Enable /Disable),禁止写使能的话 FSMC 只能从存储器中读取数据,不能写入。 (5) FSMC_ExtendedMode 本成员用于设置是否使用扩展模式 (FSMC_ExtendedMode_Enable/Disable),在非扩展模式下,对存储器读写的时序都只使用 FSMC_BCR 寄存器中的配置,即下面的FSMC_ReadWriteTimingStruct 结构体成员;在扩展模式下,对存储器的读写时序可以分开配置,读时序使用 FSMC_BCR 寄存器,写时序使用 FSMC_BWTR 寄存器的配置,即下面的 FSMC_WriteTimingStruct 结构体。 (6) FSMC_ReadWriteTimingStruct 本 成 员 是 一 个结构体指针变量, 赋 值 时 使 用 上 一 小 节 中 讲 解 的 时 序 结 构 体FSMC_NORSRAMInitTypeDef 设置,当不使用扩展模式时,读写时序都使用本成员的参数配置。(将结构体变量的地址赋值给这个成员就好了)
(7) FSMC_WriteTimingStruct 同样地,本成员也是一个时序结构体的指针,只有当使用扩展模式时,本配置才有效,它是写操作使用的时序。
下面的成员变量没有用到 (8) FSMC_DataAddressMux 本成员用于设置地址总线与数据总线是否复用 (FSMC_DataAddressMux_Enable /Disable),在控制 NOR FLASH 时,可以地址总线与数据总线可以分时复用,以减少使用STM32 信号线的数量(9) FSMC_BurstAccessMode 本成员用于设置是否使用突发访问模式 (FSMC_BurstAccessMode_Enable/Disable),突 发访问模式是指发送一个地址后连续访问多个数据,非突发模式下每访问一个数据都需要输入一个地址,仅在控制同步类型的存储器时才能使用突发模式。 (10) FSMC_AsynchronousWait 本 成 员 用 于 设 置 是 否 使 能 在 同 步 传 输 时 使 用 的 等 待 信 号 (FSMC_AsynchronousWait_Enable/Disable), 在 控 制 同 步 类 型 的 NOR 或 PSRAM时,存储器可以使用 FSMC_NWAIT 引脚通知 STM32 需要等待。 (11) FSMC_WaitSignalPolarity本成员用于设置等待信号的有效极性,即要求等待时,使用高电平还是低电平(FSMC_WaitSignalPolarity_High/Low)。 (12) FSMC_WrapMode 本成员用于设置是否支持把非对齐的 AHB 突发操作分割成 2 次线性操作 (FSMC_WrapMode_Enable/Disable),该配置仅在突发模式下有效。 (13) FSMC_WaitSignalActive 本 成 员 用 于 配 置 在 突 发 传 输 模 式 时, 决 定 存 储 器 是 在 等 待 状 态 之 前 的 一 个 数 据 周 期 有 效 还 是 在 等 待 状 态 期 间 有 效 (FSMC_WaitSignalActive_BeforeWaitState/DuringWaitState)。 (14) FSMC_WaitSignal 本成员用于设置当存储器处于突发传输模式时,是否允许通过 NWAIT 信号插入等待状态 (FSMC_WaitSignal_Enable/Disable)。
2.程序源码分析
void FSMC_SRAM_Init(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
SRAM_GPIO_Config();
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);
readWriteTiming.FSMC_AddressSetupTime = 0x00;
readWriteTiming.FSMC_DataSetupTime = 0x02;
readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;
readWriteTiming.FSMC_AddressHoldTime = 0x00;
readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
readWriteTiming.FSMC_CLKDivision = 0x00;
readWriteTiming.FSMC_DataLatency = 0x00;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
}
在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]保留,没有用到。
另外结构体初始化函数结合寄存器去看源码就很清楚了
|