硬汉嵌入式论坛

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

[求助]SDRAM讀寫時間是否能夠更快速?

[复制链接]

3

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2015-10-28 08:39:49 | 显示全部楼层 |阅读模式
您好~
我想請教有關STM32F426I-DISCO 開發版上所使用的SDRAM資料存取時間是否能夠更快速?
以下是我量測存取時間驗證方式:


使用GPIOG Pin13 驗證寫入時間,將得到的時間除與BUFF_SIZE,驗證每筆資料儲存時間,其中BUFF_SIZE為2048。得到每筆資料寫入時間為1.02s/2048=498.0468us。
GPIOG->ODR = GPIO_Pin_13;
for(adr=0;adr<BUFF_SIZE;adr++){
    *(unsigned int*) (SDRAM_START_ADR + (adr << 2)) = write[adr];
}
GPIOG->ODR = ~GPIO_Pin_13;

使用GPIOG Pin14 驗證讀取時間,將得到的時間除與BUFF_SIZE,驗證每筆資料儲存時間,其中BUFF_SIZE為2048。得到每筆資料寫入時間為2.5s/2048=1220.7031us。
GPIOG->ODR = GPIO_Pin_14;
for(adr=0;adr<BUFF_SIZE;adr++){
    read[adr] = *(unsigned int*)(SDRAM_START_ADR +(adr << 2));
}
GPIOG->ODR = ~GPIO_Pin_14;

SDRAM FMC設定如下:
void P_SDRAM_InitFMC(void)
{
  FMC_SDRAMInitTypeDef  FMC_SDRAMInitStructure;
  FMC_SDRAMTimingInitTypeDef  FMC_SDRAMTimingInitStructure;

  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);

  //---------------------------------------------------------
  // FMC auf 180MHz/2 = 90MHz einstellen
  // 90MHz = 11,11 ns
  // Alle Timings laut Datasheet und Speedgrade -7 (=7ns)
  //---------------------------------------------------------
  FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2;    // tMRD=2CLK
  FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 7; // tXSR min=70ns
  FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4;      // tRAS min=42ns
  FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 7;        // tRC  min=63ns
  FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2;    // tWR =2CLK
  FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2;              // tRP  min=15ns
  FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2;             // tRCD min=15ns

  FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank2_SDRAM;
  FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b;
  FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_12b;
  FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = SDRAM_MEMORY_WIDTH;
  FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4;
  FMC_SDRAMInitStructure.FMC_CASLatency = SDRAM_CAS_LATENCY;
  FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable;
  FMC_SDRAMInitStructure.FMC_SDClockPeriod = SDRAM_CLOCK_PERIOD;
  FMC_SDRAMInitStructure.FMC_ReadBurst = SDRAM_READBURST;
  FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1;
  FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure;

  FMC_SDRAMInit(&FMC_SDRAMInitStructure);

  P_SDRAM_InitSequence();
}

void P_SDRAM_InitSequence(void)
{
  FMC_SDRAMCommandTypeDef FMC_SDRAMCommandStructure;
  uint32_t tmpr = 0;

  FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled;
  FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;
  FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
  FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
  
  while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET);

  FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);

  P_SDRAM_delay(10);


  FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_PALL;
  FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;
  FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
  FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
  
  while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET);

  FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);

  FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_AutoRefresh;
  FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;
  FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 4;
  FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;

  while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET);

  FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);

  while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET);

  FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);


  tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2          |
                   SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
                   SDRAM_MODEREG_CAS_LATENCY_3           |
                   SDRAM_MODEREG_OPERATING_MODE_STANDARD |
                   SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;

  FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_LoadMode;
  FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;
  FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
  FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = tmpr;
  
  while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET);

  FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);

  //-----------------------------------------------
  // FMC_CLK = 90MHz
  // Refresh_Rate = 7.81us
  // Counter = (FMC_CLK * Refresh_Rate) - 20
  //-----------------------------------------------
  FMC_SetRefreshCount(683);

  while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET);
}

系統相關時脈設定,如下:
/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M      8
/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
#define PLL_Q      8

#if defined (STM32F40_41xxx)
#define PLL_N      336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2
#endif /* STM32F40_41xxx */

#if defined (STM32F427_437xx) || defined (STM32F429_439xx)
#define PLL_N      360 //336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2
#endif /* STM32F427_437x || STM32F429_439xx */

#if defined (STM32F401xx)
#define PLL_N      336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      4
#endif /* STM32F401xx */

/******************************************************************************/

SDRAM Datasheet 如下網址:
http://www.issi.com/WW/pdf/42-45S16400J.pdf
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107396
QQ
发表于 2015-10-28 09:13:25 | 显示全部楼层
楼主测试的写入速度是40MB/S吗,写入速度还行。
================================================
楼主的测试方法可以优化下,改成下面这样看看速度如何:
uint16_t *pBuf;
uint32_t i, n;

GPIOG->ODR = GPIO_Pin_13;
for (n = 0; n < 80; n++)
{
     pBuf = (uint16_t *)SDRAM_BANK_ADDR;
     for (i = 0; i < 1024*1024; i++)
     {
          *pBuf++ = 0x55AA;
     }
}
GPIOG->ODR = ~GPIO_Pin_13;


看看这种测试的话,速度是不是可以提高。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107396
QQ
发表于 2015-10-28 14:35:02 | 显示全部楼层
我中午按照这种方式测试下,用的也是探索板子:
每次写入32位数据
测试速度是:320MB/4.401s = 72.7MB/S
    uint32_t i, n;
    uint32_t *pBuf;

    iTime1 = bsp_GetRunTime();    /* 记下开始时间 */
    for (n = 0; n < 80; n++)
    {
        pBuf = (uint32_t *)SDRAM_BANK_ADDR;
        for (i = 0; i < 1024*1024; i++)
        {
            *pBuf++ = 0x55AA55AA;
        }
    }
    iTime2 = bsp_GetRunTime();    /* 记下结束时间 */
==================================================
每次写入16位数据
测试速度是:160MB/3.820s = 41.88MB/S

    uint32_t i, n;
    uint16_t *pBuf;

    iTime1 = bsp_GetRunTime();    /* 记下开始时间 */
    for (n = 0; n < 80; n++)
    {
        pBuf = (uint16_t *)SDRAM_BANK_ADDR;
        for (i = 0; i < 1024*1024; i++)
        {
            *pBuf++ = 0x55AA;
        }
    }
    iTime2 = bsp_GetRunTime();    /* 记下结束时间 */
==================================================
每次写入8位数据
测试速度是:80MB/3.298s = 24.32MB/S

    uint32_t i, n;
    uint16_t *pBuf;

    iTime1 = bsp_GetRunTime();    /* 记下开始时间 */
    for (n = 0; n < 80; n++)
    {
        pBuf = (uint16_t *)SDRAM_BANK_ADDR;
        for (i = 0; i < 1024*1024; i++)
        {
            *pBuf++ = 0x55AA;
        }
    }
    iTime2 = bsp_GetRunTime();    /* 记下结束时间 */
回复

使用道具 举报

3

主题

3

回帖

3

积分

新手上路

积分
3
 楼主| 发表于 2015-10-28 14:47:29 | 显示全部楼层
eric2013 您好 感謝您提供的方法,存取速度有明顯變快許多,目前我測得的情況如下:
SDRAM寫入2048筆unsigned short的資料需花費70us,因此一筆資料為70us/2048=0.03417us,導數為1/(0.03417us)=29.26M。
SDRAM讀取2048筆unsigned short的資料需花費208us,因此一筆資料為208us/2048=0.10156us,導數為1/(0.10156us)=9.84M。
請問以上寫入與讀取速度正常嗎?是否有需要再進行設定的地方?
請問一下,以下設定需使用DISABLE還是ENABLE?
FMC_SDRAMWriteProtectionConfig(FMC_Bank2_SDRAM, DISABLE);
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107396
QQ
发表于 2015-10-29 08:50:45 | 显示全部楼层

回 bai790902 的帖子

bai790902:eric2013 您好 感謝您提供的方法,存取速度有明顯變快許多,目前我測得的情況如下:
SDRAM寫入2048筆unsigned short的資料需花費70us,因此一筆資料為70us/2048=0.03417us,導數為1/(0.03417us)=29.26M。
SDRAM讀取2048筆unsigned short的資料需花費208us,因此一筆資料為208us/20 .. (2015-10-28 14:47) 
这个设置为禁止就可以了,FMC_SDRAMWriteProtectionConfig(FMC_Bank2_SDRAM, DISABLE);
如果开启了写保护的话,那么就无法再写入数据了。
回复

使用道具 举报

3

主题

3

回帖

3

积分

新手上路

积分
3
 楼主| 发表于 2015-10-29 16:26:56 | 显示全部楼层

回 eric2013 的帖子

eric2013:我中午按照这种方式测试下,用的也是探索板子:
每次写入32位数据
测试速度是:320MB/4.401s = 72.7MB/S
    uint32_t i, n;
    uint32_t *pBuf;
....... (2015-10-28 14:35)
eric2013 您好 感謝您用心地回答,那個我想再請教一下,您的Code有使用到以下函式:
bsp_GetRunTime();
想請教您該函式是要如何使用?
您輸出的值是利用UART傳輸到電腦後去觀看嗎?
若是我想請問一下UART傳輸會拖慢SDRAM寫入時間嗎?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107396
QQ
发表于 2015-10-30 19:00:17 | 显示全部楼层

回 bai790902 的帖子

bai790902:eric2013 您好 感謝您用心地回答,那個我想再請教一下,您的Code有使用到以下函式:
bsp_GetRunTime();
想請教您該函式是要如何使用?
您輸出的值是利用UART傳輸到電腦後去觀看嗎?
....... (2015-10-29 16:26) 
这个函数是用滴答定时器中断里面加个计数变量,毫秒计数,而函数
bsp_GetRunTime()就是获取下这个变量的值。前后相减就得到了执行时间。

我是把差值显示在了LCD上面,当然用UART也是可以的,UART不会拖慢SDRAM的。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-29 16:46 , Processed in 0.172139 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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