我制作了一块定制板,其特点是STM32F469NI MCU与AS4C4M32S SDRAM耦合。
以下是SDRAM定时和寄存器设置信息:
hsdram1.Instance = FMC_SDRAM_DEVICE;
/* hsdram1.Init */
hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
/* SdramTiming */
SdramTiming.LoadToActiveDelay = 2;
SdramTiming.ExitSelfRefreshDelay = 7;
SdramTiming.SelfRefreshTime = 4;
SdramTiming.RowCycleDelay = 6;
SdramTiming.WriteRecoveryTime = 2;
SdramTiming.RPDelay = 2;
SdramTiming.RCDDelay = 2;
if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
{
Error_Handler( );
}
/* USER CODE BEGIN FMC_Init 2 */
FMC_SDRAM_CommandTypeDef cmd = { 0 };
cmd.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
cmd.AutoRefreshNumber = 1;
cmd.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &cmd, 0xFFFF);
HAL_Delay(100);
cmd.CommandMode = FMC_SDRAM_CMD_PALL;
cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
cmd.AutoRefreshNumber = 1;
cmd.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &cmd, 0xFFFF);
cmd.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
cmd.AutoRefreshNumber = 8;
cmd.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &cmd, 0xFFFF);
cmd.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
cmd.AutoRefreshNumber = 1;
cmd.ModeRegisterDefinition = (uint32_t) 0x230; //also tried 0x231
HAL_SDRAM_SendCommand(&hsdram1, &cmd, 0xFFFF);
//Setup SDRAM Refresh Timer Register with the delay between refresh cycles of the SDRAM, this is SDRAM specific.
HAL_SDRAM_ProgramRefreshRate(&hsdram1, 1404); //Tried 1386
当在STM32F469-I DISCOVERY板上运行时,这个代码也能工作,但当在我的自定义承载板上运行它时,它会失败。
在我的板上,每当我写入任何SDRAM地址时,只有第一个字节被读取/写入,例如,当我将0x00写入地址0xC0000000时,在调试中监控的该地址的数据包含0x48129100,即前3个字节是随机垃圾,只有最后一个字节被正确写入(0x00(,并且假设如果我将0xAA写入同一地址,则在监视时那里的数据包含值0x481291AA。
这适用于我从外部SDRAM读取/写入的每个地址。
只写入/读取最后一个字节。
自定义板原理图和PCB布局与STM32F469-I DISCO板相同。
唯一的区别是RAM芯片,它不是MICRON,而是联盟存储器的AS4C4M32S。
这样的问题会是什么问题?
读取SDRAM总是使用全位宽,但写入需要设置四个信号BL0、BL1、BL2和BL3来说明要写入哪些字节。
听起来目前只有BL0在工作。也许BL1-3没有物理连接(硬件(,或者你只是忘记配置它们(软件(。
(如果这是一个硬件问题,那么有适当权限的人会想把这个问题和答案转移到电子堆栈交换(