STM32 控制器芯片内部有一定大小的 SRAM 及 FLASH 作为内存和程序存储空间,但当程序较大,内存和程序空间不足时,就需要在 STM32 芯片的外部扩展存储器。
SDRAM 控制原理
给 STM32 芯片扩展内存与给 PC 扩展内存的原理是一样的,只是 PC 上一般以内存条的形式扩展,内存条实质是由多个内存颗粒(即 SDRAM 芯片)组成的通用标准模块,而STM32 直接与 SDRAM 芯片连接。
SDRAM 芯片外观:
下图是一种型号为 IS42-45S16400J 的 SDRAM芯片内部结构框图:
SDRAM 信号线
除了时钟、地址和数据线,控制 SDRAM 还需要很多信号配合,它们具体作用在描述时序图时进行讲解。
控制逻辑
SDRAM 内部的“控制逻辑”指挥着整个系统的运行,外部可通过 CS、WE、CAS、RAS 以及地址线来向控制逻辑输入命令,命令经过“命令器译码器”译码,并将控制参数保存到“模式寄存器中”,控制逻辑依此运行。
地址控制
SDRAM 包含有“A”以及“BA”两类地址线,A 类地址线是行(Row)与列(Column)共用的地址总线,BA 地址线是独立的用于指定 SDRAM 内部存储阵列号(Bank)。在命令模式下,A 类地址线还用于某些命令输入参数。
SDRAM 的存储阵列
和表格查找一样,指定一个行地址和列地址,就可以精确地找到目标单元格,这是SDRAM 芯片寻址的基本原理。
这样的每个单元格被称为存储单元,而这样的表则被称为存储阵列(Bank),目前设计的 SDRAM 芯片基本上内部都包含有 4 个这样的 Bank,寻址时指定 Bank 号以及行地址,然后再指定列地址即可寻找到目标存储单元。
SDRAM 内部具有多个 Bank 时的结构见图:
SDRAM 芯片向外部提供有独立的 BA 类地址线用于 Bank 寻址,而行与列则共用 A 类地址线。
程序框图中标号④中表示的就是它内部的存储阵列结构:
- 通讯时当 RAS 线为低电平,则“行地址选通器”被选通,地址线 A[11:0]表示的地址会被输入到“行地址译码及锁存器”中,作为存储阵列中选定的行地址;
- 同时地址线 BA[1:0]表示的 Bank 也被锁存,选中了要操作的 Bank 号;
- 接着控制 CAS 线为低电平,“列地址选通器”被选通,地址线 A[11:0]表示的地址会被锁存到“列地址译码器”中作为列地址,完成寻址过程。
数据输入输出
若是写 SDRAM 内容,寻址完成后,DQ[15:0]线表示的数据经过程序框图中标号⑤中的输入数据寄存器,然后传输到存储器阵列中,数据被保存。数据输出过程相反。
本型号的 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]表示的数据无效。
SDRAM 的命令
控制 SDRAM 需要用到一系列的命令,见下表。
各种信号线状态组合产生不同的控制命令。
1. 命令禁止
只要 CS 引脚为高电平,即表示“命令禁止”(COMMAND INHBIT),它用于禁止SDRAM 执行新的命令,但它不能停止当前正在执行的命令。
2. 空操作
“空操作”(NO OPERATION),“命令禁止”的反操作,用于选中 SDRAM,以便接下来发送命令。
3. 行有效
进行存储单元寻址时,需要先选中要访问的 Bank 和行,使它处于激活状态。该操作通过“行有效”(ACTIVE)命令实现,见下图,发送行有效命令时,RAS 线为低电平,同时通过 BA 线以及 A 线发送 Bank 地址和行地址。
4. 列读写
行地址通过“行有效”命令确定后,就要对列地址进行寻址了。“读命令”(READ)和“写命令”(WRITE)的时序很相似,见下图,通过共用的地址线 A 发送列地址,同时使用 WE 引脚表示读/写方向,WE 为低电平时表示写,高电平时表示读。数据读写时,使用DQM 线表示有效的 DQ 数据线。
本型号的 SDRAM 芯片表示列地址时仅使用 A[7:0]线,而 A10 线用于控制是否“自动预充电”,该线为高电平时使能,低电平时关闭。
5. 预充电
SDRAM 的寻址具有独占性,所以在进行完读写操作后,如果要对同一个 Bank 的另一行进行寻址,就要将原来有效(ACTIVE)的行关闭,重新发送行/列地址。
Bank 关闭当前工作行,准备打开新行的操作就是预充电(Precharge)。
预充电可以通过独立的命令控制,也可以在每次发送读写命令的同时使用“A10”线控制自动进行预充电。实际上,预充电是一种对工作行中所有存储阵列进行数据重写,并对行地址进行复位,以准备新行的工作。
独立的预充电命令时序见下图。该命令配合使用 A10 线控制,若 A10 为高电平时,所有 Bank 都预充电;A10 为低电平时,使用 BA 线选择要预充电的 Bank。
6. 刷新
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. 加载模式寄存器
前面提到 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 值,则调用“突发停止”(BURST TERMINATE)命令结束传输。
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
模式寄存器的最后三位的被保留,没有设置参数。
SDRAM 的初始化流程
SDRAM 并不是上电后立即就可以开始读写数据的,它需要按步骤进行初始化,对存储矩阵进行预充电、刷新并设置模式寄存器,见下图:
该流程说明如下:
- 给 SDRAM 上电,并提供稳定的时钟,至少 100us;
- 发送“空操作”(NOP) 命令;
- 发送“预充电”(PRECHARGE) 命令,控制所有 Bank 进行预充电,并等待 tRP 时间,tRP 表示预充电与其它命令之间的延迟;
- 发送至少 2 个“自动刷新”(AUTO REFRESH) 命令,每个命令后需等待 tRFC 时间,tRFC 表示自动刷新时间;
- 发送“加载模式寄存器”(LOAD MODE REGISTER) 命令,配置 SDRAM 的工作参数,并等待 tMRD 时间,tMRD 表示加载模式寄存器命令与行有行或刷新命令之间的延迟;
- 初始化流程完毕,可以开始读写数据。
其中 tRP、tRFC、tMRD等时间参数跟具体的 SDRAM 有关,可查阅其数据手册获知,
STM32 FMC 访问时配置需要这些参数。
SDRAM 的读写流程
初始化步骤完成,开始读写数据。
带 AUTO PRECHARGE 命令的读时序:
带 AUTO PRECHARGE 命令的写时序:
读时序和写时序的命令过程类似:
- 发送“行有效”(ACTIVE) 命令,发送命令的同时包含行地址和 Bank 地址,然后等待 tRCD 时间,tRCD 表示行有效命令与读/写命令之间的延迟;
- 发送“读/写”(READ/WRITE) 命令,在发送命令的同时发送列地址,完成寻址的地址输入。对于读命令,根据模式寄存器的 CL 定义,延迟 CL 个时钟周期后,SDRAM 的数据线 DQ 才输出有效数据,而写命令是没有 CL 延迟的,主机在发送写命令的同时就可以把要写入的数据用 DQ 输入到 SDRAM 中,这是读命令与写命令的时序最主要的区别。
图中的读/写命令都通过地址线 A10 控制自动预充电,而 SDRAM 接收到带预充电要求的读/写命令后,并不会立即预充电,而是等待tWR时间才开始,tWR 表示写命令与预充电之间的延迟; - 执行“预充电”(auto precharge) 命令后,需要等待 tRP 时间,tRP 表示预充电与其它命令之间的延迟;
- 图中的标号④处的 tRAS,表示自刷新周期,即在前一个“行有效”与 “预充电”命令之间的时间;
- 发送第二次“行有效”(ACTIVE) 命令准备读写下一个数据,在图中的标号⑤处的tRC,表示两个行有效命令或两个刷新命令之间的延迟。
其中 tRCD、tWR、tRP、tRAS以及 tRC等时间参数跟具体的 SDRAM 有关,可查阅其数据手册获知,STM32 FMC 访问时配置需要这些参数。