你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

使用 stm32f7x单片机对sdram 读写 ?

[复制链接]
hpdell 提问时间:2016-10-23 12:34 /
悬赏4ST金币未解决
大虾们好,最近在使用 stm32f7x单片机对sdram 读写 ?? 出现如下情况:

图片1,读写正常,单个字节读写,见图片描述

1.png

一写一读正常,这说明硬件木有什么问题吧 ??

下面的连续写或者连续读都不行,图片如下:
大神们看看是哪里不对,SDRAM 我是使用两片 16位组合成32位的
a、 不行-1.png

b、 不行-2.png

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 芯片截图
2.png

详细的 MT48LC32M16资料如下: MT48LC32M16 datasheet.pdf (1.78 MB, 下载次数: 5)

收藏 1 评论20 发布时间:2016-10-23 12:34

举报

20个回答
hpdell 最优答案 回答时间:2016-10-29 22:21:50
已经搞定了,吧两个芯片更换为一模一样的就可以了

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

anywill 回答时间:2016-10-26 07:20:13
sdram 太高深,暂时还没接触,支持一下
无薪税绵 回答时间:2016-10-26 08:19:15
这个真的不会,只能帮楼主加人气了。
zhoupxa 回答时间:2016-10-26 08:50:22
遇到这种问题,建议用如此测试:

1.原厂例程+评估板
2.原厂例程+自制板
3.自写程序+评估板
4.自写程序+自制板

并对照原厂和自己的软件、硬件设计,以找出问题所在
当然不必全部测试
z258121131 回答时间:2016-10-26 09:16:14
顶楼主,学习啦。
haifeng-388081 回答时间:2016-10-26 09:49:28

顶楼主,学习啦。
wofei1314 回答时间:2016-10-26 11:06:42
2片SDRAM么?
五哥1 回答时间:2016-10-26 12:34:57
帮楼主顶一下
wudianjun2001 回答时间:2016-10-26 15:25:22
不会,帮顶
STM32LEARN 回答时间:2016-10-26 15:57:01
帮顶   
hpdell 回答时间:2016-10-26 16:39:27

是的

两片 MT48LC32M16(两片16bit)组合成 MT48LC32M32(32bit)
zbber 回答时间:2016-10-26 17:07:53
顶楼主,学习啦
高二毛 回答时间:2016-10-26 17:32:20
学习了。。。。
高二毛 回答时间:2016-10-26 17:34:14
刚看了看代码,你吧printf放到你连续的外面试试?printf毕竟速度最慢,操作内存是很快的。
wofei1314 回答时间:2016-10-26 19:42:24
hpdell 发表于 2016-10-26 16:39
是的

两片 MT48LC32M16(两片16bit)组合成 MT48LC32M32(32bit)

这个确实比较麻烦,我还没试过
12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版