记录超快的SDRAM驱动

STM32H750XBT6通过16bit FMC驱动IS42S16160J-7

在考虑到阻抗和等长的情况下,频率跑到了180M,已经远超单片机和SDRAM手册值,时序也是按照不出错为标准取的极限值。

读写为全片32M,字节,半字,比特连续写入读出

使用32bit的TIM2计时,240M不分频

结果如图

计算出来的带宽

附上测试代码

代码里有个要命的坑,读写涉及到的变量不可以加volatile,否则会导致写入极端慢,务必注意

#define SDRAM_TEST_TIM  TIM2                   // SDRAM testing timer
#define SDRAM_TEST_ADDRESS_START 0xC0000000    // Start address of SDRAM
#define SDRAM_TEST_SIZE 0x1fffffA              // Size of test data
#define TEST_TIM_FRE 240000000                 // Timer 2 frequency
#define SDRAM_PRINT 1                          // SDRAM printing
void sdram_test(void) // SDRAM test function
{
  volatile uint32_t temp = 0;
  unsigned short err = 0;
  #if SDRAM_PRINT
  printf("/*************** WORD TEST ***************/\n\r");  // Word test start
  printf("writing start\n\r");    // Writing start message
  SDRAM_TEST_TIM->CNT=0;         // Resetting the timer counter
  LL_TIM_EnableCounter(SDRAM_TEST_TIM);  // Enable the timer
  #endif
  for(temp=0; temp<SDRAM_TEST_SIZE; temp+=4)
  {
    *(uint32_t *)(SDRAM_TEST_ADDRESS_START+temp) = temp;
  }
  #if SDRAM_PRINT
  LL_TIM_DisableCounter(SDRAM_TEST_TIM);  // Disable the timer
  printf("writing end, cost:%1.2fS\n\r", ((float)(SDRAM_TEST_TIM->CNT)/TEST_TIM_FRE));   // Writing end, display time taken
  printf("reading start\n\r");    // Reading start message
  SDRAM_TEST_TIM->CNT=0;              // Resetting the timer counter
  LL_TIM_EnableCounter(SDRAM_TEST_TIM);  // Enable the timer
  #endif
  for(temp=0; temp<SDRAM_TEST_SIZE; temp+=4)
  {
    if((*(uint32_t*)(SDRAM_TEST_ADDRESS_START+temp)) != temp)
    {
      printf("0x%x\n\r", temp);
      printf("find err on 0x%x\n\r", (SDRAM_TEST_ADDRESS_START+temp));
      err++;
    }
  }
  #if SDRAM_PRINT
  LL_TIM_DisableCounter(SDRAM_TEST_TIM);    // Disable the timer
  printf("reading end, cost:%1.2fS\n\r", ((float)(SDRAM_TEST_TIM->CNT)/TEST_TIM_FRE));   // Reading end, display time taken
  printf("/************ HALF WORD TEST ************/\n\r");  // Half-word test start
  printf("writing start\n\r");    // Writing start message
  SDRAM_TEST_TIM->CNT=0;                // Resetting the timer counter
  LL_TIM_EnableCounter(SDRAM_TEST_TIM);  // Enable the timer
  #endif
  for(temp=0; temp<SDRAM_TEST_SIZE; temp+=2)
  {
    *(unsigned short*)(SDRAM_TEST_ADDRESS_START+temp) = temp;
  }
  #if SDRAM_PRINT
  LL_TIM_DisableCounter(SDRAM_TEST_TIM);  // Disable the timer
  printf("writing end, cost:%1.2fS\n\r", ((float)(SDRAM_TEST_TIM->CNT)/TEST_TIM_FRE));   // Writing end, display time taken
  printf("reading start\n\r");    // Reading start message
  SDRAM_TEST_TIM->CNT=0;              // Resetting the timer counter
  LL_TIM_EnableCounter(SDRAM_TEST_TIM);  // Enable the timer
  #endif
  for(temp=0; temp<SDRAM_TEST_SIZE; temp+=2)
  {
    if((*(unsigned short*)(SDRAM_TEST_ADDRESS_START+temp)) != (unsigned short)temp)
    {
      printf("find err on 0x%x\n\r", (SDRAM_TEST_ADDRESS_START+temp));
      err++;
    }
  }
  #if SDRAM_PRINT
  LL_TIM_DisableCounter(SDRAM_TEST_TIM);    // Disable the timer
  printf("reading end, cost:%1.2fS\n\r", ((float)(SDRAM_TEST_TIM->CNT)/TEST_TIM_FRE));   // Reading end, display time taken
  printf("/*************** BYTE TEST ***************/\n\r");  // Byte test start
  printf("writing start\n\r");    // Writing start message
  SDRAM_TEST_TIM->CNT=0;                // Resetting the timer counter
  LL_TIM_EnableCounter(SDRAM_TEST_TIM);  // Enable the timer
  #endif
  for(temp=0; temp<SDRAM_TEST_SIZE; temp++)
  {
    *(unsigned char*)(SDRAM_TEST_ADDRESS_START+temp) = (unsigned char)temp;
  }
  #if SDRAM_PRINT
  LL_TIM_DisableCounter(SDRAM_TEST_TIM);  // Disable the timer
  printf("writing end, cost:%1.2fS\n\r", ((float)(SDRAM_TEST_TIM->CNT)/TEST_TIM_FRE));   // Writing end, display time taken
  printf("reading start\n\r");    // Reading start message
  SDRAM_TEST_TIM->CNT=0;              // Resetting the timer counter
  LL_TIM_EnableCounter(SDRAM_TEST_TIM);  // Enable the timer
  #endif
  for(temp=0; temp<SDRAM_TEST_SIZE; temp++)
  {
    if((*(unsigned char*)(SDRAM_TEST_ADDRESS_START+temp)) != (unsigned char)temp)
    {
      printf("find err on 0x%x\n\r", (SDRAM_TEST_ADDRESS_START+temp));
      err++;
    }
  }
  #if SDRAM_PRINT
  LL_TIM_DisableCounter(SDRAM_TEST_TIM);    // Disable the timer
  printf("reading end, cost:%1.2fS\n\r", ((float)(SDRAM_TEST_TIM->CNT)/TEST_TIM_FRE));   // Reading end, display time taken
  #endif
  if(err>0)
  {
    printf("find %d err\n\r", err);
  }
  else
  {
    printf("0x%X BYTE CHECKED, NO ERROR\n\r", SDRAM_TEST_SIZE);
  }
  printf("/************ SDRAM TEST COMPLETE ************/\n\r");
}

代码里有个要命的坑,读写涉及到的变量不可以加volatile,否则会导致写入极端慢,务必注意

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值