硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4034|回复: 4
收起左侧

SDRAM 存储数据发生异常

[复制链接]

2

主题

9

回帖

15

积分

新手上路

积分
15
发表于 2021-1-16 21:00:47 | 显示全部楼层 |阅读模式
自己做了块板子,MCU主控使用的是STM32F429IIT6,用到一个128MB的SDRAM—IS42S32400。现在在读取数据时候遇到了一个问题:SDRAM所有地址的32位数据中的第29位(从0开始)会随着读的过程而变化,从0跳变成1,造成读取错误。分别进行了32位与8位写入测试。
  • 32位数据长度的写入测试中,往0xD000_0000~0xD100_0000依次写入地址的递增值(例如,往0xD0FF_FF00中写入0x00FF_FF00)。写入之后马上依次读出,与写入值进行比较。当二者不相等时输出此刻地址,做了几次实验,误码大致都发生在地址0xD029_0000~0XD040_0000之间,且一但发生了误码,则所有存储空间中的第29位全部变成1。
  • 8位数据长度的读写测试中,往0xD000_0000~0xD100_00FF中分别写入0x00~0xFF,每写4个byte数据都会发生一次SDRAM所有存储空间中的第29位变成0,而后再变成1的过程。

个人怀疑是软件什么地方配置不对,可能跟SDRAM的刷新过程有关,附上SDRAM初始化代码:
  1. void MX_FMC_Init(void)
  2. {
  3.   /* USER CODE BEGIN FMC_Init 0 */
  4.   FMC_SDRAM_CommandTypeDef Command;        // 控制指令
  5.   __IO uint32_t tmpmrd=0;
  6.   /* USER CODE END FMC_Init 0 */

  7.   FMC_SDRAM_TimingTypeDef SdramTiming = {0};

  8.   /* USER CODE BEGIN FMC_Init 1 */

  9.   /* USER CODE END FMC_Init 1 */

  10.   /** Perform the SDRAM1 memory initialization sequence
  11.   */
  12.   hsdram1.Instance = FMC_SDRAM_DEVICE;
  13.   /* hsdram1.Init */
  14.   hsdram1.Init.SDBank = FMC_SDRAM_BANK2;
  15.   hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
  16.   hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
  17.   hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
  18.   hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  19.   hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
  20.   hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  21.   hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  22.   hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  23.   hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
  24.   /* SdramTiming */
  25.   SdramTiming.LoadToActiveDelay = 2;
  26.   SdramTiming.ExitSelfRefreshDelay = 7;
  27.   SdramTiming.SelfRefreshTime = 4;
  28.   SdramTiming.RowCycleDelay = 7;
  29.   SdramTiming.WriteRecoveryTime = 3;
  30.   SdramTiming.RPDelay = 2;
  31.   SdramTiming.RCDDelay = 2;

  32.   if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
  33.   {
  34.     Error_Handler( );
  35.   }

  36.   /* USER CODE BEGIN FMC_Init 2 */
  37.    
  38.   /* Configure a clock configuration enable command */
  39.   Command.CommandMode                                         = FMC_SDRAM_CMD_CLK_ENABLE;        // 开启SDRAM时钟
  40.   Command.CommandTarget                                 = FMC_COMMAND_TARGET_BANK;         // 选择要控制的区域
  41.   Command.AutoRefreshNumber                         = 1;
  42.   Command.ModeRegisterDefinition         = 0;
  43.   
  44.   HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);        // 发送控制指令
  45.   SDRAM_delay(1);                // 延时等待
  46.   
  47.   /* Configure a PALL (precharge all) command */
  48.   Command.CommandMode                                         = FMC_SDRAM_CMD_PALL;                // 预充电命令
  49.   Command.CommandTarget                                 = FMC_COMMAND_TARGET_BANK;        // 选择要控制的区域
  50.   Command.AutoRefreshNumber                         = 1;
  51.   Command.ModeRegisterDefinition         = 0;
  52.   
  53.   HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);  // 发送控制指令
  54.   
  55.   /* Configure a Auto-Refresh command */
  56.   Command.CommandMode                                         = FMC_SDRAM_CMD_AUTOREFRESH_MODE;        // 使用自动刷新
  57.   Command.CommandTarget                                 = FMC_COMMAND_TARGET_BANK;          // 选择要控制的区域
  58.   Command.AutoRefreshNumber                        = 8;                                // 自动刷新次数
  59.   Command.ModeRegisterDefinition         = 0;
  60.   
  61.   HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);        // 发送控制指令
  62.   
  63.   /* Program the external memory mode register */
  64.   tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2          |
  65.                      SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
  66.                      SDRAM_MODEREG_CAS_LATENCY_3           |
  67.                      SDRAM_MODEREG_OPERATING_MODE_STANDARD |
  68.                      SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
  69.   
  70.   Command.CommandMode                                        = FMC_SDRAM_CMD_LOAD_MODE;        // 加载模式寄存器命令
  71.   Command.CommandTarget                                 = FMC_COMMAND_TARGET_BANK;        // 选择要控制的区域
  72.   Command.AutoRefreshNumber                         = 1;
  73.   Command.ModeRegisterDefinition         = tmpmrd;
  74.   
  75.   HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);        // 发送控制指令
  76.   
  77.   hsdram1.Instance->SDRTR |= ((uint32_t)((1386)<< 1));        // 设置刷新计数器

  78.   /* USER CODE END FMC_Init 2 */
  79. }
复制代码

ST-LINK调试的视频如下:


32位写入.mp4

881.65 KB, 下载次数: 9

8位写入.mp4

1.78 MB, 下载次数: 2

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2021-1-17 08:02:11 | 显示全部楼层
第1感觉,你的焊接是不是有点问题,先重新焊接下。

另外你的SDRAM应该是128Mbit,即16MB
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2021-1-17 09:33:03 | 显示全部楼层
eric2013 发表于 2021-1-17 08:02
第1感觉,你的焊接是不是有点问题,先重新焊接下。

另外你的SDRAM应该是128Mbit,即16MB

有可能是焊接问题,因为这个是我手焊的。我过几天再重新焊一块板子试试。
但我还有一个疑问,如果是焊接问题,为什么一写完马上读就不会有问题,而是在之后某个瞬间全部的第29位都变成1?(即32位中最高的字节由0000_0000变为0010_0000)
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2021-1-19 07:39:52 | 显示全部楼层
nosi12 发表于 2021-1-17 09:33
有可能是焊接问题,因为这个是我手焊的。我过几天再重新焊一块板子试试。
但我还有一个疑问,如果是 ...

虚焊?
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2021-1-20 09:51:59 | 显示全部楼层
结贴了,我重新上了一遍锡就好了
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 21:11 , Processed in 0.054769 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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