OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4063|回复: 2

使用stm32fxx单片机对sdram 读写 ?

[复制链接]

259

主题

806

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1887
金钱
1887
注册时间
2012-10-28
在线时间
353 小时
发表于 2016-10-23 12:08:04 | 显示全部楼层 |阅读模式
3金钱
本帖最后由 hpdell 于 2016-10-23 12:41 编辑


大虾们好,最近在使用 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, 下载次数: 59)

最佳答案

查看完整内容[请看2#楼]

终于搞定了啊,不容易啊
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

259

主题

806

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1887
金钱
1887
注册时间
2012-10-28
在线时间
353 小时
 楼主| 发表于 2016-10-23 12:08:05 | 显示全部楼层
终于搞定了啊,不容易啊
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2016-10-24 22:43:28 | 显示全部楼层
参考下我们开发板例程试试吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-3-1 05:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表