引言
之前说好要做一个LTDC的显示作品,所以在使用LTDC的时候必然需要链接外置SDRAM作为缓冲区(显存)。我所使用的开发板野火h743的核心板自带了两个SDRAM。我们使用FMC来连接他们
基础代码生成
这部分还是用大家都喜欢的CubeMX来完成,很多基础的设置我这里就不讲了,因为没必要,都学到SDRAM了就没必要再看基础设置了,这一篇文章建议和之前写的LTDC显示部分连起来看
先随随便便设个时钟,记住FMC我们挂载在PLL2R上
然后我们前往FMC界面(connectivity->FMC)进行进一步设置
- 我们先看到这个界面
我们选择SDRAM1,当然你选2也不是不行,结果是一样的
2.
这一步的设置是按照每个人的设备来看的,就以我的为例子。我的储存芯片是W9825G6KH,这是一个十六位的芯片。但是我的开发板将他们两连起来了,做成了一个32位的芯片,但是共享地址线。
- 第一个选项是芯片时钟和芯片片选线,这个部分是根据你自己的接线来选择的,一共有两个可选,这样不同的选择会导致你的SDRAM挂载到不同的地址上。
- 接下来的东西需要查阅芯片数据手册,这个东西的意思是你的芯片里面有几个BANK,意思就是分了几个区,我这里是四个。
- 这个地址线个数,自查手册
- 数据位数,我这个连接成三十二位了
- 这个开
- 第一个不用看,自动生成的
- 第二个第三个看数据手册
- 剩下的涉及到复杂的计算,简单提一下。
- 举个例子,这个所谓的common clock的意思是分频,你可以理解为这玩意是把FMC的频率分几份给芯片。我这里选的2就是分给芯片一半,就是120mhz
- 突发模式一般开了
- 写保护肯定关了
- 下面的东西先要查数据手册上的时间,然后按照分配的频率来计算延时周期,挺麻烦,计算过程就不细说了。
代码部分
cubemx能帮我们生成所需要的代码,但是还有一部分要我们自己实现,这部分就是芯片的初始化,因为芯片内部操作还有一部分是自动进行的。比如自刷新,这是动态存储器必须的一个操作,假如没有,芯片上的数据就会自己慢慢消失。
hal库其实给了我们芯片初始化的时候需要的函数
这里给出芯片初始化要用的函数,只要针对自己的芯片更改就行了
void SDRAM_InitSequence(void)
{
uint32_t tmpr = 0;
/* Step 1 ----------------------------------------------------------------*/
Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command.CommandTarget = FMC_COMMAND_TARGET_BANK;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 2: ÑÓʱ100us */
SDRAM_delay(1);
/* Step 3 ----------------------------------------------------------------*/
Command.CommandMode = FMC_SDRAM_CMD_PALL;
Command.CommandTarget = FMC_COMMAND_TARGET_BANK;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 4 ----------------------------------------------------------------*/
Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command.CommandTarget = FMC_COMMAND_TARGET_BANK;
Command.AutoRefreshNumber = 8;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 5 ----------------------------------------------------------------*/
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_2 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command.CommandTarget = FMC_COMMAND_TARGET_BANK;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = tmpr;
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 6 ----------------------------------------------------------------*/
HAL_SDRAM_ProgramRefreshRate(&sdramHandle, 830);
}
这一个函数就可以将需要的设置数据发送到芯片,我们将这个函数放在HAL自带的初始化函数中即可
然后编译下载一气呵成
启动调试模式
外置SDRAM在芯片中会有两个映射的地址
启动我们的仿真器以后使用寄存器窗口查看是否能够读取即可。