SDRAM | GPIO | 解释 |
---|---|---|
FMC A0:5 | PF0:5 | 地址线 |
FMC A6:9 | PF12:15 | 地址线 |
FMC A10:12 | PG0:2 | 地址线 |
FMC D0:1 | PD14:15 | 数据线 |
FMC D2:3 | PD0:1 | 数据线 |
FMC D4:12 | PE7:15 | 数据线 |
FMC D13:15 | PD8:10 | 数据线 |
FMC BA0 | PG4 | Bank地址输入 |
FMC BA1 | PG5 | Bank地址输入 |
FMC NBL0 | PE0 | 数据掩码 |
FMC NBL1 | PE1 | 数据掩码 |
FMC SDNE | PC2 | 片选 |
FMC SDCKE | PC3 | 时钟使能信号,选择哪个Bank主要就是看这个引脚 |
FMC SDNCAS | PG15 | 列地址选通(低电平有效) |
FMC SDNRAS | PF11 | 行地址选通(低电平有效) |
FMC SDNWE | PH5 | 写入使能(低电平有效) |
FMC SDCLK | PG8 | 同步时钟 |
Bank0开始地址为0xC000 0000(本文使用)
Bank1开始地址为0xD000 0000
使用 SDRAM Bank1所以选择 SDRAM1
使能片选和时钟
每个WB芯片内部
有4个bank
地址13位,数据16位
使用地址掩码功能所以启用Byte Enable
GPIO速度注意使用Very High
参考华邦数据手册,翻译大概如下:
1. 在上电过程中,当输入信号保持在“NOP”状态时,所有VDD和VDDQ引脚必须同时爬升到指定电压(所有引脚电平拉高)。任何输入引脚或VDD电源的上电电压不得超过VDD + 0.3V
2. 通电后,需要先暂停200uS,然后使用precharge命令对所有Banks进行预充电。
3. 为了防止上电过程中DQ总线上的数据争用,需要在初始暂停期间将DQM和CKE引脚保持在高位。
4. 所有Bank预充电完成后,必须发出模式寄存器设置命令来初始化模式寄存器。
5. 在编程模式寄存器之前或之后,还需要额外的8个自动刷新周期(CBR),以确保正确的后续操作。
/* USER CODE BEGIN FMC_Init 2 */
//自己填充的代码,第一步给SDRAM提供时钟FMC_SDRAM_CommandTypeDef Command;Command.CommandMode= FMC_SDRAM_CMD_CLK_ENABLE;Command.CommandTarget=FMC_SDRAM_CMD_TARGET_BANK1;Command.AutoRefreshNumber=1;Command.ModeRegisterDefinition = 0;HAL_SDRAM_SendCommand(&hsdram1,&Command,0xFFFF);
//第二步HAL_Delay(1);//至少延时200us//第三步 对所有bank预充电 Command.CommandMode= FMC_SDRAM_CMD_PALL;Command.CommandTarget=FMC_SDRAM_CMD_TARGET_BANK1;Command.AutoRefreshNumber=1;Command.ModeRegisterDefinition = 0;HAL_SDRAM_SendCommand(&hsdram1,&Command,0xFFFF);
//第四步 插入8个自动刷新周期Command.CommandMode= FMC_SDRAM_CMD_AUTOREFRESH_MODE;Command.CommandTarget=FMC_SDRAM_CMD_TARGET_BANK1;Command.AutoRefreshNumber=8;Command.ModeRegisterDefinition = 0;HAL_SDRAM_SendCommand(&hsdram1,&Command,0xFFFF);//第五步 编程SDRAM加载模式寄存器Command.CommandMode= FMC_SDRAM_CMD_LOAD_MODE;Command.CommandTarget=FMC_SDRAM_CMD_TARGET_BANK1;Command.AutoRefreshNumber=1;Command.ModeRegisterDefinition = 0x230;HAL_SDRAM_SendCommand(&hsdram1,&Command,0xFFFF);//第六步,配置自动刷新周期HAL_SDRAM_ProgramRefreshRate(&hsdram1,1022);/* USER CODE END FMC_Init 2 */
uint32_t pbuff[32*1024*1024/4] __attribute__((at(0xC0000000)));//bank1 放置到另一个拓展内存里for(int count=0;count<0x20000000/4;count++){pbuff[count]=count/3;}for(int count=0;count<0x20000000/4;count++){if(pbuff[count]!=count/3){goto checkFailed;}}
checkFailed:while(1);/* USER CODE END 3 */
gitee