大虾们好,最近在使用 STM32f7x单片机对sdram 读写 ?? 出现如下情况:
图片1,读写正常,单个字节读写,见图片描述
一写一读正常,这说明硬件木有什么问题吧 ??
下面的连续写或者连续读都不行,图片如下:
大神们看看是哪里不对,SDRAM 我是使用两片 16位组合成32位的
a、
b、
c、上述a或者b操作后,如果不使用 static void MPU_Config(void) 这个函数,那么再单独进行单个字节的读写也不正常,这又是为何啊 ???
软件设置如下:
/**
* @brief Configure the MPU attributes as Write Back for SDRAM.
* @note The Base Address is 0xC0000000.
* The Region Size is 32MB, it is related to SDRAM memory size.
* @param None
* @retval None
*/
static void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes as WB for SDRAM */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = SDRAM_BASE_ADDR; // 0xC0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
// 执行外部存储器SDRAM的初始化序列
/**
* @brief Perform the SDRAM external memory initialization sequence
* @param hsdram: SDRAM handle
* @param Command: Pointer to SDRAM command structure
* @retval None
*/
void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd =0;
/* Step 1: Configure a clock configuration enable command */
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Step 2: Insert 100 us minimum delay */
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
HAL_Delay(1);
/* Step 3: Configure a PALL (precharge all) command */
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Step 4 : Configure a Auto-Refresh command */
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 8;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Step 5: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_2 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Step 6: Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
hsdram->Instance->SDRTR |= ((uint32_t)((1292)<< 1)); // 1292
}
/* FMC initialization function */
void MX_FMC_Init(void)
/** Perform the SDRAM1 memory initialization sequence
*/
hsdram1.Instance = FMC_SDRAM_DEVICE; //SDRAM在BANK5,6
/* hsdram1.Init */
/* 两片 MT48LC32M16(数据宽度16位) 组合成为 一片 MT48LC32M32(即把两片16位的组合成32位宽的)*/
hsdram1.Init.SDBank = FMC_SDRAM_BANK1; //SDRAM接在BANK5上
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_10; // 列地址线数目
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13; // 行地址线数目
hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; //一共4个BANK
hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2; //CAS为3
hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; // 使能突发读
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; // 定义在CAS个延时后在等待多少个HCLK时钟才读取数据
/* SdramTiming */
#if 1
SdramTiming.LoadToActiveDelay = 2; // TMDR 加载模式寄存器到激活时间的延迟为2个时钟周期
SdramTiming.ExitSelfRefreshDelay = 6; // TXSR 退出自刷新延迟为x个时钟周期
SdramTiming.SelfRefreshTime = 4; // TRAS 自刷新时间为x个时钟周期
SdramTiming.RowCycleDelay = 6; // TRC 行循环延迟为x个时钟周期
SdramTiming.WriteRecoveryTime = 2; // TWR 恢复延迟为x个时钟周期
SdramTiming.RPDelay = 2; // TRP 行预充电延迟为x个时钟周期
SdramTiming.RCDDelay = 2; // TRCD 行到列延迟为x个时钟周期
#else
SdramTiming.LoadToActiveDelay = 3; // TMDR 加载模式寄存器到激活时间的延迟为2个时钟周期
SdramTiming.ExitSelfRefreshDelay = 7; // TXSR 退出自刷新延迟为x个时钟周期
SdramTiming.SelfRefreshTime = 5; // TRAS 自刷新时间为x个时钟周期
SdramTiming.RowCycleDelay = 7; // TRC 行循环延迟为x个时钟周期
SdramTiming.WriteRecoveryTime = 3; // TWR 恢复延迟为x个时钟周期
SdramTiming.RPDelay = 3; // TRP 行预充电延迟为x个时钟周期
SdramTiming.RCDDelay = 3; // TRCD 行到列延迟为x个时钟周期
#endif
if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
{
Error_Handler();
}
/* Program the SDRAM external device */
BSP_SDRAM_Initialization_Sequence(&hsdram1, &SDRAMcommand); // 执行外部存储器SDRAM的初始化序列
}
MT48LC32M16 芯片截图
详细的 MT48LC32M16资料如下:
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
这个确实比较麻烦,我还没试过
一周热门 更多>