STM32 SDRAM知识点

1.SDRAM和SRAM的区别

SRAM不需要刷新电路即能保存它内部存储的数据。而SDRAM(Dynamic Random Access Memory)每隔一段时间,要刷新充电一次,否则内部的数据即会消失,因此SRAM具有较高的性能,但是SRAM也有它的缺点,即它的集成度较低,功耗较SDRAM大 [1],相同容量的SDRAM内存可以设计为较小的体积,但是SRAM却需要很大的体积。同样面积的硅片可以做出更大容量的SDRAM,因此SRAM显得更贵。
异步SRAM,首先明确一下这里的异步的概念:将不依赖于外部时钟工作的设备称为异步设备,将不依赖于外部时钟工作的设备称为异步SRAM。

2.异步和同步的概念

异步—独立的时钟频率,读写受控于地址线与控制使能信号。
同步—所有工作是时钟脉冲边沿开始,地址线、数据线、控制线均与时钟脉冲配合。

同步就相当于是 当客户端发送请求给服务端,在等待服务端响应的请求时,客户端不做其他的事情。当服务端做完了才返回到客户端。这样的话客户端需要一直等待。用户使用起来会有不友好。

异步就是,当客户端发送给服务端请求时,在等待服务端响应的时候,客户端可以做其他的事情,这样节约了时间,提高了效率。

3.SDRAM芯片管脚图
以W9825GKH-6芯片为例
在这里插入图片描述
SDRAM信号线
在这里插入图片描述
4.SDRAM地址控制

SDRAM 包含有“A”以及“BS”两类地址线, A 类地址线是行 (Row) 与列 (Column) 共用的地址
总线, BS 地址线是独立的用于指定 SDRAM 内部存储阵列号 (Bank)。在命令模式下, A 类地址
线还用于某些命令输入参数。

5.SDRAM 的存储阵列

要了解 SDRAM 的储存单元寻址以及“A”、“BA”线的具体运用,需要先熟悉它内部存储阵列的结构,见图 SDRAM 存储阵列模型。
在这里插入图片描述SDRAM 内部包含的存储阵列,可以把它理解成一张表格,数据就填在这张表格上。和表格查找一样,指定一个行地址和列地址,就可以精确地找到目标单元格,这是 SDRAM 芯片寻址的基本原理。这样的每个单元格被称为存储单元,而这样的表则被称为存储阵列 (Bank),目前设计的SDRAM 芯片基本上内部都包含有 4 个这样的 Bank,寻址时指定 Bank 号以及行地址,然后再指定列地址即可寻找到目标存储单元。
在这里插入图片描述
SDRAM 芯片向外部提供有独立的 BA 类地址线用于 Bank 寻址,而行与列则共用 A 类地址线。

6.SDRAM的寻址过程

通讯时当 RAS线为低电平,则“行地址选通器”被选通,地址线 A[12:0] 表示的地址会被输入到“行地址译码及锁存器”中,作为存储阵列中选定的行地址,同时地址线 BS[1:0] 表示的 Bank 也被锁存,选中了要操作的 Bank 号;接着控制 CAS 线为低电平,“列地址选通器”被选通,地址线 A[12:0] 表示的地址会被锁存到“列地址译码器”中作为列地址,完成寻址过程。

7.SDRAM的数据输入输出

若是写 SDRAM 内容,寻址完成后, DQ[15:0] 线表示的数据经过图一种 SDRAM 芯片的内部结构框图 标号中的输入数据寄存器,然后传输到存储器阵列中,数据被保存;数据输出过程相反。W9825GKH型号的 SDRAM 存储阵列的“数据宽度”是 16 位 (即数据线的数量),在与 SDRAM 进行数据通讯时, 16 位的数据是同步传输的,但实际应用中我们可能会以 8 位、 16 位的宽度存取数据,也就是说 16 位的数据线并不是所有时候都同时使用的,而且在传输低宽度数据的时候,我们不希望其它数据线表示的数据被录入。如传输 8 位数据的时候,我们只需要 DQ[7:0] 表示的数据,而 DQ[15:8] 数据线表示的数据必须忽略,否则会修改非目标存储空间的内容。所以数据输入输出时,还会使用 DQM[1:0] 线来配合,每根 DQM 线对应 8 位数据,如“DQM0(LDQM)”为低电平,“DQM1(HDQM)”为高电平时,数据线 DQ[7:0] 表示的数据有效,而 DQ[15:8] 表示的数据无效。

8.SDRAM的命令

控制 SDRAM 需要用到一系列的命令,见图SDRAM 命令表 。各种信号线状态组合产生不同的控制命令。
在这里插入图片描述
(1).命令禁止 (COMMAND INHBIT)
只要 CS 引脚为高电平,即表示“命令禁止” (COMMAND INHBIT),它用于禁止 SDRAM 执行新的命令,但它不能停止当前正在执行的命令。

(2).空操作(NO OPERATION)
“空操作” (NO OPERATION),“命令禁止”的反操作,用于选中 SDRAM,以便接下来发送命令。

(3).行有效(ACTIVE)
进行存储单元寻址时,需要先选中要访问的 Bank 和行,使它处于激活状态。该操作通过“行有效” (ACTIVE) 命令实现,见图行有效命令时序图 ,发送行有效命令时, RAS 线为低电平,同时通过 BA 线以及 A 线发送 Bank 地址和行地址。

(4).列读写(READ和WRITE)
行地址通过“行有效”命令确定后,就要对列地址进行寻址了。“读命令” (READ) 和“写命令”(WRITE) 的时序很相似,见图读取命令时序 ,通过共用的地址线 A 发送列地址,同时使用 WE引脚表示读/写方向, WE 为低电平时表示写,高电平时表示读。数据读写时,使用 DQM 线表示有效的 DQ 数据线。

(5).预充电(PRECHARGE)
SDRAM 的寻址具有独占性,所以在进行完读写操作后,如果要对同一个 Bank 的另一行进行寻址,就要将原来有效(ACTIVE)的行关闭,重新发送行/列地址。 Bank 关闭当前工作行,准备打开新行的操作就是预充电(Precharge)。预充电可以通过独立的命令控制,也可以在每次发送读写命令的同时使用“A10”线控制自动进行预充电。实际上,预充电是一种对工作行中所有存储阵列进行数据重写,并对行地址进行复位,以准备新行的工作。独立的预充电命令时序见图 PRECHARGE 命令时序 。该命令配合使用 A10 线控制,若 A10 为高电平时,所有 Bank 都预充电; A10 为低电平时,使用 BA 线选择要预充电的 Bank。

(6).自动刷新与自我刷新(AUTO REFRESH or SELF REFRESH)

SDRAM 要不断进行刷新 (Refresh) 才能保留住数据,因此它是 DRAM 最重要的操作。刷新操作与预充电中重写的操作本质是一样的。但因为预充电是对一个或所有 Bank 中的工作行操作,并且不定期,而刷新则是有固定的周期,依次对所有行进行操作,以保证那些久久没被访问的存储单元数据正确。刷新操作分为两种:“自动刷新”(Auto Refresh)与“自我刷新” (Self Refresh),发送命令后 CKE时钟为有效时 (低电平),使用自动刷新操作,否则使用自我刷新操作。不论是何种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作。对于“自动刷新”, SDRAM 内部有一个行地址生成器(也称刷新计数器)用来自动地依次生成行地址,每收到一次命令刷新一行。在刷新过程中,所有 Bank 都停止工作,而每次刷新所占用的时间为 N 个时钟周期 (视 SDRAM 型号而定,通常为 N=9),刷新结束之后才可进入正常的工作状态,也就是说在这 N 个时钟期间内,所有工作指令只能等待而无法执行。一次次地按行刷新,刷新完所有行后,将再次对第一行重新进行刷新操作,这个对同一行刷新操作的时间间隔,称为 SDRAM 的刷新周期,通常为 64ms。显然刷新会对 SDRAM 的性能造成影响,但这是它的DRAM 的特性决定的,也是 DRAM 相对于 SRAM 取得成本优势的同时所付出的代价。“自我刷新”则主要用于休眠模式低功耗状态下的数据保存,也就是说即使外部控制器不工作了,SDRAM 都能自己确保数据正常。在发出“自我刷新”命令后,将 CKE 置于无效状态 (低电平),就进入自我刷新模式,此时不再依靠外部时钟工作,而是根据 SDRAM 内部的时钟进行刷新操作。在自我刷新期间除了 CKE 之外的所有外部信号都是无效的,只有重新使 CKE 有效才能退出自我刷新模式并进入正常操作状态。

(7).加载模式寄存器(LOAD MODE REGISTER)

前面提到 SDRAM 的控制逻辑是根据它的模式寄存器来管理整个系统的,而这个寄存器的参数就是通过“加载模式寄存器”命令 (LOAD MODE REGISTER) 来配置的。发送该命令时,使用地址线表示要存入模式寄存器的参数“OP-Code”,各个地址线表示的参数见图模式寄存器解析图 。
在这里插入图片描述
模式寄存器的各个参数介绍如下:

Burst Length

Burst Length 译为突发长度,下面简称 BL。突发是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输所涉及到存储单元(列)的数量就是突发长度。

上文讲到的读/写操作,都是一次对一个存储单元进行寻址,如果要连续读/写就还要对当前存储单元的下一个单元进行寻址,也就是要不断的发送列地址与读/写命令(行地址不变,所以不用再对行寻址)。虽然由于读/写延迟相同可以让数据的传输在 I/O 端是连续的,但它占用了大量的内存控制资源,在数据进行连续传输时无法输入新的命令,效率很低。

为此,人们开发了突发传输技术,只要指定起始列地址与突发长度,内存就会依次地自动对后面相应数量的存储单元进行读/写操作而不再需要控制器连续地提供列地址。这样,除了第一笔数据的传输需要若干个周期外,其后每个数据只需一个周期的即可获得。其实我们在 EERPOM 及FLASH 读写章节讲解的按页写入就是突发写入,而它们的读取过程都是突发性质的。

非突发连续读取模式:不采用突发传输而是依次单独寻址,此时可等效于 BL=1。虽然也可以让数据连续地传输,但每次都要发送列地址与命令信息,控制资源占用极大。

突发连续读取模式:只要指定起始列地址与突发长度,寻址与数据的读取自动进行,而只要控制好两段突发读取命令的间隔周期 (与 BL 相同) 即可做到连续的突发传输。而 BL 的数值,也是不能随便设或在数据进行传输前临时决定。在初始化 SDRAM 调用 LOAD MODE REGISTER 命令时就被固定。 BL 可用的选项是 1、 2、 4、 8,常见的设定是 4 和 8。若传输时实际需要数据长度小于设定的 BL 值,则调用“突发停止” (BURSTTERMINATE) 命令结束传输。

BT

模式寄存器中的 BT 位用于设置突发模式,突发模式分为顺序 (Sequential) 与间隔 (Interleaved) 两种。在顺序方式中,操作按地址的顺序连续执行,如果是间隔模式,则操作地址是跳跃的。跳跃访问的方式比较乱,不太符合思维习惯,我们一般用顺序模式。顺序访问模式时按照“0-1-2-3-4-5-6-7”的地址序列访问。

CASLatency

模式寄存器中的 CASLatency 是指列地址选通延迟,简称 CL。在发出读命令 (命令同时包含列地址) 后,需要等待几个时钟周期数据线 DQ 才会输出有效数据,这之间的时钟周期就是指 CL, CL一般可以设置为 2 或 3 个时钟周期,见图说明图 。

在这里插入图片描述
CL 只是针对读命令时的数据延时,在写命令是不需要这个延时的,发出写命令时可同时发送要写入的数据。

Op Mode
OP Mode 指 Operating Mode, SDRAM 的工作模式。当它被配置为“00”的时候表示工作在正常
模式,其它值是测试模式或被保留的设定。实际使用时必须配置成正常模式。

WB
WB 用于配置写操作的突发特性,可选择使用 BL 设置的突发长度或非突发模式。

Reserved
模式寄存器的最后三位的被保留,没有设置参数。

9.STM32中FMC的简介

STM32F429 使用 FMC 外设来管理扩展的存储器, FMC 是 Flexible Memory Controller 的缩写,译为可变存储控制器。它可以用于驱动包括 SRAM、 SDRAM、 NOR FLASH 以及 NANDFLSAH 类型的存储器。在其它系列的 STM32 控制器中,只有FSMC 控制器 (Flexible Static MemoryController),译为可变静态存储控制器,所以它们不能驱动 SDRAM 这样的动态存储器,因为驱动 SDRAM 时需要定时刷新, STM32F429 的 FMC 外设才支持该功能,且只支持普通的 SDRAM,不支持 DDR类型的 SDRAM。

STM32中FMC的框图
在这里插入图片描述
FMC通讯引脚
在这里插入图片描述
其中比较特殊的是 FMC_A[15:14] 引脚用作 Bank 的寻址线;而 FMC_SDCKE 线和 FMC_SDNE 都各有 2 条, FMC_SDCKE 用于控制 SDRAM 的时钟使能, FMC_SDNE 用于控制 SDRAM 芯片的片选使能。它们用于控制 STM32 使用不同的存储区域驱动 SDRAM,使用编号为 0 的信号线组会使用 STM32 的存储器区域 1,使用编号为 1 的信号线组会使用存储器区域 2。使用不同存储区域时, STM32 访问 SDRAM 的地址不一样。
NOR/PSRAM/SRAM 设备使用相同的控制器, NAND/PC 卡设备使用相同的控制器,而 SDRAM 存储器使用独立的控制器。不
同的控制器有专用的寄存器用于配置其工作模式。

FMC地址映射
FMC 连接好外部的存储器并初始化后,就可以直接通过访问地址来读写数据,这种地址访问与I2C EEPROM、 SPI FLASH 的不一样,后两种方式都需要控制 I2C 或 SPI 总线给存储器发送地址,然后获取数据;在程序里,这个地址和数据都需要分开使用不同的变量存储,并且访问时还需要使用代码控制发送读写命令。而使用 FMC 外接存储器时,其存储单元是映射到 STM32 的内部寻址空间的;在程序里,定义一个指向这些地址的指针,然后就可以通过指针直接修改该存储单元的内容, FMC 外设会自动完成数据访问过程,读写命令之类的操作不需要程序控制。
在这里插入图片描述
FMC中SDRAM的存储区域
FMC 把 SDRAM 的存储区域分成了 Bank1 和 Bank2 两块,这里的 Bank 与 SDRAM 芯片内部的Bank 是不一样的概念,只是 FMC 的地址区域划分而已。每个 Bank 有不一样的起始地址,且有独立的 FMC_SDCR 控制寄存器和 FMC_SDTR 时序寄存器,还有独立的 FMC_SDCKE 时钟使能信号线和 FMC_SDCLK 信号线。 FMC_SDCKE0 和 FMC_SDCLK0 对应的存储区域 1 的地址范围是 0xC000 0000-0xCFFF FFFF,而 FMC_SDCKE1 和 FMC_SDCLK1 对应的存储区域 2 的地址范围是 0xD000 0000- 0xDFFFFFFF。当程序里控制内核访问这些地址的存储空间时, FMC 外设会即会产生对应的时序,对它外接的 SDRAM 芯片进行读写。

External RAM 与 External device 的区别

比较遗憾的是 FMC 给 SDRAM 分配的区域不在 External RAM 区,这个区域可以直接执行代码,而SDRAM 所在的 External device 区却不支持这个功能。这里说的可直接执行代码的特性就是在“常用存储器”章节介绍的 XIP(eXecute In Place) 特性,即存储器上若存储了代码, CPU 可直接访问代码执行,无需缓存到其它设备上再运行;而且 XIP 特性还对存储器的种类有要求, SRAM/SDRAM及 NOR Flash 都支持这种特性,而 NAND FLASH 及 PC 卡是不支持 XIP 的。结合存储器的特性和 STM32FMC 存储器种类的地址分配,就发现它的地址规划不合理了, NAND FLASH 和 PC 卡这些不支持 XIP 的存储器却占据了 External RAM 的空间,而支持 XIP 的 SDRAM 存储器的空间却被分配到了 Externdevice 区。为了解决这个问题,通过配置“SYSCFG_MEMRMP”寄存器的“SWP_FMC”寄存器位可用于交换 SDRAM 与 NAND/PC 卡的地址映射,使得存储在 SDRAM 中
的代码能被执行,只是由于 SDRAM 的最高同步时钟是 90MHz,代码的执行速度会受影响。

本章主要讲解当 STM32 的片内 SRAM 不够用时使用 SDRAM 扩展内存,但假如程序太大,它的程序空间 FLASH 不够用怎么办呢?首先是裁剪代码,目前 STM32F429 系列芯片内部 FLASH空间最高可达 2MB,实际应用中只要我们把代码中的图片、字模等占据大空间的内容放到外部存储器中,纯粹的代码很难达到 2MB。如果还不够用,非要扩展程序空间的话,一种方法是使
用 FMC 扩展 NOR FLASH,把程序存储到 NOR 上,程序代码能够直接在 NOR FLASH 上执行。另一种方法是把程序存储在其它外部存储器,如 SD 卡,需要时把存储在 SD 卡上的代码加载到SRAM 或 SDRAM 上,再在 RAM 上执行代码。

如果 SDRAM 不是用于存储可执行代码,只是用来保存数据的话,在 External RAM 或 Exteranl device 区域都没有区别,不需要与 NAND 的映射地址交换。

10.SDRAM 的初始化流程

SDRAM 的初始化流程, SDRAM 并不是上电后立即就可以开始读写数据的,它需要按步骤进行初始化,对存储矩阵进行预充电、刷新并设置模式寄存器,见图 SDRAM 初始化流程 。
在这里插入图片描述
流程说明如下:
(1) 给 SDRAM 上电,并提供稳定的时钟,至少 100us;
(2) 发送“空操作” (NOP) 命令;
(3) 发送“预充电” (PRECHARGE) 命令,控制所有 Bank 进行预充电,并等待 tRP 时间, tRP 表示预充电与其它命令之间的延迟;
(4) 发送至少 2 个“自动刷新” (AUTO REFRESH) 命令,每个命令后需等待 tRFC 时间, tRFC 表示自动刷新时间;
(5) 发送“加载模式寄存器” (LOAD MODE REGISTER) 命令,配置 SDRAM 的工作参数,并等待tMRD 时间, tMRD 表示加载模式寄存器命令与行有行或刷新命令之间的延迟;
(6) 初始化流程完毕,可以开始读写数据。
其中 tRP、 tRFC、 tMRD 等时间参数跟具体的 SDRAM 有关,可查阅其数据手册获知, STM32 FMC
访问时配置需要这些参数。

11.SDRAM的时序结构体

SDRAM 时序结构体的成员:
在这里插入图片描述这个结构体成员定义的都是 SDRAM 发送各种命令后必须的延迟,它的配置对应到 FMC_SDTR中的寄存器位。所有成员参数值的单位是周期,参数值大小都可设置成“1-16”。关于这些延时时间的定义可以看“SDRAM 初始化流程”和“SDRAM 读写流程”小节的时序图了解。具体参数值根据 SDRAM 芯片的手册说明来配置。各成员介绍如下:

(1) FMC_LoadToActiveDelay
本成员设置 TMRD 延迟 (Load Mode Register to Active),即发送加载模式寄存器命令后要等待的时间,过了这段时间才可以发送行有效或刷新命令。在IS42S32800J芯片数据手册中此参数对应tMRD(Mode Register Program Time,Mode Register Set To Command Delay Time),在W9825G6KH数据手册中此参数对应tRSC(Mode register Set Cycle Time) 。

(2) FMC_ExitSelfRefreshDelay
本成员设置退出 TXSR 延迟 (Exit Self-refresh delay),即退出自我刷新命令后要等待的时间,过了这段时间才可以发送行有效命令,tXSR参数信息,在SDRAM芯片手册中可以查到此参数信息。

(3) FMC_SelfRefreshTime
本成员设置自我刷新时间 TRAS,即发送行有效命令后要等待的时间,过了这段时间才执行预充电命令,tRAS参数信息,在SDRAM芯片手册中可以查到此参数信息。

(4) FMC_RowCycleDelay
本成员设置 TRC 延迟 (Row cycle delay),即两个行有效命令之间的延迟,以及两个相邻刷新命令之间的延迟,tRC参数信息,在SDRAM芯片手册中可以查到此参数信息。

(5) FMC_WriteRecoveryTime
本成员设置 TWR 延迟 (Recovery delay),即写命令和预充电命令之间的延迟,等待这段时间后才开始执行预充电命令。tWR参数信息,在SDRAM芯片手册中可以查到此参数信息,在有些SDRAM的芯片数据手册中此参数为tDPL(Input Data To Precharge Command Delay time)。

(6) FMC_RPDelay
本成员设置 TRP 延迟 (Row precharge delay),即预充电命令与其它命令之间的延迟。tRP参数信息,在SDRAM芯片手册中可以查到此参数信息。

(7) FMC_RCDDelay
本成员设置 TRCD 延迟 (Row to column delay),即行有效命令到列读写命令之间的延迟。tRCD参数信息,在SDRAM芯片手册中可以查到此参数信息。

注意:此结构体填入的是周期的数目而不是具体的时间秒数,所以需要将时间转换为周期的数目。

12.SDRAM 初始化结构体

在这里插入图片描述
(1) FMC_Bank
本成员用于选择 FMC 映射的 SDRAM 存储区域,可选择存储区域 1 或 2(FMC_Bank1/2_SDRAM),对应于STM32芯片中的bank而不是SDRAM芯片中的bank。

(2) FMC_ColumnBitsNumber
本 成 员 用 于 设 置 要 控 制 的 SDRAM 的 列 地 址 宽 度, 可 选 择 8-11 位(FMC_ColumnBits_Number_8/9/10/11b)。具体的列地址宽度需要查看SDRAM芯片的数据手册。

(3) FMC_RowBitsNumber
本成员用于设置要控制的 SDRAM 的行地址宽度,可选择设置成 11-13 位(FMC_RowBits_Number_11/12/13b)。具体的行地址宽度需要查看SDRAM芯片的数据手册。

(4) FMC_SDMemoryDataWidth
本成员用于设置要控制的 SDRAM 的数据宽度,可选择设置成 8、 16 或 32 位(FMC_SDMemory_Width_8/16/32b)。

(5) FMC_InternalBankNumber
本成员用于设置要控制的 SDRAM 的内部 Bank 数目,可选择设置成 2 或 4 个 Bank 数目 (FMC_InternalBank_Number_2/4),请注意区分这个结构体成员与 FMC_Bank 的区别。

(6) FMC_CASLatency
本成员用于设置 CASLatency 即 CL 的时钟数目,可选择设置为 1、 2 或 3 个时钟周期(FMC_CAS_Latency_1/2/3)。注意这个参数的值需要和模式寄存器中的一致,例如这里设置CAS_Latency_2,那么模式寄存器中的CAS也需要设置CAS_Latency_2,否则会出现错误。

(7) FMC_WriteProtection
本成员用于设置是否使能写保护模式,如果使能了写保护则不能向 SDRAM 写入数据,正常使用都是禁止写保护的。

(8) FMC_SDClockPeriod
本成员用于设置 FMC 与外部 SDRAM 通讯时的同步时钟参数,可以设置成STM32 的 HCLK 时钟频率的 1/2、 1/3 或禁止输出时钟 (FMC_SDClock_Period_2/3 或FMC_SDClock_Disable)。

(9) FMC_ReadBurst
本成员用于设置是否使能突发读取模式,禁止时等效于 BL=1,使能时 BL 的值等于模式寄存器中的配置。

(10) FMC_ReadPipeDelay
本成员用于配置在 CASLatency 个时钟周期后,再等待多少个 HCLK 时钟周期才进行数据采样,在确保正确的前提下,这个值设置为越短越好,可选择设置的参数值为 0、1 或 2 个 HCLK 时钟周期 (FMC_ReadPipe_Delay_0/1/2)。

(11) FMC_SDRAMTimingStruct
这个成员就是我们上一小节讲解的 SDRAM 时序结构体了,设置完时序结构体后再把赋值到这里即可。

配置完 SDRAM 初始化结构体后,调用 FMC_SDRAMInit 函数把这些配置写入到 FMC 的 SDRAM控制寄存器及时序寄存器,实现 FMC 的初始化。

13.SDRAM 命令结构体

控制 SDRAM 时需要各种命令,通过向 FMC 的命令模式寄存器 FMC_SDCMR 写入控制参数,即可控制 FMC 对外发送命令
在这里插入图片描述
命令结构体中的各个成员介绍如下:
(1) FMC_CommandMode
本成员用于配置将要发送的命令,它可以被赋值为表 FMC 可输出的 SDRAM 控制命令 中的宏,这些宏代表了不同命令
在这里插入图片描述
(2) FMC_CommandTarget
本 成 员 用 于 选 择 要 控 制 的 FMC 存 储 区 域, 可 选 择 存 储 区 域 1 或2(FMC_Command_Target_bank1/2);

(3) FMC_AutoRefreshNumber
有时需要连续发送多个“自动刷新” (Auto Refresh) 命令时,配置本成员即可控制它发送多少次,可输入参数值为 1-16,若发送的是其它命令,本参数值也需要输入1,否则会导致读写SDRAM错误的问题。如 FMC_CommandMode 成员被配置为宏 FMC_Command_Mode_AutoRefresh,而FMC_AutoRefreshNumber 被设置为 2 时, FMC 就会控制发送 2 次自动刷新命令。
特别注意:即使发送的命令不是FMC_Command_Mode_AutoRefresh时,本参数值也需要输入1,否则会导致读写SDRAM错误。

(4) FMC_ModeRegisterDefinition
当向 SDRAM 发送加载模式寄存器命令时,这个结构体成员的值将通过地址线发送到SDRAM 的模式寄存器中,这个成员值长度为 13 位,各个位一一对应 SDRAM 的模式寄存器。

配置完这些结构体成员,调用库函数 FMC_SDRAMCmdConfig 即可把这些参数写入到FMC_SDCMR 寄存器中,然后 FMC 外设就会发送相应的命令了。

14.设置SDRAM刷新计数器

在SDRAM_InitSequence 函数的最后,我们还调用了库函数 FMC_SetRefreshCount 设置 FMC自动刷新周期,这个函数会向刷新定时寄存器 FMC_SDRTR 写入计数值,这个计数值每个 SDCLK周期自动减 1,减至 0 时 FMC 会自动向 SDRAM 发出自动刷新命令,控制 SDRAM 刷新, SDRAM每次收到刷新命令后,刷新一行,对同一行进行刷新操作的时间间隔称为 SDRAM 的刷新周期。

根据 STM32F4xx 参考手册的说明, COUNT 值的计算公式如下:
刷新速率 = (COUNT + 1) x SDRAM 频率时钟
COUNT =(SDRAM 刷新周期/行数) –20

而查询我们的 SDRAM 芯片规格书,可知它的 SDRAM 刷新周期为 64ms,行数为 8192,可算出
它的 SDRAM 刷新要求:
TRefresh = 64ms/8192=7.813us
即每隔 7.813us 需要收到一次自动刷新命令。

所以:
COUNTA = TRefresh/TSDCLK=7.813x90=703
但是根据要求,如果 SDRAM 在接受读请求后出现内部刷新请求,则必须将刷新速率增加 20 个
SDRAM 时钟周期以获得重充足的裕量。
最后计算出: COUNT=COUNTA-20=683。
以上就是函数 FMC_SetRefreshCount 参数值的计算过程,在Hal库中使用HAL_SDRAM_ProgramRefreshRate(&sdramHandle, 683);函数。

在IS42S32800J芯片数据手册中对应tREF(Refresh Cycle Time (4096)),在W9825G6KH芯片数据手册中对应tREF(Refresh Time(8K Refresh Cycles))。

15.利用STM32CubeMx配置FMC中SDRAM
(1).STM32H743IIT6单片机,利用野火开发板,W9825G6KH芯片(SDRAM芯片),电路原理图如下:
在这里插入图片描述
(2).根据电路图得到:PH6管脚连接到SDRAM芯片的CS管脚,查看STM32的数据手册可知PH6管脚为FMC_SDNE1,PH7管脚连接到SDRAM芯片的CKE管脚,查看STM32的数据手册可知PH7管脚为FMC_SDCKE1,通过STM32的数据手册得知FMC_SDNE1,FMC_SDCKE1对应SDRAM2,FMC_SDNE0,FMC_SDCK0对应SDRAM1。
在这里插入图片描述
在这里插入图片描述
(3).打开STM32CubeMx软件,选择FMC外设,由于电路图中硬件连接的是SDRAM2,所以选择SDRAM2项
配置FMC中的Mode
Clock and chip enable:由于SDRAM2项对应FMC_SDNE1,FMC_SDCKE1,所以此处选择SDCKE1+SDNE1。
Internal bank number:查看W9825G6KH数据手册可知,此SDRAM芯片中有4个Banks,所以此处选择4banks
Address:查看W9825G6KH芯片可知,Address为A0-A12,一共有13根地址线,所以此处选择13bits
Data:查看W9825G6KH芯片可知,Data为DQ0-DQ15,一共有16根数据线,所以此处选择16bits
Byte enable:由于是16位数据线,所以此处选择16-bits byte enable
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置FMC的Configuration
Bank:注意此处的Bank并不是SDRAM芯片(W9825G6KH)中的bank,而是STM32芯片中FMC的SDRAM的Bank,由于FMC_SDNE1,FMC_SDCKE1对应SDRAM2,所以此处选择SDRAM bank2。
Number of column address bits:查看W9825G6KH数据手册可知,列地址线为9bits(A0-A8),所以此处选择9bits。
Number of row address bits:查看W9825G6KH数据手册可知,行地址线为13bits(A0-A12),所以此处选择13bits。

在这里插入图片描述
CAS latency:查看W9825G6KH数据手册可知,CAS Latency=3,所以此处选择3 memory clock cycles
在这里插入图片描述
Write protection:由于需要对SDRAM进行读写,所以此处选择Disabled
SDRAM common clock:这个选项实际上对应hsdram2.Init.SDClockPeriod的值,即对FMC的时钟分频,查看W9825G6KH-6芯片可知,在CAS Latency3的时候时钟为166MHz,在CAS Latency2的时候时钟为133MHZ。由于FMC的时钟为240M,已经超过了W9825G6KH-6,所以需要对FMC的时钟分频,2分频后的时钟为120M,120M低于W9825G6KH芯片的时钟,所以此处选择2 HCLK clock cycles。
SDRAM common burst read:突发读使能,所以此处选择Enabled
SDRAM common read pipe delay:这个选项实际上对应hsdram2.Init.ReadPipeDelay,表示在 CASLatency 个时钟周期后,再等待多少个 HCLK 时钟周期才进行数据采样,这个时间越短越好,这里选择0 HCLK clock cycle。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
由于FMC的时钟分频后时钟为120M,所以1/120=0.00833us=8.333ns
查看W9825G6KH数据手册可知以下参数信息:
Load mode register tRSC=2(tck)
Exit self tXSR=75ns 75/8.33=9
self refresh tRAS=45ns 45/8.33=5.4 6
SDRAM common row cycle delay tRC=65ns 65/8.33=7.8 8
Write revovery time tWR=2(tck) 3
SDRAM common row precharge tRP=20ns 20/8.33=2.4 3
Row to column delay tRCD=20ns 20/8.33=2.4 3
以下填入的值均为周期的数目
Load mode register to active delay:由于此处是周期的数目,根据上面的计算可知此处应填入2
Exit self-refresh delay:根据上面的计算可知此处应填入9
Self-refresh time:根据上面的计算可知此处应填入6
SDRAM common row cycle delay:根据上面的计算可知应填入8
Write recovery time:由于W9825G6KH数据手册中标注的2,但是由于STM32CubeMx软件提示报错,最小值为3,所以此处应填入3
SDRAM common row precharge delay:根据上面的计算可知应填入3
Row to column delay:根据上面的计算可知应填入3

16.初始化SDRAM的序列
由于STM32CubeMx软件中的关于FMC的SDRAM配置,只能配置FMC中的SDRAM而不能初始化SDRAM的序列,所以还需要增加SDRAM的初始化序列的代码。
(1) 给 SDRAM 上电,并提供稳定的时钟,至少 100us;
(2) 发送“空操作” (NOP) 命令;
(3) 发送“预充电” (PRECHARGE) 命令,控制所有 Bank 进行预充电,并等待 tRP 时间, tRP 表示预充电与其它命令之间的延迟;
(4) 发送至少 2 个“自动刷新” (AUTO REFRESH) 命令,每个命令后需等待 tRFC 时间, tRFC 表示自动刷新时间;
(5) 发送“加载模式寄存器” (LOAD MODE REGISTER) 命令,配置 SDRAM 的工作参数,并等待tMRD 时间, tMRD 表示加载模式寄存器命令与行有行或刷新命令之间的延迟;
特别注意:SDRAM_MODEREG_BURST_LENGTH的值不可以配置为_MODEREG_BURST_LENGTH_8,需要配置为SDRAM_MODEREG_BURST_LENGTH_4,否则在使用SDRAM读写数据时会偶尔出错,出错率为百分之80,一定一定要注意。
(6).设置刷新计数器。

代码如下:
在这里插入图片描述
在这里插入图片描述

刷新计数器计算方法
由于本程序中FMC的时钟为240M,二分频后为120M,所以一个时钟周期的时间为1/120M=0.00833us=8.333ns
查看W9825G6KH的数据手册可知,刷新的时间tREF为64ms,一共有8K行,即8*1024=8192行,由此计算得知每一行的刷新时间为64/8192=0.0078125ms=7.8125us=7812.5ns,则刷新一行需要的时钟周期数目为7812.5/8.333=937.53。由于STM32芯片数据手册中规定刷新一行的周期数目需要减去20,则937.53-20=917.53
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
特别注意:在SDRAM初始化序列中,在发送非自动刷新命令时,自动刷新的次数变量Command.AutoRefreshNumber中的值不能为0,需要赋值为1,否则会导致SDRAM读写错误的问题。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值