天天看点

STM32F429 外部SDRAM调试记录

记录自己学习的过程,欢迎交流

STM32F429 外部SDRAM调试记录

直接生成之后是无法直接使用。

添加函数,配置了图形相关设置后该函数会自动生成。

#define SDRAM_MODEREG_BURST_LENGTH_1             ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2             ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4             ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8             ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((uint16_t)0x0200)

void MX_SDRAM_InitEx(void)
{
  __IO uint32_t tmpmrd = 0;
  FMC_SDRAM_CommandTypeDef Command;
  /* Step 1: Configure a clock configuration enable command */
  Command.CommandMode            = FMC_SDRAM_CMD_CLK_ENABLE;
  Command.CommandTarget          =  FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber      = 1;
  Command.ModeRegisterDefinition = 0;
 
  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &Command, 0x1000);
 
  /* Step 2: Insert 100 us minimum delay */ 
  /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
  HAL_Delay(1);
    
  /* Step 3: Configure a PALL (precharge all) command */ 
  Command.CommandMode            = FMC_SDRAM_CMD_PALL;
  Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber      = 1;
  Command.ModeRegisterDefinition = 0;
 
  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &Command, 0x1000);  
  
  /* Step 4: Configure an Auto Refresh command */ 
  Command.CommandMode            = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber      = 8;
  Command.ModeRegisterDefinition = 0;
 
  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &Command, 0x1000);
  
  /* Step 5: Program the external memory mode register */
  tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |\
                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |\
                     SDRAM_MODEREG_CAS_LATENCY_3           |\
                     SDRAM_MODEREG_OPERATING_MODE_STANDARD |\
                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
 
  Command.CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;
  Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber      = 1;
  Command.ModeRegisterDefinition = tmpmrd;
 
  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &Command, 0x1000);
  
  /* Step 6: Set the refresh rate counter */
  /* Set the device refresh rate */
  HAL_SDRAM_ProgramRefreshRate(&hsdram1, 683); 
}
           

直接采用他人例程,使用的SDRAM_DEVICE_ADDR 0xD0000000是采用STM32中SDRAM Bank 2的地址

///*绝对定位方式访问SDRAM,这种方式必须定义成全局变量*/
#define SDRAM_DEVICE_ADDR 0xD0000000
uint8_t testValue __attribute__((at(SDRAM_DEVICE_ADDR)));
void test_sdram(void)
{
	/*指针方式访问SDRAM*/
	{	
	 uint32_t temp;
	
	 printf("\r\n指针方式访问SDRAM\r\n");
	/*向SDRAM写入8位数据*/
	 *( uint8_t*) (SDRAM_DEVICE_ADDR ) = (uint8_t)0xAA;
	 printf("\r\n指针访问SDRAM,写入数据0xAA \r\n");

	 /*从SDRAM读取数据*/
	 temp =  *( uint8_t*) (SDRAM_DEVICE_ADDR );
	 printf("读取数据:0x%X \r\n",temp);

	 /*写/读 16位数据*/
	 *( uint16_t*) (SDRAM_DEVICE_ADDR+10 ) = (uint16_t)0xBBBB;
	 printf("指针访问SDRAM,写入数据0xBBBB \r\n");
	 
	 temp =  *( uint16_t*) (SDRAM_DEVICE_ADDR+10 );
	 printf("读取数据:0x%X \r\n",temp);


	 /*写/读 32位数据*/
	 *( uint32_t*) (SDRAM_DEVICE_ADDR+20 ) = (uint32_t)0xCCCCCCCC;
	 printf("指针访问SDRAM,写入数据0xCCCCCCCC \r\n");	 
	 temp =  *( uint32_t*) (SDRAM_DEVICE_ADDR+20 );
	 printf("读取数据:0x%X \r\n",temp);

	}
	
	/*绝对定位方式访问SDRAM,这种方式必须定义成全局变量*/
	{
		testValue = 0xDD;
		printf("\r\n绝对定位访问SDRAM,写入数据0xDD,读出数据0x%X,变量地址为%X\r\n",testValue,(uint32_t )&testValue);	 
	}

}