如何设置FMC外围设备与ISSI的SDRAM IS42S16800F-6BLI接口

介绍


HMI of Things应用程序具有在用户和机器之间控制和显示数据的能力是非常常见的。这样的应用需要与诸如SDRAM之类的外部存储器接口的能力,SDRAM用作帧(或视频)缓冲器和图形资产的高速缓存。STM32的集成F可弯曲的M埃默里C控制器(FMC)外围设备使其易于与外部存储器接口。
在本文中,我们将了解如何配置STM32的FMC外围设备,以与ISSI中的SDRAM IS42S16800F-6BLI接口——数据表可通过以下链接获得:
https://www.issi.com/WW/pdf/42-45S81600F-16800F.pdf
SDRAM可从Digi-Key面向大众市场提供:
https://www.digikey.com/en/products/detail/issi-integrated-silicon-solution-inc/IS42S16800F-6BLI/486...
 

先决条件:

  • 微控制器:STM32H7B3LI
  • 软件:TouchGFX Designer、STM32CubeIDE和STM32CubeMx

在本文中,我们将了解如何在STM32H7B3I-DK TouchGFX Board Setup(TBS)中设置FMC外围设备,使其能够在SDRAM IS42S16800F-6BLI中具有帧缓冲区。
 

步骤

 
1.创建TouchGFX应用程序
基于STM32H7B3I-DK板设置创建TouchGFX应用程序。如果您不知道如何执行此步骤,请参阅此链接:https://support.touchgfx.com/4.18/docs/tutorials/tutorial-02.本教程使用STM32F746G-DK,而在本文中,我们将使用STM32H7B3I-DK。

2.打开STM32CubeMx项目
在项目位置下,双击STM32H7B3I-DK.ioc打开STM32CubeMx项目
 
 

­­­
3.设置FMC时钟
当我们查看SDRAM数据表时,我们看到SDRAM的最大时钟取决于列地址选通CAS延迟。对于SDRAM“-6”变体,CAS延迟可以设置为2,最大时钟频率为100MHz,可以设置为3个时钟周期,最大时钟周期为166MHz。
 
 

另一方面,当我们查看STM32H7B3LI数据表时,我们看到VDD=3.3V时的最大FMC时钟为110MHz。
 
 

在本文中,我们将使用100MHz的FMC时钟频率(这是为SDRAM提供数据的时钟)和2的CAS延迟。
第一步是设置FMC外围设备的时钟。在这里,我们将使用PLL2将其设置为200MHz。我们稍后将看到,SDRAM时钟源自此FMC时钟,使用200MHz,您可以获得高达100MHz的SDRAM时钟频率,分频器设置为2。
在STM32CubeMx中,在时钟配置选项卡下,我们可以看到FMC时钟多路复用器。如下所示,FMC时钟是从PLL2中导出的。因此,我们需要在PLL2的输出后立即设置DIVM2和PLL2的“N”乘法器、“R”和除法器,以使FMC达到200MHz。

一种可能的解决方案是使DIVM2=24,N=200,R=1。该解决方案提供了200MHz的FMC时钟。该时钟稍后将在FMC中除以2。参考“SDRAM公共时钟”
 
4.设置SDRAM

SDRAM IS42S16800F-6BLI具有以下主要功能:
  • 4096行乘512列
  • 4个银行
  • 12位地址:A0…A11
  • 16位数据:D0…D15
  • 自刷新时间=64ms

­
FMC最多可支持两个SDRAM组:SDRAM1和SDRAM2,每个256Mbit。SDRAM1被映射在地址0xC000 0000处,而SDRAM2被映射到地址0xD000 0000处。STM32H7B3I-DK发现套件上的SDRAM连接到SDRAM2接口。如下图所示,SDCKE1信号连接到SDRAM时钟输入,SDNE1连接到芯片选择/启用输入。

如上面SDRAM IS42S16800F-6BLI的框图所示,存储器具有4个存储体、12位地址、16位数据和16位字节使能。我们所需要做的就是提供如下所示的SDRAM特性:

下一步是设置以下参数:
  • 列数:我们需要9位来编码512列。在STM32CubeMx中,我们需要将列地址位数设置为9位。
  • 行数:我们需要12位来编码4096行。在STM32CubeMx中,我们需要将行地址位数设置为12位。
  • CAS延迟:100MHz时,CAS延迟为2。在STM32CubeMx中,我们将CAS延迟设置为2。
  • 写保护:我们将禁用写保护。
  • SDRAM时钟:SDRAM最大时钟频率为100MHz,CAS延迟为2。在STM32CubeMx中,我们将除法器设置为2。这得到了一个FMC时钟除以2的SDRAM时钟,即200MHz/2=100MHz。
  • 我们将为单个读取请求启用突发读取,并将管道延迟设置为2个时钟周期。


5.设置SDRAM时序
SDRAM IS42S16800F-6BLI的数据表指定了一组定时值,其中一些定时值需要在STM32CubeMx中提供,例如tRC、tRAS…:
  • 我们将从加载模式寄存器到活动延迟(tMRD)开始,它指示加载模式寄存器命令和行或刷新命令之间的延迟。内存数据表指定了12ns,需要将其转换为多个内存周期。因此,我们将12ns除以SDRAM时钟周期10ns,然后四舍五入到上限值,这是我们在STM32CubeMx中使用的值。
  • 其次,退出自刷新延迟(tXSR)是有效命令之间的退出自刷新延时。内存数据表指定67ns,并转换为7个SDRAM时钟周期,是我们在STM32CubeMx中使用的值。
  • 第三,定义的自刷新时间(tRAS)是线有效和预充电命令之间的延迟。内存数据表指定42ns,并转换为5个SDRAM时钟周期,是我们在STM32CubeMx中使用的值。
  • 之后,公共行周期延迟(tRC)是两个刷新命令或两行有效命令之间的延迟。内存数据表指定60ns,并转换为6个SDRAM时钟周期,是我们在STM32CubeMx中使用的值。
  • 接下来,写入恢复时间(tDPL)是从写入命令到预充电命令之间的延迟。内存数据表指定12ns,当我们将其转换为SDRAM时钟周期时,我们得到2,而STM32的规格要求TWR>=TRAS–TRCD=5-2=3,这是我们在STM32CubeMx中使用的值。
  • 之后,公共行预充电延迟(tRP)是预充电和行有效命令之间的延迟。内存数据表指定18ns,转换后为2个SDRAM时钟周期,这是我们在STM32CubeMx中使用的值。
  • Last参数是行到列延迟(tRCD),表示行有效命令和读/写命令之间的延迟。内存数据表指定18ns,并转换为2个SDRAM时钟周期,这是我们在STM32CubeMx中使用的值。


 
6.设置GPIO
最后,我们选择在GPIO设置选项卡下,我们看到SDRAM的STM32CubeMx默认引脚与STM32H7B3I-DK原理图匹配,但以下引脚除外:FMC_SDCKE1SDCKE1、FMC_SDNNE1和FMC_SDNWE
  • STM32CubeMx默认选择PB5用于SD时钟启用1,而原理图使用PH7
  • STM32CubeMx默认选择PB6启用SD芯片,而原理图使用PH6
  • 当原理图使用PH5时,STM32CubeMx默认选择PC0启用SD写入
因此,我们需要更改FMC_SDCKE1、FMC_SDNE1和FMC_SDNWE的映射,以匹配STM32H7B3I-DK示意图。

在引脚视图选项卡中,在搜索字段中键入引脚的名称,引脚将高亮显示,左键单击引脚并将替代功能更改为SDRAM信号。下面的示例显示了如何将FMC_SDEC1更改为PH7。

 
7.SDRAM初始化顺序
STM32无法在通电后立即开始从SDRAM读取数据和向SDRAM写入数据。SDRAM要求初始化序列是可访问的。参考手册RM0455第23.9.3节SDRAM控制器功能说明中所述的初始化顺序为:
  1. 步骤1和步骤2:设置SDRAM定时,在前面的步骤中使用STM32CubeMx第4节和第5节完成
  2. 步骤3:发出时钟启用命令
  3. 步骤4:等待至少100 us
  4. 步骤5:配置预充电全部命令
  5. 步骤6:发出自动刷新命令
  6. 步骤7:对外部存储器模式进行编程
  7. 步骤8:使用刷新时间除以行数乘以SDRAM时钟的公式设置刷新计数器,然后减去20,这得到1542
初始化序列第3步至第7步不是由STM32CubeMx生成的——由用户手动添加。
下面的代码片段显示了初始化序列的实现:
/*用户代码开始FMC_Init 2*/FMC_SDRAM_CommandTypeDef命令;/*步骤1和步骤2已在HAL_SDRAM_Init()中完成*/*步骤3:配置时钟配置启用命令*/command.CommandMode=FMC_DRAM_CMD_CLK_enable;/*将MODE位设置为“001”*/Command.CommandTarget=FMC_DRAM_CMD_TARGET_BANK2;/*配置目标组位*/Command.AutoRefreshNumber=1;Command.ModeRegisterDefinition=0;HAL_SDRAM_SendCommand(&hsdram2,&Command,0xfff);HAL_延迟(1);/*步骤4:插入100 us最小延迟-最小HAL延迟为1ms*/*步骤5:配置PALL(全部预充电)命令*/command.CommandMode=FMC_DRAM_CMD_PALL;/*将MODE位设置为“010”*/HAL_SDRAM_SendCommand(&hsdram2,&Command,0xfff);/*步骤6:配置自动刷新命令*/command.CommandMode=FMC_DRAM_CMD_AUTORREFRESH_MODE;/*将MODE位设置为“011”*/Command.AutoRefreshNumber=2;HAL_SDRAM_SendCommand(&hsdram2,&Command,0xfff);/*步骤7:对外部存储器模式寄存器*/Command.CommandMode=FMC_DRAM_CMD_LOAD_mode进行编程/*将MODE位设置为“100”*/Command.ModeRegisterDefinition=(uint32_t)0|0<3|2<4|0<7|1<9;HAL_SDRAM_SendCommand(&hsdram2,&Command,0xfff);/*步骤8:设置刷新率计数器-请参阅RM0455中SDRAM刷新定时器寄存器部分*/*设置设备刷新率*COUNT=[(SDRAM自刷新时间/行数)x SDRAM CLK]–20=[(64ms/4096)*100MHz]–20=1562.5-20~1542*/HAL_SDRAM_ProgramRefreshRate(&hsdram21542);/*用户代码结束FMC_Init 2*/
 

链接


STM32H7B3LI–产品介绍
STM32F75xxx和STM32F74xxx高级基于arm的32位MCU-参考手册
STM32CubeMx-STM32Cube初始化代码生成器
STM32H7B3I-DK-带STM32H7M3LI MCU的发现套件
TouchGFX文档