发新帖本帖赏金 10.00元(功能说明)我要提问
返回列表
打印
[STM32F4]

【STM32F469I试用】SDRAM使用及测试

[复制链接]
5147|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
netlhx|  楼主 | 2015-12-20 13:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 netlhx 于 2015-12-20 13:23 编辑

感谢21IC举办的这次试用活动,有幸入围,评估板前几天已收到,今天正式开始学习及使用高大上的开发板。

各位热情的网友已陆续有开箱及DEMO测试**,本文就不再重复开箱照片,只上图片一张,以飨各位!



SDRAM概述

为了更好的体验显示效果,板载一块16MB的美光内存,型号为MT48LC4M32B2B5-6A,构成4 Meg x 32 (1 Meg x 32 x 4 banks),12位行地址,8位列地址。主要特性参考数据手册如下:





关于SDRAM的使用,详细情况请参考对应的手册,这里只介绍几个重要的参数,包括TRCD, TRP, CL。


  • RCD 在发送列读写命令时必须要与行有效命令有一个间隔,这个间隔被定义为tRCD,即RAS to CASDelay(RAS至CAS延迟),大家也可以理解为行选通周期,这应该是根据芯片存储阵列电子元件响应时间(从一种状态到另一种状态变化的过程)所制定的延迟。tRCD是SDRAM的一个重要时序参数,可以通过主板BIOS经过北桥芯片进行调整,但不能超过厂商的预定范围。广义的tRCD以时钟周期(tCK,Clock Time)数为单位,比如tRCD=2,就代表延迟周期为两个时钟周期,具体到确切的时间,则要根据时钟频率而定,对于PC100SDRAM,tRCD=2,代表20ns的延迟,对于PC133则为15ns
  • RP 在发出预充电命令之后,要经过一段时间才能允许发送RAS行有效命令打开新的工作行,这个间隔被称为tRP(Precharge command Period,预充电有效周期)。和tRCD、CL一样,tRP的单位也是时钟周期数,具体值视时钟频率而定。
  • CL 在选定列地址后,就已经确定了具体的存储单元,剩下的事情就是数据通过数据I/O通道(DQ)输出到内存总线上了。但是在CAS发出之后,仍要经过一定的时间才能有数据输出,从CAS与读取命令发出到第一笔数据输出的这段时间,被定义为CL(CAS Latency,CAS潜伏期)。由于CL只在读取时出现,所以CL又被称为读取潜伏期(RL,Read Latency)。CL的单位与tRCD一样,为时钟周期数,具体耗时由时钟频率决定。

这些参数都可以参考上面的表1,需要注意的是这个值一般是指时钟周期,具体到不同的SDRAM时钟上的话,需要进行换算。数据手册上给出了具体的时间数,其值对应为18-18-18NS,单位是纳秒。

具体来说,在F469-DISCO开发板上,SDRAM的时钟周期最大可以达到HCLK/2,如果配置HCLK为180MHZ的话,则2分频后,SDRAM的时钟频率为90MHZ,一个周期长度约为11.1纳秒,所以在初始化的时候应该分别指定这些值为2, 2, 2。

GPIO配置

参考官方原理图,GPIO用到的主要包括地址线,这些是复用的,还是数据线,BANK选择等。见下图



只不过这些引脚有些多,可以参考官方例程查看具体用到的引脚。

FMC控制器配置

F469MCU内置FMC控制器,可以访问SRAM, SDRAM, NORFLASH等常见存储器件,这里主要指定一些基本的参数,先看代码,再做一个简单的说明。

  /* SDRAM device configuration */
  hsdram.Instance = FMC_SDRAM_DEVICE;

  SDRAM_Timing.LoadToActiveDelay    = 2;
  SDRAM_Timing.ExitSelfRefreshDelay = 6;
  SDRAM_Timing.SelfRefreshTime      = 4;
  SDRAM_Timing.RowCycleDelay        = 6;
  SDRAM_Timing.WriteRecoveryTime    = 2;
  SDRAM_Timing.RPDelay              = 2;
  SDRAM_Timing.RCDDelay             = 2;

  hsdram.Init.SDBank             = FMC_SDRAM_BANK1;
  hsdram.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8;
  hsdram.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;
  hsdram.Init.MemoryDataWidth    = SDRAM_MEMORY_WIDTH;
  hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  hsdram.Init.CASLatency         = FMC_SDRAM_CAS_LATENCY_3;
  hsdram.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  hsdram.Init.SDClockPeriod      = SDCLOCK_PERIOD;
  hsdram.Init.ReadBurst          = FMC_SDRAM_RBURST_ENABLE;
  hsdram.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_0;

  /* Initialize the SDRAM controller */
  HAL_SDRAM_Init(&hsdram, &SDRAM_Timing);

注意看TRP, TRCD及CL的配置,这里指定的都是2,因为SDRAM工作在90MHZ频率之下,2个时钟周期大约为20NS,刚好满足要求,不能再小了。

后面的一些参数,如行列地址线的数目,BANK的个数,基本都可以从SDRAM的数据手册上获取。

SDRAM的初始化序列

按官方手册上的介绍,在使用SDRAM之前,先要执行一系列的初始化命令,然后才能正常访问SDRAM。基本步骤如下:

  • 同时给VDD及VDDQ上电
  • 提供稳定的时钟信号
  • 在发送命令前至少等待100US,在此期间拉高CKE,直到结束
  • 发送PRECHARGE ALL命令
  • 等待至少TRP指定的时间,直到预充电完成
  • 发磅AUTO REFRESH命令,等待TRFC指定的时间
  • 现在SDRAM可以进入模式选择阶段,这里如果不指定的话,SDRAM会进入默认的工作模式,也许不是用户需要的状态。
  • 等待TMRD指定的时间后,SDRAM就可以正常访问了。

结合下面的代码可以看看

  __IO uint32_t tmpmrd =0;
  /* Step 3:  Configure a clock configuration enable command */
  Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
  Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command->AutoRefreshNumber = 1;
  Command->ModeRegisterDefinition = 0;

  /* Send the command */
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

  /* Step 4: Insert 100 us minimum delay */
  /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
  HAL_Delay(1);

  /* Step 5: Configure a PALL (precharge all) command */
  Command->CommandMode = FMC_SDRAM_CMD_PALL;
  Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command->AutoRefreshNumber = 1;
  Command->ModeRegisterDefinition = 0;

  /* Send the command */
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

  /* Step 6 : Configure a Auto-Refresh command */
  Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command->AutoRefreshNumber = 8;
  Command->ModeRegisterDefinition = 0;

  /* Send the command */
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

  /* Step 7: Program the external memory mode register */
  tmpmrd = (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;

  Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command->AutoRefreshNumber = 1;
  Command->ModeRegisterDefinition = tmpmrd;

  /* Send the command */
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

  /* Step 8: Set the refresh rate counter */
  /* (15.62 us x Freq) - 20 */
  /* Set the device refresh counter */
  hsdram->Instance->SDRTR |= ((uint32_t)((1292)<< 1));

至此,SDRAM的初始化就全部完成了,现在可以正常访问SDRAM了。

SDRAM的映射地址

SDRAM在MCU的地址空间中的映射地址为0xC0000000到0xC0FFFFFF,可随机线性访问。


代码测试

这里设计了一段简单的代码来测试所有的内存是否正常。首先将数据写入到SDRAM中,然后读出来,进行比较后判断是否正常。

SDRAM_Init();

HAL_UART_Transmit(&huart3, (uint8_t *)msg1, strlen(msg1), 100);

for(uwIndex = 0; uwIndex < uwCount; uwIndex += 4)
{
  *(__IO uint32_t*) (SDRAM_BANK_ADDR + 4*uwIndex) = 0x01234567;
  if(*(__IO uint32_t*) (SDRAM_BANK_ADDR + 4*uwIndex) == 0x01234567)
  {
   percent2 = uwIndex * 100 / uwCount;
   
   if(percent1 != percent2)
   {
    sprintf(msg, "PASSED: %3d%%\r\n", percent2);
    HAL_UART_Transmit(&huart3, (uint8_t *)msg, strlen(msg), 100);
   }
   percent1 = percent2;
   
  }
  else
   while(1);
  
}

下面是测试结果





结束!

附件:

SDRAM数据手册: MT48LC4M32B2B5-6A.pdf (3.52 MB)

工程文件: sdram.zip (3.71 MB)



打赏榜单

21ic小管家 打赏了 10.00 元 2016-05-16
理由:【申请有奖】TI USBType-C来袭,测评达人是你吗?活动打赏。

沙发
paderboy| | 2015-12-20 15:43 | 只看该作者
多谢分享。。。学习了。。

使用特权

评论回复
板凳
huaiqiao| | 2015-12-22 22:45 | 只看该作者
谢谢分享了,sdram的测试还没搞过。学习下

使用特权

评论回复
地板
exson_2006| | 2015-12-23 15:14 | 只看该作者
感谢分享

使用特权

评论回复
5
hpdell| | 2016-10-24 12:23 | 只看该作者
你好,请教下,这个 hsdram->Instance->SDRTR |= ((uint32_t)((1292)<< 1));  里面的 1292 是怎么来的啊,

改变此值对sdram 会有什么影响 ???

使用特权

评论回复
6
Larm1| | 2017-2-15 14:15 | 只看该作者
好东西,多谢分享...

使用特权

评论回复
7
向阳123| | 2017-5-13 16:11 | 只看该作者
好东西多谢分享

使用特权

评论回复
发新帖 本帖赏金 10.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

144

帖子

4

粉丝