
大虾们好,最近在使用 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资料如下: ![]() |
评分
查看全部评分
1.原厂例程+评估板
2.原厂例程+自制板
3.自写程序+评估板
4.自写程序+自制板
并对照原厂和自己的软件、硬件设计,以找出问题所在
当然不必全部测试
顶楼主,学习啦。
是的
两片 MT48LC32M16(两片16bit)组合成 MT48LC32M32(32bit)
这个确实比较麻烦,我还没试过