就在几天由于受到了一点小刺激,狠下心就把F429DISC的开发板给买了,让后就变成穷13了。
但是既然买了,就得发挥他的作用,刚好STM32F103已经学完了,拿这个新外设练练手~~~~
查阅资料很重要!!!
F429的基本时钟配置和debug配置这里不做介绍
众所周知,SDRAM需要用到STM32的FMC外设
所以我们打开cubeMX的FMC界面
我们看原理图
PB5对应NE1,PB6对应CKE1
查询手册可知,PB5和PB6复用模式由SDNE1和SDCKE1
所以我们配置为:
这些数据我们可以查询IS42S16400J的技术手册
这里有十二位地址线
最后记得设置PG13和PG14的LED,这里不做演示
由图中HAL库红框的部分得知,FMC初始化后SDRAM还需要初始化
篮筐的部分得知,可以用初始化函数HAL_SDRAM_SendCommand()和初始化结构体FMC_SDRAM_CommandTypeDef来初始化
于是我们再查看IS42S16400J的手册
搜索初始化英文Initialization
发现
这里有初始化步骤
翻译一下
//初始化时钟
FMC_SDRAM_CommandTypeDef Command;
Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand( &hsdram1, &Command, 0xffff);
HAL_Delay(1);
//在一个无效命令或空操作后执行执行预充电
Command.CommandMode = FMC_SDRAM_CMD_PALL;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand( &hsdram1, &Command, 0xffff);
HAL_Delay(1);
//执行两个自动刷新周期
Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK12;
Command.AutoRefreshNumber = 2;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand( &hsdram1, &Command, 0xffff);
HAL_Delay(1);
//配置模式寄存器
Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0x230;
HAL_SDRAM_SendCommand( &hsdram1, &Command, 0xffff);
HAL_Delay(1);
这里说一下模式寄存器
A[2-0]:突发模式读取数,F429的SDRAM不支持突发模式,所以一次读一个,设置为000
A3 :1为间隔模式即每次读取4个字节会延迟一会儿,0为连续模式,我们选择连续模式,设置为0
A[6-4]:相当于CAS,我配置的数和cubeMX一样,设置为011
A[8-7]:没用,不管
A9:突发模式写,关了,设置1
配置模式寄存器为0b10 0011 0000 即0x230
通过F4的手册我们可以知道,初始化完成FMC和IS42S16400J之后还得配置IS42S16400J的刷新率
根据提示在手册中找到FMC_SDRTR寄存器
F429频率为180Mhz,经过cubeMX在这里的二分频,得到90Mhz就是SDRAM时钟频率。
IS42S16400J刷新周期和行数可以在IS42S16400J得手册中查找:
4096行,刷新率64ms
所以我们可以得到Refresh Rate为1407
让后
HAL_SDRAM_ProgramRefreshRate(&hsdram1 , 1407);
初始化一个于内存大小相同的数组并将该数组存放位置改变到SDRAM中
uint32_t pbuf[(1024*1024*64)/32] __attribute__((at(0xD0000000)));
/*******************************************
解释
int x __attribute__((at(ADDR)));
可以将x存放在指定的地址ADDR中
********************************************/
给我点赞哼哼啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊