FMC篇-SDRAM(IS42S16400J)

news2024/12/23 17:02:19

IS42S16400J

这个东西太常见啦,长方形的。不会过多解释,详细请阅读它的数据手册。

IS42S16400J是一种高速同步动态随机存储器(SDRAM),64Mb的存储容量,采用4个bank,每个bank大小为16Mb,总线宽度为16位,工作电压为3.3V。它是一种常用的存储器芯片,广泛应用于嵌入式系统、通信设备、计算机等领域。

在STM32上使用IS42S16400J,需要先配置STM32的外部存储器控制器(FSMC、FMC)。FSMC是STM32的一种外设,用于连接外部存储器,包括NOR Flash、NAND Flash、SRAM和SDRAM等。在使用IS42S16400J时,需要将FSMC、FMC配置为SDRAM模式,并设置好时序参数。

以下是在STM32上使用IS42S16400J的基本步骤:

配置FSMC控制器,设置SDRAM模式和时序参数。

初始化SDRAM,包括对SDRAM进行预充电和初始化操作。

使用SDRAM进行数据读写操作,可以通过FSMC接口进行读写。

需要注意的是,在使用SDRAM时,需要遵循SDRAM的时序要求,包括时钟频率、时序延迟等参数。同时,还需要注意SDRAM的电源和地线连接,以确保正常工作。

总之,IS42S16400J是一种常用的存储器芯片,可以在STM32等嵌入式系统中使用。在使用时,需要配置好FSMC控制器,并遵循SDRAM的时序要求,以确保正常工作。

常见引脚定义

读写时A0~A11作为行地址线输入,A0~A7作为列地址线输入。

一个bank有12根行地址、8根列地址,总线宽度为16位,所以SDRAM容量=4*4096*256*16=64Mb=8MB。

CKE高电平时使用AUTO REFRESH,通常显高电平,只有在使用SELF REFRESH时CKE低电平。

在写入(0个时钟延迟)和读取(2个时钟延迟)期间激活或停用DQ。

在配置SDRAM工作状态时发送对应指令。

命令

SELF REFRESH COMMAND,自我刷新命令 

DRAM使用电容存储电荷,电容会放电。

自刷新:在电容存储的电荷丢失前读取存储的数据,再重新写进去。刷新周期为64ms,即64ms电容数据会丢失,所以需要保证在64ms内对bank内所有单元均完成一次自刷新。一个bank有4096行,所以需要64ms/4096=15.625us发送一个自刷新指令。

芯片内部在自我刷新操作时,需要刷新的行地址、bank和刷新间隔会自动生成。即使系统断电,自我刷新也可以在没有外部时钟时保留SDRAM数据。

CKE引脚(HIGH->LOW)启动自我刷新操作,自我刷新操作期间,无视所有引脚输入,在设备内部恢复期(tRC)前不能执行下一个命令。

一旦CKE恢复HIGH,必须发出NOP命令(至少两个时钟),以便为完成正在进行的任何内部刷新提供时间。

AUTO REFRESH COMMAND,自动刷新命令

在SELF REFRESH完成之后,由于不确定刷新的最后一行地址,因此应该立即对所有地址执行AUTO REFRESH,自动生成需要刷新的行地址、bank。

ACTIVE AOMMAND,激活命令

在读写操作前,一般需要进行激活操作。

因为SDRAM的行地址线和列地址线都是同一组地址线,分时复用。读写操作发送的是列地址,所以在读写操作之前需要确定行地址和bank。确定行地址后还需要tRCD时间才能把该行打开才可以对该行数据进行读写操作。

激活:BA0、BA1选择bank,A0~A11选择行。在向bank发出预充电指令前,该行将保持打开状态以供访问。

PRECHARGE,预充电命令

在读写操作完成后,所在行(所有行)仍处于打开状态,需要使用预充电命令关闭所在行(所有行),才能使用激活命令打开其它行进行读写操作。

预充电时A10高电平表示对所有bank预充电,低电平表示对某个bank(由BA0、BA1决定)进行预充电

预充电命令用于停用某个bank的空行或所有bank的空行。

执行预充电命令后,所选bank的下一个命令将在经过时段tRP(bank预充电所需的时段)后执行。一旦某个bank已预充电,它将处于空闲状态。

AUTO PRECHARGE,自动预充电命令

自动预充电命令可确保在脉冲串内最早的有效阶段启动预充电。此功能允许单个bank预充电,而无需显式命令。A10高电平可与读写命令一起用于启动自动预充电功能

对于单个单独的读写命令,启用和禁用自动预充电。除非在整页突发模式下,否则自动预充电不适用。读写突发完成后,将自动(不需要发送自动预充电)对寻找的bank或行进行预充电。

READ,读命令

读命令从BA0、BA1输入中选择bank,并启动突发读访问已激活的行。输入A0~A7提供起始列位置。

当A10高电平时,该命令作为自动预充电命令运行。当选择自动预充电时,正在访问的行将在读突发结束时预充电。未选择自动预充电时,该行将保持打开状态,以便后续访问。

DQ的读数据受两个时钟之前(与潜伏期无关)DQM输入上的逻辑电平的影响。

当给定的DQM信号被记录为高电平时,对应的DQ将在两个时钟后变成高阻态。当给定的DQM信号被记录为低电平时,对应的DQ将提供有效数据

发送读指令后,SDRAM会经过2~3个时钟周期才会给出数据(潜伏期,CAS延迟)。

WRITE,写命令

写命令启动对活动行的突发写访问。从BA0、BA1输入中选择bank,从A0~A7输入中提供起始列位置。

当A10高电平时,该命令作为自动预充电命令运行。当选择自动预充电时,正在访问的行将在写突发结束时预充电。未选择自动预充电时,该行将保持打开状态,以便后续访问。

写入内存阵列时,DQ和DQM输入逻辑级上的相应输入数据同时出现。

当给定的DQM信号被记录为高电平时,将忽略相应的数据输入,并且不会对其执行写操作。当给定的DQM信号被记录为低电平时,数据写入存储器。

LOAD MODE REGISTER,加载模式寄存器命令

在加载模式寄存器命令期间,模式寄存器从A0~A11加载。此命令只能在所有bank空闲时发出。

BURST TERMINATE,突发终止命令

突发终止命令通过截断固定长度或整页突发以及突发终止前最近注册的读写命令,强制终止突发读写操作,可以通过此命令结合全页读写模式实现任意长度的读写操作。

COMMAND INHIBIT,命令禁止

命令禁止表示禁止执行新的命令。除CLK信号是否启用外,正在进行的操作不受影响。与空指令(NO OPERATION)效果差不多,当CS低电平时NOP无操作,NOP命令可防止在空闲或等待状态下注册不需要的命令。

上电初始化

SDRAM必须按预定义的方式上电并初始化。

在VDD和VDDQ同时通电后,64Mb SDRAM初始化,DQM和CKE高电平时时钟稳定。

除了命令禁止和NOP外,在发出任何命令之前都需要100us的命令。可以在100us的时间段内应用命令禁止和NOP命令,并应至少持续到时间段结束。如果至少应用了一个命令禁止或NOP命令,则应在满足100us延迟后应用预充电命令。

所有bank都必须预充电,使得所有bank处于空闲状态,之后必须执行至少两个自动预充电周期,自动预充电周期完成后,SDRAM就可以进行模式寄存器编程了。

应该在应用任何操作命令之前加载模式寄存器,因为它将在未知状态下上电。在加载模式寄存器命令之后,必须在任何命令之前断言至少一个NOP命令。

模式寄存器

用于定义SDRAM的特定操作模式。通过LOAD MODE REGISTER命令应用,并将保留存储的信息,直到再次应用或设备失去电源。

模式寄存器必须在所有bank空闲时加载,控制器必须等待指定时间才能启动后续操作。违反任何一个要求都将导致未指定的操作。

CAS延迟

CAS延迟是以时钟周期为单位,从注册一个READ命令到第一个输出数据可用之间的延迟。可以设置为2~3个时钟周期。

实验环节

STM32CubeMX配置

 配置完成后导出工程,还需要额外的配置模式寄存器。创建drive_sdram.c和.h文件,存放于UserCode/Drivers子目录下。

drive_sdram.c

/* Includes ------------------------------------------------------------------*/
#include "drive_sdram.h"
#include "fmc.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define SDRAM_MODEREG_BURST_LENGTH_1             	((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2             	((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4             	((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8             	((uint16_t)0x0003)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      	((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     	((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              	((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              	((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    	((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED 	((uint16_t)0x0000) 
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     	((uint16_t)0x0200) 

#define IS42S16400J_SIZE             				0x400000
#define SDRAM_BANK_ADDR     					 	((uint32_t)0xD0000000)

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/
void SDRAM_InitSequence(void);

/* Private user code ---------------------------------------------------------*/

void SDRAM_Init(void)
{
    SDRAM_InitSequence();
    HAL_SDRAM_WriteProtection_Disable(&hsdram1);
}

void SDRAM_InitSequence(void)
{
  FMC_SDRAM_CommandTypeDef FMC_SDRAMCommandStructure;
  uint32_t tmpr = 0;
  
/* Step 3 --------------------------------------------------------------------*/
  /* Configure a clock configuration enable command */
  FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
  FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
  FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
  /* Wait until the SDRAM controller is ready */ 
  while(HAL_SDRAM_GetState(&hsdram1) == HAL_SDRAM_STATE_BUSY)
  {
  }
  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &FMC_SDRAMCommandStructure, 0x1000);
    
  
/* Step 4 --------------------------------------------------------------------*/
  /* Insert 100 ms delay */
  HAL_Delay(100);
    
/* Step 5 --------------------------------------------------------------------*/
  /* Configure a PALL (precharge all) command */ 
  FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_PALL;
  FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
  FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
  /* Wait until the SDRAM controller is ready */ 
  while(HAL_SDRAM_GetState(&hsdram1) == HAL_SDRAM_STATE_BUSY)
  {
  }
  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &FMC_SDRAMCommandStructure, 0x1000);
  
/* Step 6 --------------------------------------------------------------------*/
  /* Configure a Auto-Refresh command */ 
  FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  FMC_SDRAMCommandStructure.AutoRefreshNumber = 2;
  FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
  /* Wait until the SDRAM controller is ready */ 
  while(HAL_SDRAM_GetState(&hsdram1) == HAL_SDRAM_STATE_BUSY)
  {
  }
  /* Send the  first command */
  HAL_SDRAM_SendCommand(&hsdram1, &FMC_SDRAMCommandStructure, 0x1000);
  
/* Step 7 --------------------------------------------------------------------*/
  /* Program the external memory mode register */
  tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |
                   SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
                   SDRAM_MODEREG_CAS_LATENCY_3           |
                   SDRAM_MODEREG_OPERATING_MODE_STANDARD |
                   SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
  
  /* Configure a load Mode register command*/ 
  FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
  FMC_SDRAMCommandStructure.ModeRegisterDefinition = tmpr;
  /* Wait until the SDRAM controller is ready */ 
  while(HAL_SDRAM_GetState(&hsdram1) == HAL_SDRAM_STATE_BUSY)
  {
  }
  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &FMC_SDRAMCommandStructure, 0x1000);
  
/* Step 8 --------------------------------------------------------------------*/

  /* Set the refresh rate counter */
  /* SDRAM Refresh Timer register(FMC_SDRTR)
	refresh rate = (sdram refresh rate * sdram clock frequency) - 20
	sdram refresh rate = sdram refresh period / Number of rows
  
	example:
		sdram refresh rate = 64ms / 4096 = 15.625us
		refresh rate = (15.625 * 90Mhz) - 20 = 1386.25
  */
  /* Set the device refresh counter */
  HAL_SDRAM_ProgramRefreshRate(&hsdram1, 1386);
  /* Wait until the SDRAM controller is ready */ 
  while(HAL_SDRAM_GetState(&hsdram1) == HAL_SDRAM_STATE_BUSY)
  {
  }
}

SDRAM的起始地址可以看STM32F429的数据手册。

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

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

相关文章

eDiary-白日梦电子记事本基本使用说明【记事本导出和导入方法、本地数据迁移方法、记录工作日报、日历代办等】

文章目录 说明笔记导出与导入导出导入 本地数据迁移及备份本地备份说明恢复 记录工作日报记录今天发生美事等日历代办 说明 因为公司大佬分享资料,需要用到白日梦这个电子记事本,所以才了解到这个软件,体量小,功能高级&#xff0…

图数据库 NebulaGraph 的内存管理实践之 Memory Tracker

数据库的内存管理是数据库内核设计中的重要模块,内存的可度量、可管控是数据库稳定性的重要保障。同样的,内存管理对图数据库 NebulaGraph 也至关重要。 图数据库的多度关联查询特性,往往使图数据库执行层对内存的需求量巨大。本文主要介绍 …

Amazon 一周回顾 – 2022 年 7 月 18 日

上周,Amazon 峰会(纽约)在贾维茨中心线下举办,有数千名与会者以及 100 多家赞助商和合作伙伴参加。在主题演讲中,Amazon 首席开发人员倡导者 Martin Beeby 谈到了云基础设施的创新如何帮助客户适应挑战并抓住新的机遇。…

开源之夏 2023 | 欢迎参加openEuler A-Tune SIG和Base-service SIG开发任务

开源之夏是中国科学院软件研究所联合openEuler发起的开源软件供应链点亮计划系列暑期活动,旨在鼓励在校学生积极参与开源软件的开发维护,促进优秀开源软件社区的蓬勃发展。活动联合各大开源社区,针对重要开源软件的开发与维护提供项目&#x…

linux Fd以及重定向讲解

感谢你的阅读,是对我最大的鼓励!!!! 目录 fd理解 文件操作重定向 让我们回顾C语言文件操作 首选我们要知道2个知识点: 额外知识点 如何理解一切皆文件呢? 当父进程fork创建子进程是否创建…

移动出行下半场,T3出行做起“加减法”

五一小长假外出聚餐时,在T3出行打了一辆网约车,车厢上居然印了《灌篮高手》的动漫角色。 松果财经了解到,这是T3出行在上海、深圳、广州、成都、重庆及武汉等六大城市与《灌篮高手》展开的合作,大概有数百辆定制网约车印上了《灌篮…

现在Java和大数据开发还能学来找工作吗?

卷是必然的,不止java和大数据,也不止IT这个行业~ 这两个方向其实都是不错的方向,java虽然卷,但是技能在手也不怕。大数据的发展前景也是不容小觑的。关键就在于你未来想发展的方向以及个人的兴趣 首先先给你吃一颗定心丸&#x…

HTML零基础快速入门(详细教程)

1&#xff0c;HTML代码特点 <html><head></head><body>hello world!</body> </html>HTML代码有以下特点&#xff1a; html代码是通过标签来组织的&#xff0c;而标签是由尖括号< >组织的&#xff0c;也可被叫作元素&#xff08;ele…

SpringCloudAlibaba项目打成war后无法注册到Nacos,无法连接到Nacos Server

SpringCloudAlibaba项目打成war后无法注册到Nacos,无法连接到Nacos Server 背景原因解决重新打包、部署&#xff1a;正常&#xff01; 参考&#xff1a;https://www.jb51.net/article/233940.htm 背景 正常jar(使用内嵌tomcat)包是可以连接并注册到Nacos的&#xff0c;但是将…

uniapp源码编译打包App上架发布详细教程

基础配置 App打包&#xff08;使用Hbuilder进行App打包&#xff09; 视频教程 视频地址&#xff1a; https://www.bilibili.com/video/BV1Kg411g7cb 一、修改接口地址 1.打开uni-app下config/app.js修改接口地址&#xff0c;将下图红框中的地址修改成您的域名 二、配置参…

研发工程师玩转Kubernetes——安装microk8s和Docker

《研发工程师玩转Kubernetes》将立足于实操&#xff0c;试图由浅入深探索Kubernetes世界。于是在技术选型和内容上也将由易到难&#xff0c;由简单到复杂。 为了降低进入的门槛&#xff0c;我们前期将不考虑多实例&#xff08;机器&#xff09;的部署&#xff0c;而采用单机部署…

ThreadLocal 的原理讲述 + 基于ThreadLocal实现MVC中的M层的事务控制

ThreadLocal 的原理讲述 基于ThreadLocal实现MVC中的M层的事务控制 文章目录 ThreadLocal 的原理讲述 基于ThreadLocal实现MVC中的M层的事务控制每博一文案1. ThreadLocal 给概述2. 抛砖引玉——>ThreadLocal3. ThreadLocal 的模拟编写4. ThreadLocal 源码原理分析5. Thre…

云厂商降价潮背后:来中小企业战场「拼刺刀」

如果说过往云厂商的降价打响的是从C端进军B端的营销战&#xff0c;那么在这一轮降价潮背后&#xff0c;对应的则是云厂商从大型KA客户向中小企业进军的信号&#xff0c;强被集成&#xff0c;强获客。 云厂商又一轮降价潮袭来。 5月16日&#xff0c;移动云宣布部分产品线最高降…

技术探秘:揭秘Bean Factory与FactoryBean的区别!

大家好&#xff0c;我是小米&#xff0c;一个热衷于技术分享的29岁小编。今天&#xff0c;我们来聊一聊在Spring框架中常用的两个概念&#xff1a;beanFactory和FactoryBean。它们虽然看似相似&#xff0c;但实际上有着不同的用途和作用。让我们一起来揭开它们的神秘面纱吧&…

SaleSmartly聊天机器人如何帮助您的电商业务(二)

上文为大家介绍了两类机遇SaleSmartly&#xff08;ss客服)强大的自动化编辑器构建的两类聊天机器人&#xff0c;接下来继续为大家介绍两种类型的聊天机器人。SaleSmartly&#xff08;ss客服&#xff09;可构建的聊天机器人还有以下两类&#xff1a; 3. NLP聊天机器人 SaleSma…

Datax+Datax-web2.1实现MySQL数据库数据同步(二)

目录 流程1、创建项目2、创建数据源3、创建任务模板4、构建任务5、执行同步任务 安装文档参考&#xff1a;https://blog.csdn.net/zhanremo3062/article/details/130728287 流程 这里以2.1.2版本为例&#xff0c;datax-web使用起来还是很顺滑的&#xff0c;操作流程跟其他任务…

结合自由能计算

结合自由能计算 打分函数 背景 打分函数广泛应用于基于结构的计算辅助药物设计&#xff0c;其通过定量化评估药-靶的相互作用为药物研发中的药效评估提供理论依据&#xff0c;提高活性化合物甄别的效率。定量评估药物与靶标蛋白的相互作用通常分为两步&#xff0c;一步是对接…

Android之 fragment页面碎片详解

一 简介 1.1 Fragment是Android3.0新增的概念&#xff0c;中文意思是“碎片”&#xff0c;它与Activity非常相似&#xff0c;是用来描述一些行为或者一部分用户界面 1.2 可以在一个单独的Activity中建立多个Fragment面板&#xff0c;也可以在多个Activity中复用Fragment 1.3…

【OpenCV】C++红绿灯轮廓识别+ROS话题实现

目录 前言 一、背景知识 Opencv轮廓检测 ROS相关知识 二、环境依赖 三、具体实现 Step1&#xff1a;初始化ROS&#xff0c;订阅话题 Step2&#xff1a;接收话题&#xff0c;进入回调 1. 帧处理 2. 膨胀腐蚀处理 Step3&#xff1a;红绿特征处理 1. 提取绘制轮廓 2…

20230517提升cv1826的打印等级

20230517提升cv1826的打印等级 2023/5/17 17:43 https://www.xitongjiaocheng.com/linux/2017/53494.html Linux内核log等级与printk打印消息控制 时间&#xff1a;2017-03-13 出处&#xff1a;系统之家复制分享人气(206次) 【大中小】 printk打印消息控制 // linux/includ…