STM32F429用FMC驱动SDRAM写入数据不对

2019-07-20 19:50发布

如题,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的小伙伴帮忙看一下。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。