022 - STM32学习笔记 - 扩展外部SDRAM(一) - 初识SDRAM和FMC

news2024/11/22 9:00:02

022 - STM32学习笔记 - 扩展外部SDRAM(一) - 初识SDRAM和FMC

之前学习了I2C读写EEPROM和SPI读写FLASH,学完之后在学习一种新的存储介质–SDRAM。

一、初识SDRAM

我们知道在stm32内部是有一定大小的SRAM(256Kb)和FLASH(1M)作为内存和程序存储空间,但是如果我们内建的程序体量比较大的时候,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 地址输入,选择要控制的 Bank
A[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 Length):ADDR[2:0]

突发我们在之前学习DMA的时候接触过了,这里在复习一下,突发主要是指在同一行中相邻的的存储单元连续进行数据传输的方式,连续传输所涉及到的存储单元的数量就是突发长度。

在实际对SDRAM的读写中,我们一般不会对存储器一个一个存储单元的去读写,这样有耗时又耗力,需要不停的发送列地址与读写命令,虽然读写延迟相同可以让数据的传输在I/O端是连续的,但是会消耗大量的内存/控制资源,而且数据在传输过程中,也无法接收新的命令,因此效率比较低下。

要解决上面的问题,需要用到突发传输技术,只需要指定起始列地址和突发长度,内存会自动从起始位置到后面突发长度的存储单元进行读写,不需要控制器连续的提供地址。

在上图中,可以看到突发长度可选为1、2、4、8,当设定为1时,相当于不采用突发模式,常见的突发传输长度设定为4或者8。

这里需要注意的是,当传输的实际数据长度小于设定的突发长度时,可下发突发停止命令结束传输。

突发模式设置(Burst Type):ADDR[3]

突发模式分为顺序模式间隔模式两种,在顺序模式中,操作会按照地址的顺序连续执行;如果时间隔模式,则是操作地址是跳跃的。这里野火的资料中没有过多介绍间隔模式,等到后面学习到了,再做补充。顺序模式访问时,地址顺序时按照“0-1-2-3-4-5-6-7“的地址序列进行访问。

列地址选通延迟(CASLatency):ADDR[6:4]

字面意思,当发送读命令(命令中会包含列地址)时,列地址选通延迟就是在命令下发后,延迟多久后数据线DQ才会输出有效数据,可选的延迟周期有1、2、3个时钟周期,一般设置为2或者3个时钟周期。

这个配置只针对于读命令,写命令时不需要,当发出写命令时,可以同时发送要写入的数据。

工作模式(Operating Mode):ADDR[8:7]

这一项需要注意,在实际使用时必须配置为**“00”**(正常模式),其他值是测试模式或者被保留的设定。

写突发模式(Write Burst Mode):ADDR[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中采用的时FMC(Flexible 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:设置是否使能突发读取模式,禁止时等效于 BL=1,使能时 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或者2(FMC_Command_Target_bank1/2)。

FMC_AutoRefreshNumber:当需要连续多次发送“自动刷新”命令时,配置此项可控制发送次数,可选参数值为1-16。如果发送的是其他命令时,此项无效。

FMC_ModeRegisterDefinition:此项对应的是SDRAM的模式寄存器,发送加载模式寄存器命令时,此项会通过地址线发送到SDRAM的模式寄存器中。

以上三个结构体成员配置完成后,就可以调用库函数FMC_SDRAMCmdConfig把这些参数写入到FMC_SDCMR寄存器中,之后FMC会自动发送响应的命令了。

OK,关于SDRAM和FMC的相关内容就先学习到这里,下节就开始实战了,相关的参数配置等到实战的时候在做总结。
或者2(FMC_Command_Target_bank1/2)。

FMC_AutoRefreshNumber:当需要连续多次发送“自动刷新”命令时,配置此项可控制发送次数,可选参数值为1-16。如果发送的是其他命令时,此项无效。

FMC_ModeRegisterDefinition:此项对应的是SDRAM的模式寄存器,发送加载模式寄存器命令时,此项会通过地址线发送到SDRAM的模式寄存器中。

以上三个结构体成员配置完成后,就可以调用库函数FMC_SDRAMCmdConfig把这些参数写入到FMC_SDCMR寄存器中,之后FMC会自动发送响应的命令了。

OK,关于SDRAM和FMC的相关内容就先学习到这里,下节就开始实战了,相关的参数配置等到实战的时候在做总结。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/866517.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言案例 分数列求和-11

题目:有一分数列:2 / 1,3 / 2,5 / 3,8 / 5,13 / 8,21 / 13 …求出这个数列的前20项之和。 程序分析 这是一个典型的分数列数学逻辑题,考究这类题目是需要从已知的条件中找到它们的分布规律 我们把前6荐的分子与分母分别排列出来,…

白帽黑帽与linux安全操作

目录 白帽黑帽 Linux安全 白帽黑帽 白帽(White Hat)和黑帽(Black Hat)通常用于描述计算机安全领域中的两种不同角色。白帽黑客通常被认为是合法的安全专家,他们通过合法途径寻找和修复安全漏洞,帮助企业和…

【大数据之Flume】八、Flume 数据流监控

1 Ganglia 的安装与部署 (1)安装 安装规划: 在hadoop102、103、104安装epel-release: sudo yum -y install epel-release在102安装:web、gmetad、gmod: sudo yum -y install ganglia-gmetad sudo yum -y…

【Java】智慧工地云平台源码-支持私有化部署+硬件设备

智慧工地硬件设备包括:AI识别一体机、智能广播音响、标养箱、塔机黑匣子、升降机黑匣子、吊钩追踪控制设备、扬尘监测设备、喷淋设备。 1.什么是AI危险源识别 AI危险源识别是指基于智能视频分析技术,对视频图像信息进行自动分析识别,以实时监…

cmake扩展(1)——VS+CMake创建Qt项目

创建项目 创建CMakeLists #cmake最低版本 cmake_minimum_required(VERSION 3.10) #项目名 project(regextool)#查找所有*.h,*.ui,*.cpp文件,并存入SOURCES中 file(GLOB SOURCES "*.cpp" "*.ui" "*.h")#开启moc set(CMAKE_AUTOMOC O…

SCAU操作系统知识点之(九)单处理器调度

1、处理器调度的类型–长程,中程,短程 例:作业调度程序从处于_____A______状态的队列中选取适当的作业投入运行。 A. 后备 B. 提交 C. 运行 D. 完成 例:**“选一个进程占用 CPU”**是____A_____的功能。 A. 短程调度 B. 中程调度 …

重要日期提醒软件有哪些?有没有适合提醒自己的软件

在时间如潮水般流逝的时代,我们总是在忙碌中度过日子。然而,纵使再忙碌,我们也不能忘记那些温馨而重要的日期,因为这些日期是我们生活中最珍贵的记忆。 无论是生日、纪念日还是重要节日,这些日期都是我们生活的点滴&a…

快速上手ProtoBuf

目录: 需求:引⼊ProtoBuf包创建.proto⽂件编译contacts.proto⽂件,⽣成JAVA⽂件编译contacts.proto⽂件后会⽣成什么序列化与反序列化的使⽤⼩结ProtoBuf使⽤流程 1.需求: 在快速上手中,会编写第一版本的通讯录1.0。…

【JZ36 二叉搜索树与双向链表】

目录 1.题目描述2.算法思想3.代码实现 1.题目描述 2.算法思想 注意点:为什么要引用传参?原因如下: 3.代码实现 class Solution { public:void inorder(TreeNode* cur,TreeNode*& prev){if(curnullptr){return ;}inorder(cur->left,…

pve组网实现公网访问pve,访问电脑,访问pve中的openwrt同时经过openwrt穿透主路由地址nginx全公网访问最佳办法测试研究...

一台路由器 做主路由 工控机 装pve虚拟机 虚拟机里面装一个openwrt, 外网可以直接访问pve,可以访问pve里的openwrt 一台主机 可选择连 有4个口,分别eth0,eth1,eth2,eth3 pve有管理口 这个情况下 ,没有openwrt 直接电脑和pve管理口连在一起就能进pve管理界…

vue3 + vite + ts 封装 SvgIcon组件

环境 vite vue3 ts "vue": "^3.3.4", "vite": "^4.4.0", "typescript": "^5.0.2",# 需要下载的依赖 "vite-plugin-svg-icons": "^2.0.1",不同版本可能存在一定差异, 这篇文章不可能对应所…

数学建模(一)前继概念

课程推荐:数学建模老哥_哔哩哔哩_bilibili 目录 一、什么是数学建模? 二、数学建模的一般步骤 三、数学建模赛题类型 1.预测型 2. 评价类 3.机理分析类 4. 优化类 一、什么是数学建模? 数学建模是利用数学方法解决实际问题的一种实践。…

关于ISO27701隐私信息安全管理体系介绍

01 什么是ISO27701 ISO27701是对ISO27001信息安全管理和ISO27002安全控制的隐私扩展,全称《安全技术—扩展ISO27001和ISO27002的隐私信息管理—要求与指南》,是ISO标准委员会以ISO 27001为基准,以ISO27552为蓝本,建立发布的隐私…

Flink多流处理之Broadcast(广播变量)

写过Spark批处理的应该都知道,有一个广播变量broadcast这样的一个算子,可以优化我们计算的过程,有效的提高效率;同样在Flink中也有broadcast,简单来说和Spark中的类似,但是有所区别,首先Spark中的broadcast是静态的数据,而Flink中的broadcast是动态的,也就是源源不断的数据流.在…

docker-compose redis 一直启动失败

环境: centos 8.x 背景 使用docker-compose 来启动redis docker-compose.yml 如下: version: 3.3 services:redis:image: redis:latestrestart: alwayscontainer_name: redisports:- 6379:6379volumes:- ./data:/redis/data- ./redis.conf:/redis/re…

JMeter 查看 TPS 数据,详细指南

TPS 是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。在 JMeter 中,我们可以使用以下方法查看 T…

AI一键生成数字人

AI一键生成数字人,不玩虚的 阅读时长:10分钟 本文内容: 结合开源AI,一键生成短视频发布到常见的某音,某手平台,狠狠赚一笔 前置知识: 基本的 python 编程知识Jupyter Notebook 使用过Linux 使用过 先上源码…

Linux Idea启动项目打印堆栈日志(JMX监控日志)

说明 Idea更新至新版本(2023.1)后, 在Linux环境下默认会开启JMX监控并输出日志。 关闭JMX监控 打开Configurations配置面板。打开Modify options(ALt M)选项面板。勾选Disable JMX endpoints。 修改Configurations模板 确定不需要打印…

【算法题】螺旋矩阵I (求解n阶螺旋矩阵问题)

一、问题的提出 螺旋矩阵是一种常见的矩阵形式,它的特点是按照螺旋的方式排列元素。n阶螺旋矩阵是指矩阵的大小为nn,其中n为正整数。 二、解决的思路 当N1时,矩阵为; 当N2时,矩阵为; 当N>2(N为偶数如N4)时,矩阵…

通达OA SQL注入漏洞【CVE-2023-4166】

通达OA SQL注入漏洞【CVE-2023-4166】 一、产品简介二、漏洞概述三、影响范围四、复现环境POC小龙POC检测工具: 五、修复建议 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损…