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,否则会导致写入极端慢,务必注意