如题,STM32F429-DISCOVERY开发板原来自带SDRAM的。我直接移植了原来的SDRAM程序到自己的板子上驱动镁光的SDRAM( MT48LC16M16A2)。在对照数据手册修改之后,发现SDRAM执行HAL_SDRAM_Write_16b()时写入数据不对。
下面是MT48LC16M16A2的初始化程序:
[mw_shl_code=c,true]void sdram_init(void)
{
hsdram.Instance = FMC_SDRAM_DEVICE;
// flag_sdram_LED4=1;
// flag_sdram_LED3=1;
/* Timing configuration for 90 MHz of SD clock frequency (180MHz/2) */
/*11.1ns=(1/90)----这个是开发板的IS4*/
/*11.9ns=(1/84)----MT48*/
/*1/28=35.7 tclk>15ns*/
/* TMRD: 2 Clock cycles */
SDRAM_Timing.LoadToActiveDelay = 2;
/* TXSR: min=75ns (7x11.90ns) */
SDRAM_Timing.ExitSelfRefreshDelay = 8;//7;
/* TRAS: min=44ns (4x11.90ns) max=120k (ns) */
SDRAM_Timing.SelfRefreshTime = 6;//4;
/* TRC: min=66 (6x11.90ns) */
SDRAM_Timing.RowCycleDelay = 8;//7;
/* TWR: 2 Clock cycles */
SDRAM_Timing.WriteRecoveryTime = 1;
/* TRP: 20ns => 2x11.90ns */
SDRAM_Timing.RPDelay = 3;
/* TRCD: 20ns => 2x11.90ns */
SDRAM_Timing.RCDDelay = 6;//4;
//BANK2是因为FMC的BANK5_6有两篇BANK
hsdram.Init.SDBank = FMC_SDRAM_BANK2;
//以下的行列要修改为9 13
hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
//width 和 banks_num 都不用改
hsdram.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;
hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram.Init.SDClockPeriod = SDCLOCK_PERIOD;
hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
hsdram.Init.ReadPipeDelay =FMC_SDRAM_RPIPE_DELAY_1;
/* Initialize the SDRAM controller */
if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK)
{
// flag_sdram_LED4=1;
flag_sdram_LED3=1;
}
}[/mw_shl_code]
/////////////////////////////////
[mw_shl_code=c,true]void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd =0;
/* Step 3: Configure a clock configuration enable command */
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget =FMC_SDRAM_CMD_TARGET_BANK2;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x0100);
/* Step 4: Insert 100 ms delay */
HAL_Delay(100);//这个延时也是100,两个数据手册16,17页对比。
/* Step 5: Configure a PALL (precharge all) command */
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x0100);
/* Step 6 : Configure a Auto-Refresh command */
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command->AutoRefreshNumber = 8;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x0100);
/* Step 7: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_3 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x0100);
/* Step 8: Set the refresh rate counter */
HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);
//flag_sdram_LED4=1;
}
[/mw_shl_code]
初始化之后 pSrcBuffer经过
Fill_Buffer(sdram_aTxBuffer, sdram_BUFFER_SIZE, 9)函数赋值是9到18的值。
之后调用下面函数给SDRAM写入数据。
[mw_shl_code=c,true]HAL_StatusTypeDef HAL_SDRAM_Write_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize)
{
__IO uint16_t *pSdramAddress = (uint16_t *)pAddress;
uint32_t tmp = 0;
/* Process Locked */
__HAL_LOCK(hsdram);
/* Check the SDRAM controller state */
tmp = hsdram->State;
if(tmp == HAL_SDRAM_STATE_BUSY)
{
return HAL_BUSY;
}
else if((tmp == HAL_SDRAM_STATE_PRECHARGED) || (tmp == HAL_SDRAM_STATE_WRITE_PROTECTED))
{
return HAL_ERROR;
}
/* Write data to memory */
for(; BufferSize != 0; BufferSize--)
{
*(__IO uint16_t *)pSdramAddress = *pSrcBuffer;
pSrcBuffer++;
pSdramAddress++;
}
/* Process Unlocked */
__HAL_UNLOCK(hsdram);
return HAL_OK;
}[/mw_shl_code]
下图是在线调试时执行HAL_SDRAM_Write_16b()的for循环这个写入过程时得出的结果。
pSdramAddress应该是和pSrcBuffer数值一样啊。
现在不知是硬件还是程序有问题???调过SDRAM的小伙伴帮忙看一下。
一周热门 更多>