834|3

749

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

[STM32F769IDISCO返场]SDRAM扩展系统内存 [复制链接]

### 背景

一张800x480x分辨率的bmp文件足有1.09MB大小,即使是16位的bmp文件也有187KB。再看STM32F769芯片片上SRAM比较大,但也仅有512KB的容量大小。如果在GUI显示应用上面,以太网应用场景里负荷较重下,则相当吃紧。这里需要SDRAM芯片的协助了。

SDRAM

SDRAM(Synchronous Dynamic Random Access Memory)是同步动态随机存取存储器,是一种常用的内存类型。它是在时钟信号的控制下进行数据读取和写入的,具有高速、高效的特点。SDRAM的特点是高速、高效、灵活性强。它可以在一个时钟周期内进行一次数据读写操作,比传统的DRAM操作更快。此外,SDRAM的功耗相对较低,体积较小,质量也轻,适用于各种电子产品中。

配置SDRAM

从原理图上可以看到在STM32F769IDISCO开发板上面,SDRAM与STM32F769的FMC外设相连接。

阅读芯片手册,可以看到通过FMC外设驱动SDRAM内存,其地址空间可以选择2个bank。我选择了bank1,即SDRAM的地址空间起始为0xC000_0000。

在本次实验中,我们仍然通过STM32CubeMX工具软件来生成硬件配置代码。

测试代码

在main.c中,我们再编写简单的测试代码。本次我设计通过读写SDRAM内存中某个地址,把读写结果进行简单的对比,再将读写操作的结果通过串口输出出来。如果写入数据与读取数据相同,则代表SDRAM配置以及读写成功。

  1. main.c
  2. static void sdram_init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
  3. {
  4. uint32_t tmpmrd = 0;
  5. /* Step 3:Configure a clock configuration enable command */
  6. Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
  7. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  8. Command->AutoRefreshNumber = 1;
  9. Command->ModeRegisterDefinition = 0;
  10. /* Send the command */
  11. HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
  12. /* Step 4: Insert 100 us minimum delay */
  13. /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
  14. HAL_Delay(1);
  15. /* Step 5: Configure a PALL (precharge all) command */
  16. Command->CommandMode = FMC_SDRAM_CMD_PALL;
  17. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  18. Command->AutoRefreshNumber = 1;
  19. Command->ModeRegisterDefinition = 0;
  20. /* Send the command */
  21. HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
  22. /* Step 6 : Configure a Auto-Refresh command */
  23. Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  24. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  25. Command->AutoRefreshNumber = 8;
  26. Command->ModeRegisterDefinition = 0;
  27. /* Send the command */
  28. HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
  29. /* Step 7: Program the external memory mode register */
  30. tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
  31. SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
  32. SDRAM_MODEREG_CAS_LATENCY_2 |
  33. SDRAM_MODEREG_OPERATING_MODE_STANDARD |
  34. SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
  35. Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  36. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  37. Command->AutoRefreshNumber = 1;
  38. Command->ModeRegisterDefinition = tmpmrd;
  39. /* Send the command */
  40. HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
  41. /* Step 8: Set the refresh rate counter */
  42. /* (15.62 us x Freq) - 20 */
  43. /* Set the device refresh counter */
  44. hsdram->Instance->SDRTR |= ((uint32_t)((1292) << 1));
  45. }
  46. void sdram_write_reg(uint32_t addr, uint32_t val)
  47. {
  48. volatile uint32_t *ptr = (volatile uint32_t *)addr;
  49. *ptr = val;
  50. }
  51. uint32_t sdram_read_reg(uint32_t addr)
  52. {
  53. volatile uint32_t *ptr = (volatile uint32_t *)addr;
  54. return (*ptr);
  55. }
  56. /* FMC initialization function */
  57. static void MX_FMC_Init(void)
  58. {
  59. /* USER CODE BEGIN FMC_Init 0 */
  60. FMC_SDRAM_CommandTypeDef command;
  61. /* USER CODE END FMC_Init 0 */
  62. FMC_SDRAM_TimingTypeDef SdramTiming = {0};
  63. /* USER CODE BEGIN FMC_Init 1 */
  64. /* USER CODE END FMC_Init 1 */
  65. /** Perform the SDRAM1 memory initialization sequence
  66. */
  67. hsdram1.Instance = FMC_SDRAM_DEVICE;
  68. /* hsdram1.Init */
  69. hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
  70. hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
  71. hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
  72. hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
  73. hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  74. hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
  75. hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  76. hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  77. hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  78. hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
  79. /* SdramTiming */
  80. SdramTiming.LoadToActiveDelay = 2;
  81. SdramTiming.ExitSelfRefreshDelay = 6;
  82. SdramTiming.SelfRefreshTime = 4;
  83. SdramTiming.RowCycleDelay = 6;
  84. SdramTiming.WriteRecoveryTime = 2;
  85. SdramTiming.RPDelay = 2;
  86. SdramTiming.RCDDelay = 2;
  87. if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
  88. {
  89. Error_Handler();
  90. }
  91. /* USER CODE BEGIN FMC_Init 2 */
  92. sdram_init(&hsdram1, &command);
  93. /* USER CODE END FMC_Init 2 */
  94. }
  95. main.c
  96. sdram_write_reg(SDRAM_BANK_ADDR, 0x12345678);
  97. rx_buf[0] = sdram_read_reg(SDRAM_BANK_ADDR);
  98. JDEBUG_PRINTF("rx=%08X\r\n", rx_buf[0]);

结果展示

串口输出结果显示SDRAM读写操作正确。

查看精华帖全部内容,请登录或者注册
此帖出自stm32/stm8论坛

最新回复

不可多得的好东西,多谢楼主分享,接下来花点时间研究研究   详情 回复 发表于 2023-11-1 14:02
点赞 关注
 

回复
举报

7773

帖子

2

TA的资源

五彩晶圆(高级)

沙发
 

谢谢分享,期待后续深度评测!

此帖出自stm32/stm8论坛
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 

回复

55

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

不可多得的好东西,多谢楼主分享,接下来花点时间研究研究

此帖出自stm32/stm8论坛

点评

这个SDRAM确实要再仔细的多做些实验,尤其是稳定性的。    详情 回复 发表于 2023-11-1 15:45
 
 

回复

749

帖子

0

TA的资源

纯净的硅(高级)

4
 
孤独的单刀 发表于 2023-11-1 14:02 不可多得的好东西,多谢楼主分享,接下来花点时间研究研究

这个SDRAM确实要再仔细的多做些实验,尤其是稳定性的。

 

谢谢 关注

此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
中星联华&ADI明日直播
直播主题:大咖面对面,轻松玩转高速ADC性能测试
直播时间:3月25日(周二)14:00
活动奖励:京东卡、双肩包

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 6

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表