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

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.rhkb.cn/news/85134.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Cartopy】库的安装和瓦片加载(天地图、高德等)

原文作者:我辈李想 版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。 Cartopy基础入门 【Cartopy】库的安装和天地图瓦片加载 【Cartopy】【Cartopy】如何更好的确定边界显示 【Cartopy】【Cartopy】如何丝滑的加载Geojso…

100G光模块的应用案例分析:电信、云计算和大数据领域

100G光模块是一种高速光模块,由于其高速率和低延迟的特性,在电信、云计算和大数据领域得到了广泛的应用。在本文中,我们将深入探讨100G光模块在这三个领域的应用案例。 一、电信领域 在电信领域,100G光模块被广泛用于构建高速通…

机器学习深度学习——卷积的多输入多输出通道

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——从全连接层到卷积 📚订阅专栏:机器学习&&深度学习 希望文章对你们有所帮…

4用opencv玩转图像2

opencv绘制文字和几何图形 黑色底图 显示是一张黑色图片 使用opencv画圆形 #画一个圆 cv2.circle(imgblack_img,center(400,400),radius100,color(0,0,255),thickness10) 画实心圆 只需要把thickness-1。 cv2.circle(imgblack_img,center(500,600),radius50,color(0,0,255),t…

Spark(39):Streaming DataFrame 和 Streaming DataSet 输出

目录 0. 相关文章链接 1. 输出的选项 2. 输出模式(output mode) 2.1. Append 模式(默认) 2.2. Complete 模式 2.3. Update 模式 2.4. 输出模式总结 3. 输出接收器(output sink) 3.1. file sink 3.2. kafka sink 3.2.1. 以 Streaming 方式输出数据 3.2.2. 以 batch …

R语言4_安装BayesSpace

环境Ubuntu22/20, R4.1 你可能会报错说你的R语言版本没有这个库,但其实不然。这是一个在Bioconductor上的库。 同时我也碰到了这个问题,ERROR: configuration failed for package systemfonts’等诸多类似问题,下面的方法可以一并解决。 第…

数据结构刷题训练——链表篇(二)

目录 前言 1.题目一:链表分割 1.1 思路 1.2 分析 1.3 题解 2. 题目二:相交链表 2.1 思路 2.2 分析 2.3 题解 3. 题目三:环形链表 3.1 思路 3.2 分析 3.3 题解 总结 前言 本期继续分享链表相关的OJ题目,在这个专栏博客…

elasticsearch简单入门语法

基本操作 创建不同的分词器 ik_smart: 极简分词 ; ik_max_word: 最细力再度分词 基本的rest命令 methodurl地址描述PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)POSTlocalhost:9200/索引名称/类型名称创建文…

蝉妈妈:2023年抖音电商半年报(附下载)

关于报告的所有内容,公众【营销人星球】获取下载查看 核心观点 平台流量竞争从愈发激烈变为趋于愈加缓和商家直攝总时长与观众君播总时长的总体趋势并没有愈加激烈,从23年上半年各自流量的同比增速来看,观众看摄总时长增速高于商家直攝总时…

电脑合上盖子无线网络不会断开

控制面板\硬件和声音\电源选项\系统设置 最终选择不会采取任何操作 选择不会采取任何操作

Cocos Creator的 Cannot read property ‘applyForce‘ of undefined报错

序: 1、博主是看了这个教程操作的时候出的bug>游戏开发 | 17节课学会如何用Cocos Creator制作3D跑酷游戏 | P9 代码控制对象移动_哔哩哔哩_bilibili 2、其实问题不是出在代码上,但是发现物体就是不平移 3、node全栈的资料》node全栈框架 正文…

逆向破解学习-雷电星海战歌

apk 雷电星海战歌 https://download.csdn.net/download/AdrianAndroid/88200826 安装apk,并试玩 # 通过关键字搜索jad 找到统一支付接口 找到匿名内部类的名称 Hook代码 public class HookComAstPlane extends HookImpl {Overridepublic String packageNam…

竞赛项目 深度学习手势识别算法实现 - opencv python

文章目录 1 前言2 项目背景3 任务描述4 环境搭配5 项目实现5.1 准备数据5.2 构建网络5.3 开始训练5.4 模型评估 6 识别效果7 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习手势识别算法实现 - opencv python 该项目较为新颖…

LeetCode 31题:下一个排列

目录 题目 思路 代码 题目 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如,arr [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序…

Jenkins 中 shell 脚本执行失败却不自行退出

Jenkins 中 执行 shell 脚本时,有时候 shell 执行失败了,或者判断结果是错误的,但是 Jenkins 执行完成后确提示成功 success 。 此时,可以通过条件判断来解决这个问题,让 Jenkins 强制退出并提示执行失败 failed 。 …

Nginx使用proxy_cache指令设置反向代理缓存静态资源

场景 CentOS7中解压tar包的方式安装Nginx: CentOS7中解压tar包的方式安装Nginx_centos7 tar文件 怎么load_霸道流氓气质的博客-CSDN博客 参考上面流程实现搭建Nginx的基础上,实现静态资源的缓存设置。 注意上面安装时的目录是在/opt/nginx目录下&…

win10 + VS2022 安装opencv C++

最近需要用到C opencv,看了很多帖子都需要自己编译opencv源码。为避免源码编译,可以使用VS来配置opencv C。下面是主要过程: 目录 1. 从官网下载 opencv - Get Started - OpenCV 2. 点击这个exe文件进行安装 3. 配置环境变量 4. VS中的项…

java spring cloud 企业电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展 tbms

​ 项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以…

Word转PDF工具哪家安全?推荐好用的文件格式转换工具

Word文档是我们最常见也是最常用的办公软件,想必大家都知道了Word操作起来十分的简单,而且功能也是比较齐全的。随着科技的不断进步,如今也是有越来越多类型的办公文档,PDF就是其中之一,那么word转pdf怎么转?Word转PD…

DSP学习笔记

TI公司提供的c/c编译器,可以将其变成dsp语言。char类型本来是8位,在dsp里面是16位,int也是16位,long才是32位,float也是32位,enum是16位,double32位,long double是32位,p…