STM32----SDRAM配置

一、硬件环境

       野火stm32F429第一代开发板,主频180。SDRAM为:IS42S16400J,容量8M/byte。

接线如下:

如何接线,需要参考两个文件。一个是stm32参考手册,一个是SDRAM数据手册。

stm32参考手册中关于FMC引脚说明如下:

SDRAM数据手册,太容易找就不贴出来了。

需要注意的是,FMC映射到SDRAM有两个bank可以选择。从上图可知选择不同的bank SDRAM需要接到MCU不同的

SDCKE以及SDNE引脚,且程序中应根据引脚选择驱动对应的bank。

 

二、初始化程序

程序初始化,只需按照SDRAM DATASHEET提供的时序初始化SDRAM芯片,填充FMC中SDRAM有关结构体的时序参数即可。

FMC控制SDRAM的初始化结构体主要有3个。

(1)初始化参数结构体

  FMC_SDRAMInitTypeDef  FMC_SDRAMInitStructure;

在此结构体设置FMC映射的SDRAM bank,突发模式,行列长度,ram的bank数量,时钟分频等参数:

2)时序结构体

这个结构体主要设置SDRAM的读、写、预充电等的时序,具体填充的参数参考SDRAM手册:

需要注意的是,结构体并没有清楚写出tMRD,tRAS等字样,需要自己了解结构体成员的意义,才能从SDRAM

的手册中找到对应的参数填充。

(3)命令结构体

这个结构体主要使用来完成SDRAM的初始化步骤,按照SDRAM手册提供的步骤进行即可:

一个个步骤进行,即可成功初始化SDRAM:

   最后切记,要设置刷新计数器,相关计算方法如下:

   

  /* 设置刷新计数器 */
	/*刷新速率 = (COUNT + 1) x SDRAM 频率时钟
		COUNT =( SDRAM 刷新周期/行数) - 20*/
  /* 64ms/4096=15.62us  (15.62 us x FSDCLK) - 20 =1386 */
  FMC_SetRefreshCount(1386);
  /* 发送上述命令*/
  while(FMC_GetFlagStatus(FMC_BANK_SDRAM, FMC_FLAG_Busy) != RESET)
  {
  }

模式寄存器参数解析如下图:

三、SDRAM读写

       底层的时序由FMC完成,我们只需要像操控内存一样操控SDRAM即可。而SDRAM映射的地址,则可根据我们选择的bank

因为填充FMC结构体的时候是选择了Bnak2的,所以对应的地址:0xD000 0000 就是SDRAM的起始地址。

结束地址根据SDRAM的容量计算可知是:0xD07F FFFF。

完整的初始化代码如下:

/**
  * @brief  初始化配置使用SDRAM的FMC及GPIO接口,
  *         本函数在SDRAM读写操作前需要被调用
  * @param  None
  * @retval None
  */
void SDRAM_Init(void)
{
        FMC_SDRAMInitTypeDef  FMC_SDRAMInitStruct;
	FMC_SDRAMTimingInitTypeDef  FMC_SDRAMTimingStruct;
        FMC_SDRAMCommandTypeDef  FMC_SDRAMCommandStruct;


        //1、初始化GPIO
        SDRAM_GPIO_Config();
	
	
	//2、开启时钟与配置SDRAM结构体
	RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
	
	FMC_SDRAMTimingStruct.FMC_ExitSelfRefreshDelay = 6;  //tXSR
	FMC_SDRAMTimingStruct.FMC_LoadToActiveDelay = 2;     //tMRD
	FMC_SDRAMTimingStruct.FMC_RCDDelay = 2;              //tRCD
	FMC_SDRAMTimingStruct.FMC_RowCycleDelay = 6;         //tRC
	FMC_SDRAMTimingStruct.FMC_RPDelay = 2;               //tRP
	FMC_SDRAMTimingStruct.FMC_SelfRefreshTime = 4;       //tRAS
	FMC_SDRAMTimingStruct.FMC_WriteRecoveryTime = 2;     //tWR

	FMC_SDRAMInitStruct.FMC_Bank = FMC_Bank2_SDRAM;
	FMC_SDRAMInitStruct.FMC_CASLatency = FMC_CAS_Latency_2;
	FMC_SDRAMInitStruct.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b;
	FMC_SDRAMInitStruct.FMC_RowBitsNumber = FMC_RowBits_Number_12b;
	FMC_SDRAMInitStruct.FMC_InternalBankNumber = FMC_InternalBank_Number_4;
	FMC_SDRAMInitStruct.FMC_ReadBurst = FMC_Read_Burst_Enable;
	FMC_SDRAMInitStruct.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_0;  //读延迟
	FMC_SDRAMInitStruct.FMC_SDClockPeriod = FMC_SDClock_Period_2;  //2分频 
	FMC_SDRAMInitStruct.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b;
	FMC_SDRAMInitStruct.FMC_WriteProtection = FMC_Write_Protection_Disable;
	FMC_SDRAMInitStruct.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingStruct;
	
	FMC_SDRAMInit(&FMC_SDRAMInitStruct);
	
	
	//3、按照SDRAM初始化顺序初始化SDRAM
	
	//CLK使能
	FMC_SDRAMCommandStruct.FMC_AutoRefreshNumber = 0;
	FMC_SDRAMCommandStruct.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled;
	FMC_SDRAMCommandStruct.FMC_CommandTarget = FMC_Command_Target_bank2;
	FMC_SDRAMCommandStruct.FMC_ModeRegisterDefinition = 0;
	
	while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET); 	
	FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStruct);
		
	//所有bank预充电
	FMC_SDRAMCommandStruct.FMC_AutoRefreshNumber = 0;
	FMC_SDRAMCommandStruct.FMC_CommandMode = FMC_Command_Mode_PALL;
	FMC_SDRAMCommandStruct.FMC_CommandTarget = FMC_Command_Target_bank2;
	FMC_SDRAMCommandStruct.FMC_ModeRegisterDefinition = 0;

	while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET); 
	FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStruct);
	
	//自动刷新2次
	FMC_SDRAMCommandStruct.FMC_AutoRefreshNumber = 2;
	FMC_SDRAMCommandStruct.FMC_CommandMode = FMC_Command_Mode_AutoRefresh;
	FMC_SDRAMCommandStruct.FMC_CommandTarget = FMC_Command_Target_bank2;
	FMC_SDRAMCommandStruct.FMC_ModeRegisterDefinition = 0;

	while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET); 
	FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStruct);	
	
	//设置模式寄存器
	FMC_SDRAMCommandStruct.FMC_AutoRefreshNumber = 1;  //此处设置为0也能通过测试
	FMC_SDRAMCommandStruct.FMC_CommandMode = FMC_Command_Mode_LoadMode;
	FMC_SDRAMCommandStruct.FMC_CommandTarget = FMC_Command_Target_bank2;
	FMC_SDRAMCommandStruct.FMC_ModeRegisterDefinition =
                                   SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL| \
                                 SDRAM_MODEREG_OPERATING_MODE_STANDARD| \
                                          SDRAM_MODEREG_CAS_LATENCY_2 | \
                                          SDRAM_MODEREG_BURST_LENGTH_8| \
                                  SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;

	while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET); 
	FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStruct);		
	
	  /* 设置刷新计数器 */
	/*刷新速率 = (COUNT + 1) x SDRAM 频率时钟
		COUNT =( SDRAM 刷新周期/行数) - 20*/
        /* 64ms/4096=15.62us  (15.62 us x FSDCLK) - 20 =1386 */
        FMC_SetRefreshCount(1386);
	while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET); 
	FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStruct);			
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值