做网站有回扣拿吗,台州市住房和城乡建设厅网站,wordpress 文章类型,闵行广州网站建设公司022 - STM32学习笔记 - 扩展外部SDRAM#xff08;一#xff09; - 初识SDRAM和FMC
之前学习了I2C读写EEPROM和SPI读写FLASH#xff0c;学完之后在学习一种新的存储介质–SDRAM。
一、初识SDRAM
我们知道在stm32内部是有一定大小的SRAM#xff08;256Kb#xff09;和FLA…022 - STM32学习笔记 - 扩展外部SDRAM一 - 初识SDRAM和FMC
之前学习了I2C读写EEPROM和SPI读写FLASH学完之后在学习一种新的存储介质–SDRAM。
一、初识SDRAM
我们知道在stm32内部是有一定大小的SRAM256Kb和FLASH1M作为内存和程序存储空间但是如果我们内建的程序体量比较大的时候Stm32内部的存储空间就不够用了这时候就需要在外部进行扩展。
在Stm32扩展内存时可选的有SRAM和SDRAM但是相对来说SDRAM的性价比更高一些所以这里就采用SDRAM来对Stm32进行扩容。给Stm32扩容的方式与PC扩展内存的原理是一样的PC上扩容只需要增加内存条即可而内存条则是集成了很多颗SDRAM颗粒从而组成内存单元在STM32上则是直接将Stm32与SDRAM直接相连。
野火F429开发板上的SDRAM使用的是IS42-45S16400J芯片其存储大小为64Mbit即为8Mb存储空间。 根据官方手册可以看到IS42的芯片内部结构框图可分为5部分
1、信号线与地址控制
芯片框图中①部分为信号线主要由下表所列出的组成。
信号线类型说明CLKI输入同步时钟信号所有输入信号都在 CLK 为上升沿的时候被采集CKEI输入时钟使能信号禁止时钟信号时 SDRAM 会启动自刷新操作CS#I输入片选信号低电平有效CAS#I输入列地址选通为低电平时地址线表示的是列地址RAS#I输入行地址选通为低电平时地址线表示的是行地址WE#I输入写入使能低电平有效DQM[0:1]I输入数据输入/输出掩码信号表示 DQ 信号线的有效部分BA[0:1]I输入Bank 地址输入选择要控制的 BankA[0:11]I输入地址输入DQ[0:15]I/O输入/输出数据输入输出信号
2、逻辑控制单元
通过内部的逻辑控制单元控制整个芯片外部通过片选信号CS、写使能WE、列选通CAS、行选通RAS以及地址线向内部逻辑单元输入命令。输入的命令经过命令译码器译码同时将控制参数保存到模式寄存器中。内部结构框图②部分即为逻辑控制单元。
3、地址控制
在SDRAM中地址线分为“A”类与“BA”类两种地址线其中A类地址线是包含行Row和列Column共用的地址总线而BA类地址线则是用于指定SDRAM内部存储阵列号BANK。并且在命令模式下A类地址线还用于输入一些命令参数。内部结构框图③部分为地址控制单元。
4、存储阵列
与我们常用的Excel一样当我们要读取Excel内的数据时只需要根据列、行号就可以直接定位到对应的单元格SDRAM将内部包含四个BANK类似于Excel中的sheet一样所以我们寻址时只需要指定BANK号列地址行地址就可以找到指定的存储单元。 在SDRAM中向外提供了独立的BA线用于BANK寻址行列地址则复用A类地址线。在IS42芯片内部结构框图中④部分就是内部的存储阵列结构当RAS为低电平时行地址选通地址线A[11:0]表示的地址会被送到行地址译码及锁存器中同时BA[1:0]地址线选中的BANK也会被选中锁存当控制线CAS为低电平时列地址选通地址线A[11:0]表示的地址将送到列地址译码器及锁存器中从而完成寻址操作。
5、数据输入与输出
上述寻址完成后DQ[15:0]表示的数据会通过IS42芯片内部结构框图中⑤标记的输入数据寄存器将输入数据传输到存储阵列中保存数据的输出与之相反。
在野火F429开发板中使用的SDRAM芯片存储整列的数据宽度为16位当与SDRAM进行数据通讯时16位的数据时同步传输的但是根据野火官方资料中提到的实际使用中可能会采用8位、16位宽进行存取数据16位数据线并不是所有时候都是同时使用。比:如传输8位数据的时候只需要使用DQ[7:0]这8位数据线即可而DQ[15:8]这8位数据线必须忽略否则会修改我们期望存储位置之外的内容。因此在实际使用中还会使用DQM[1:0]线来配合没跟DQM线对应8位数据DQM:0为低电平DQM:1为高电平时数据线DQ[7:0]有效而DQ[15:8]无效当DQM[1:0]都为低电平时表示数据线[15:0]均有效。
6、SDRAM命令
控制SDRAM需要用到一些命令通过不同的信号线状态组合可以合成不同的命令。表格中H表示高电平L表示低电平X表示任意电平。
命令CS#RAS#CAS#WE#DQMADDRDQ命令禁止HXXXXXX空操作LHHHXXX行有效LLHHXBank/rowX读命令LHLHL/HBank/colX写命令LHLLL/HBank/colValid预充电LLHLXCodeX自动/自我刷新LLLHXXX加载模式寄存器LLLLXOp-codeX突发停止LHHLXXactive
a、命令禁止
当CS#为高电平时表示命令禁止COMMAND INHBIT将禁止SDRAM执行新的操作但是不能停止当前正在执行的命令。
b、空操作
“ 空操作” NO OPERATION “命令禁止”的反操作 用于选中 SDRAM以便接下来发送命令也就是说当我们要对SDRAM进行后续操作时首先需要下发空操作命令。
c、行有效
进行存储单元寻址时需要先选中要访问的 Bank 和行使它处于激活状态。该操作通过“行有效” (ACTIVE)命令实现发送行有效命令时 RAS 线为低电平同时通过 BA 线以及 A 线发送 Bank 地址和行地址。
d、列读写
当行有效命令确定后紧接着就需要进行列寻址读命令与写命令的时序基本一致通过共用地址线A[11:0]发送列地址同时WE#引脚表示读/写方向WE#为低电平时表示写高电平时表示读。同时读写数据时用DQM#线来确定有效的数据线。在野火F429中仅使用A[7:0]来表示列地址A10线用于控制是否自动预充电A10为高电平时使能预充电低电平时关闭。
e、预充电
在SDRAM中寻址必须要在读写进行操作完成后如果要对同一个BANK的另一行进行寻址就需要将原来有效的行先关闭重新发送行/列地址。BANK关闭当前工作行准备打开新行的操作就是预充电Precharge。
预充电可以通过每次发送读写命令时同时使用A10线控制自动进行预充电也可以通过独立的命令控制。按照官方的解释预充电是对工作行中所有存储整列进行数据重写并对行地址进行复位以准备新行的工作。就是说当前一个时序的读写操作完成后需要对新行进行寻址时需要先将原来的地址线复位然后再重新下发行地址以及列地址。
f、刷新
SDRAM需要不断刷新才能保留住数据刷新与预充电中读写的操作本质是一样的也是SDRAM中比较重要的一项操作。但是预充电是对一个或者所有的BANK的工作行进行操作操作周期不定而刷新是固定周期对所有行进行操作从而保证在SDRAM中很久没使用到的存储单元的数据正确性。
刷新分为两种自动刷新与自我刷新发送命令后CKE时钟为低电平时使用自动刷新否则为自我刷新操作。自动刷新是SDRAM按照周期性时钟周期对SDRAM中所有BANK的工作行进行刷新。而自我刷新则是当时钟线关闭时SDRAM启动内部刷新的操作不需要依靠外部时钟工作。所以这里两者的区别在于是否存在时钟线是否存在周期信号。
e、加载模式寄存器
SDRAM的控制逻辑是根据它的模式寄存器来管理整个系统这个模式寄存器就是通过“加载模式寄存器”来进行配置发送该命令时需要通过地址线表示要存入模式寄存器的参数“OP-Code”关于每条地址线表示的参数如下 突发长度配置Burst LengthADDR[2:0]
突发我们在之前学习DMA的时候接触过了这里在复习一下突发主要是指在同一行中相邻的的存储单元连续进行数据传输的方式连续传输所涉及到的存储单元的数量就是突发长度。
在实际对SDRAM的读写中我们一般不会对存储器一个一个存储单元的去读写这样有耗时又耗力需要不停的发送列地址与读写命令虽然读写延迟相同可以让数据的传输在I/O端是连续的但是会消耗大量的内存/控制资源而且数据在传输过程中也无法接收新的命令因此效率比较低下。
要解决上面的问题需要用到突发传输技术只需要指定起始列地址和突发长度内存会自动从起始位置到后面突发长度的存储单元进行读写不需要控制器连续的提供地址。
在上图中可以看到突发长度可选为1、2、4、8当设定为1时相当于不采用突发模式常见的突发传输长度设定为4或者8。
这里需要注意的是当传输的实际数据长度小于设定的突发长度时可下发突发停止命令结束传输。
突发模式设置Burst TypeADDR[3]
突发模式分为顺序模式与间隔模式两种在顺序模式中操作会按照地址的顺序连续执行如果时间隔模式则是操作地址是跳跃的。这里野火的资料中没有过多介绍间隔模式等到后面学习到了再做补充。顺序模式访问时地址顺序时按照“0-1-2-3-4-5-6-7“的地址序列进行访问。
列地址选通延迟CASLatencyADDR[6:4]
字面意思当发送读命令命令中会包含列地址时列地址选通延迟就是在命令下发后延迟多久后数据线DQ才会输出有效数据可选的延迟周期有1、2、3个时钟周期一般设置为2或者3个时钟周期。
这个配置只针对于读命令写命令时不需要当发出写命令时可以同时发送要写入的数据。
工作模式Operating ModeADDR[8:7]
这一项需要注意在实际使用时必须配置为**“00”**正常模式其他值是测试模式或者被保留的设定。
写突发模式Write Burst ModeADDR[9]
WB用于配置写操作时的突发特性可选择使用BL设置的突发长度或非突发模式。
配置为0时表示使用BL设置的突发长度配置为1时则使用非突发模式。
剩余的三位ADDR[11:10]被保留不需要进行设置。
二、SDRAM的读写流程
上面再初步认识了SDRAM以及相关的命令后我们再看一下SDRAM的读写流程
1、初始化流程 流程如下
1、SDRAM上电并提供至少100us稳定时钟
2、发送“空操作”命令NOP
3、发送“预充电”命令PRECHARGE控制所有BANK进行预充电并等待tRP时间tRP表示预充电与其他命令之间的延迟
4、发送至少2个“自动刷新”命令AUTO REFRESH每个命令后需等待tRC时间tRC表示自动刷新时间注野火在这里标记的为tRFC
5、发送“加载模式寄存器”命令LOAD MODE REGISTER配置SDRAM的工作参数并等待tMRD时间tMRD表示加载模式寄存器命令与行或者刷新命令之间的延迟
6、初始化流程完毕到这里就可以开始读写数据了。
2、读写流程
读时序和写时序过程基本一致如下时序图 读时序 写时序 1、发送行有效ACTIVE命令发送的同时需要下发BANK地址和行地址发送后等待tRCD时间tRCD表示行有效命令与读/写命令之间的延迟
2、发送读/写(READ/WRITE)命令在发送命令的同时发送列地址完成寻址的地址输入。这里需要注意下发读命令后根据模式寄存器的CL定义延迟CL个时钟周期后数据线 DQ 才输出有效数据写命令则是没有CL延迟下发写命令时同时就可以将要写入的数据通过DQ写入SDRAM。另外读/写命令需要通过A[10]地址线进行自动预充电当SDRAM收到带预充电点的读/写命令后需要等待tWR时间后才会开始tWR表示写命令与预充电之间的延迟
3、执行预充电(auto precharge)命令后需要等待tRP时间tRP表示预充电与其它命令之间的延迟
4、本次读写完成后发送第二次“行有效”(ACTIVE)命令准备读写下一个数据
在上图中标号为④的 tRAS表示自刷新周期即在前一个“行有效”与 “预充电” 命令之间的时间标号⑤处的 tRC表示两个行有效命令或两个刷新命令之间的延迟。
关于上面tRP、tRC、tMRD、tRCD、tWR、tRP时间周期是跟具体SDRAM相关具体可查阅数据手册获知这里我截图出来一部分各位先看一下后面在FMC配置的时候再去说怎么看。 三、可变存储控制器FMC
在最开始学习STM32时我们遇到加入固件库后加入FSMC的文件后会报错这里是因为在STM32中为了驱动SRAM、SDRAM、NOR FLASH以及NAND FLASH等类型的存储器需要用到存储控制器即FMC/FSMC。在429中采用的时FMCFlexible Memory Controller即为可变存储控制器在其他STM32控制器中可能只有FSMC控制器Flexible Static Memory Controller可变静态存储控制器两者的区别是在驱动SDRAM时需要定时刷新而这项功能只有FMC才支持FSMC不支持因此FSMC只能支持普通的SDRAM不能支持DDR类型的SDRAM。
1、FMC结构
下图即为FMC外设的结构框图 a、通讯引脚
图中标号为①的即为我们在控制SDRAM中需要用到的引脚虽然看着FMC框图中引脚很多特别时有一部分信号线都是共用的比如其中地址线FMC_A和FMC_D时所有控制器共用具体哪些引脚对应哪些GPIO端口可以在STM32的官方手册中查到这里直接看一下野火F429核心板原理图就知道如何对应的了。 这里需要注意FMC_SDCKE线和FMC_SDNE都各有两条FMC_SDCKE用于控制SDRAM的时钟使能FMC_SDNE用于控制SDRAM芯片的片选使能这两条线用于控制STM32使用不同的存储区域驱动SDRAM使用编号为0的信号线组会使用STM32的存储器区域1使用编号为1的信号线组会使用存储器区域2。
b、存储控器控制器
在FMC的外设图中可以看到NOR/PSRAM/SRAM设备使用的是相同的控制器NAND/PC卡用的是相同的控制器而SDRAM存储器使用独立的控制器。不同的控制器有专用寄存器用于配置器工作模式。
SDRAM控制寄存器及时序寄存器各有两个分别对应SDRAM存储区域1和存储区域2的配置。
FMC_SDCR 控制寄存器可配置 SDCLK 的同步时钟频率、突发读使能、写保护、 CAS延迟、行列地址位数以及数据总线宽度等。
FMC_SDTR 时序寄存器用于配置 SDRAM 访问时的各种时间延迟如 TRP 行预充电 延迟、 TMRD 加载模式寄存器激活延迟等。
FMC_SDCMR 命令模式寄存器用于存储要发送到 SDRAM 模式寄存器的配置以及要向 SDRAM 芯片发送的命令。
FMC_SDRTR 用于配置 SDRAM 的自动刷新周期
c、时钟逻辑控制 FMC外设是挂载在AHB3总线上时钟信号有HCLK提供控制器的时钟输出由其分频而得。用于与SDRAM芯片进行时钟同步的引脚为FMC_SDCLK他的时钟频率可通过FMC_SDCR1寄存器的SDCLK位配置可配置为HCLK的1/2或者1/3我们之前学习RCC时钟树时知道F429的HCLK时钟频率一般配置为180MHz因此与SDRAM通讯的时钟最高频率为90MHz。
2、FMC地址映射
当FMC连接好外部存储器并初始化后可以通过直接访问地址来读取数据之前学习I2C读写EEPROM和SPI读写FLASH时我们需要通过I2C或SPI总线下发地址才能接收到由存储器返回的数据。地址和数据都要通过不同的变量存储并且还得使用代码控制发送读写命令。
当使用FMC访问外部存储器时存储单元是映射到STM32的内存存储空间访问某个地址的数据时可以通过映射的地址指针直接去读写该地址的内容至于底层的事情就交给FMC自动完成即可。 上图中FMC区域中Block3和4为External RAM地址空间主要映射的为NOR/PSRAM/SRAM/NAND FLASH以及PC卡的地址Block5和6为External device区域映射的为SDRAM的地址因此访问挂载在FMC上的存储器时就可以通过直接访问映射的地址直接访问了。
a、存储区域
FMC把SDRAM的存储区域划分为BNAK1和BANK2两块这里只是FMC的地址区域划分并不是SDRAM片内的BANK划分需要注意。FMC的每个BANK都有不一样的其实地址而且有独立的FMC_SDCR控制寄存器、FMC_SDTR时序寄存器、FMC_SDCKE时钟使能信号线和FMC_SDCLK信号线。FMCSDCKE0和FMC_SDCLJ0对应的存储区域1的地址范围是0xC000 0000 ~ 0xCFFF FFFF而FMC_SDCKE1和FMC_SDCLK1对应的存储区域2地址范围是0xD000 0000 ~ 0xDFFF FFFF。
b、SDRAM时序结构体
FMC使用SDRAM存储器时主要是配置时序寄存器以及控制寄存器利用标准库的SDRAM时序结构体以及初始化结构体可以写入参数。
SDRAM时序结构体FMC_SDRAMTimingInitTypeDef
/** * brief 控制SDRAM的时序参数单位为周期每个参数的值范围为1-16个周期*/
typedef struct
{uint32_t FMC_LoadToActiveDelay; /* TMRD:加载模式寄存器命令后的延迟 */uint32_t FMC_ExitSelfRefreshDelay; /* TXSR:自刷新后的延迟 */uint32_t FMC_SelfRefreshTime; /* TRAS自刷新时间 */uint32_t FMC_RowCycleDelay; /* TRC行循环延迟 */uint32_t FMC_WriteRecoveryTime; /* TWR:恢复延迟 */uint32_t FMC_RPDelay; /* TRP:行预充电延迟 */uint32_t FMC_RCDDelay; /* TRCD行到列延迟 */
}FMC_SDRAMTimingInitTypeDef;FMC_LoadToActiveDelay本成员设置TMRD延迟即为发送加载模式寄存器命令后要等待的时间之后才可以再发送行有效或者刷新命令。
FMC_ExitSelfRefreshDelay设置推出TXRS延迟即退出自我刷新命令后要等待的时间之后才可以发送行有效命令。
FMC_SelfRefreshTime设置自我刷新时间TRAS即发送行有效命令后需要等待的时间之后才能执行预充电命令。
FMC_RowCycleDelay设置TRC延迟两个行有效命令之间的延迟以及两个相邻刷新命令之间的延迟。
FMC_WriteRecoveryTime设置TWR延迟即写命令和预充电命令之间的延迟之后才可以执行预充电命令。
FMC_RPDelay设置TRP延迟即预充电命令与其他命令之间的延迟。
FMC_RCDDelay设置TRCD延迟即行有效命令到列读写命令之间的延迟。
c、SDRAM初始化结构体
/* brief FMC SDRAM 初始化结构体类型定义 */
typedef struct
{uint32_t FMC_Bank; /*选择 FMC 的 SDRAM 存储区域*/uint32_t FMC_ColumnBitsNumber; /*定义 SDRAM 的列地址宽度 */uint32_t FMC_RowBitsNumber; /*定义 SDRAM 的行地址宽度 */uint32_t FMC_SDMemoryDataWidth; /*定义 SDRAM 的数据宽度 */uint32_t FMC_InternalBankNumber; /*定义 SDRAM 内部的 Bank 数目 */uint32_t FMC_CASLatency; /*定义 CASLatency 的时钟个数*/uint32_t FMC_WriteProtection; /*定义是否使能写保护模式 */uint32_t FMC_SDClockPeriod; /*配置同步时钟 SDCLK 的参数*/uint32_t FMC_ReadBurst; /*是否使能突发读模式*/uint32_t FMC_ReadPipeDelay; /*定义在 CAS 个延迟后再等待多少个 HCLK 时钟才读取数据 */FMC_SDRAMTimingInitTypeDef* FMC_SDRAMTimingStruct; /*定义 SDRAM 的时序参数*/
} FMC_SDRAMInitTypeDef;FMC_Bank选择 FMC 映射的 SDRAM 存储区域可选择存储区域 1 或 2 (FMC_Bank1/2_SDRAM)。
FMC_ColumnBitsNumber设置要控制的 SDRAM 的列地址宽度可选择 8-11 (FMC_ColumnBits_Number_8/9/10/11b)。
FMC_RowBitsNumber设置要控制的 SDRAM 的行地址宽度可选择设置成 11-13 (FMC_RowBits_Number_11/12/13b)。
FMC_SDMemoryDataWidth设置要控制的 SDRAM 的数据宽度可选择设置成 8、 16 或 32 位(FMC_SDMemory_Width_8/16/32b)。
FMC_InternalBankNumber设置要控制的 SDRAM 的内部 Bank 数目可选择设置成 2 或 4 个 Bank 数目(FMC_InternalBank_Number_2/4)请注意区分这个结构体成员与 FMC_Bank 的区别。
FMC_CASLatency设置 CASLatency 即 CL 的时钟数目可选择设置为 1、 2 或 3 个时钟周期(FMC_CAS_Latency_1/2/3)。
FMC_WriteProtection设置是否使能写保护模式如果使能了写保护则不能向 SDRAM 写入数据正常使用都是禁止写保护的。
FMC_SDClockPeriod设置 FMC 与外部 SDRAM 通讯时的同步时钟参数可以设置成 STM32 的HCLK 时 钟 频 率 的 1/2 、 1/3 或 禁 止 输 出 时 钟 (FMC_SDClock_Period_2/3 或FMC_SDClock_Disable)。
FMC_ReadBurst设置是否使能突发读取模式禁止时等效于 BL1使能时 BL 的值等于模式寄存器中的配置。
FMC_ReadPipeDelay配置在 CASLatency 个时钟周期后再等待多少个 HCLK 时钟周期才进行数据采样在确保正确的前提下这个值设置为越短越好可选择设置的参数值为 0、1 或 2 个 HCLK 时钟周期(FMC_ReadPipe_Delay_0/1/2)。
FMC_SDRAMTimingStruct上面已经学习过了这里不做赘述。
c、SDRAM命令结构体
了解了SDRAM的时序结构体和初始化结构体后还有一个比较重要的结构体需要了解在控制SDRAM时需要发送各种命令通过向FMC的命令模式寄存器FMC_SDCMR写入控制参数就可以向外发送命令这里了解一下FMC_SDRAMCommandTypeDef结构体
typedef struct
{uint32_t FMC_CommandMode; /*要发送的命令 */uint32_t FMC_CommandTarget; /*目标存储器区域 */uint32_t FMC_AutoRefreshNumber; /*若发送的是自动刷新命令此处为发送的刷新次数其它命令时无效 */uint32_t FMC_ModeRegisterDefinition; /*若发送的是加载模式寄存器命令此处为要写入 SDRAM 模式寄存器的参数 */
} FMC_SDRAMCommandTypeDef;FMC_CommandMode配置将要发送的命令具体命令参数如下表
宏命令说明FMC_Command_Mode_normal正常模式命令FMC_Command_Mode_CLK_Enabled使能 CLK 命令FMC_Command_Mode_PALL对所有 Bank 预充电命令FMC_Command_Mode_AutoRefresh自动刷新命令FMC_Command_Mode_LoadMode加载模式寄存器命令FMC_Command_Mode_Selfrefresh自我刷新命令FMC_Command_Mode_PowerDown掉电命令
FMC_CommandTarget选择需要控制的FMC存储区域可选为存储区1或者2FMC_Command_Target_bank1/2。
FMC_AutoRefreshNumber当需要连续多次发送“自动刷新”命令时配置此项可控制发送次数可选参数值为1-16。如果发送的是其他命令时此项无效。
FMC_ModeRegisterDefinition此项对应的是SDRAM的模式寄存器发送加载模式寄存器命令时此项会通过地址线发送到SDRAM的模式寄存器中。
以上三个结构体成员配置完成后就可以调用库函数FMC_SDRAMCmdConfig把这些参数写入到FMC_SDCMR寄存器中之后FMC会自动发送响应的命令了。
OK关于SDRAM和FMC的相关内容就先学习到这里下节就开始实战了相关的参数配置等到实战的时候在做总结。 或者2FMC_Command_Target_bank1/2。
FMC_AutoRefreshNumber当需要连续多次发送“自动刷新”命令时配置此项可控制发送次数可选参数值为1-16。如果发送的是其他命令时此项无效。
FMC_ModeRegisterDefinition此项对应的是SDRAM的模式寄存器发送加载模式寄存器命令时此项会通过地址线发送到SDRAM的模式寄存器中。
以上三个结构体成员配置完成后就可以调用库函数FMC_SDRAMCmdConfig把这些参数写入到FMC_SDCMR寄存器中之后FMC会自动发送响应的命令了。
OK关于SDRAM和FMC的相关内容就先学习到这里下节就开始实战了相关的参数配置等到实战的时候在做总结。