历史上的今天
返回首页

历史上的今天

今天是:2025年06月29日(星期日)

2019年06月29日 | STM32----SDRAM配置

2019-06-29 来源:eefocus

一、硬件环境


       野火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);

}


推荐阅读

史海拾趣

GSME Electronics公司的发展小趣事

随着生产设备的引进和技术团队的壮大,GSME Electronics开始专注于半导体器件的研发与生产。公司产品线逐渐丰富,涵盖了片式各种系列表面贴装的小信号三极管、中功率驱动三极管、肖特基、开关二极管及小功率可控硅等多种半导体分立器件。这些产品广泛应用于移动通信、计算机、消费类电子信息产品、家用电器、工业自动化控制设备等领域,满足了市场的多样化需求,推动了公司业务的快速增长。

ADI(亚德诺半导体)公司的发展小趣事

GSME Electronics深知品质是企业发展的生命线。因此,公司积极寻求并通过了ISO9001:2000质量管理体系、ISO14001环境管理体系以及IECQ QC080000危害物质流程管理体系等三项认证。同时,公司还遵循欧盟ROHS指令,通过了无铅、汞、无公害认证,确保产品符合国际环保标准。这些举措不仅提升了公司的市场竞争力,也赢得了国内外客户的广泛认可。

启珑(CHIPLON)公司的发展小趣事

随着公司业务的不断拓展和市场竞争的日益激烈,GSME Electronics开始实施国际化战略。公司积极参与国际市场竞争,加强与国外客户的合作与交流,不断提升产品的国际竞争力。同时,公司还注重品牌建设,通过提升产品质量和服务水平,树立了良好的品牌形象。如今,“桂微牌”产品已经在国内外市场上赢得了广泛的认可度和美誉度,为公司未来的发展奠定了坚实的基础。

CUI Inc.公司的发展小趣事

自1989年成立以来,CUI Inc.一直站在电源设计的前沿。公司不断投资于研发,致力于开发出更高效、更环保的电源产品。通过引入先进的电源管理技术和创新的设计方法,CUI成功地帮助客户提高了应用的能效,减少了能源消耗。这种对电源技术的专注和创新,使CUI在竞争激烈的电子行业中脱颖而出,赢得了众多客户的信赖和好评。

G24 Innovations公司的发展小趣事

在快速发展的同时,远阳公司始终不忘履行社会责任。公司积极参与公益事业,通过捐款捐物、志愿服务等方式,回馈社会、关爱弱势群体。此外,远阳还注重环境保护和可持续发展,积极推广绿色生产、节能减排等环保理念。公司建立了完善的环境管理体系和能源管理体系,通过技术创新和管理优化,不断降低生产过程中的能耗和排放。这些举措不仅提升了远阳的企业形象和社会声誉,也为企业的长远发展奠定了坚实基础。

Anaren Ceramics公司的发展小趣事

Anaren Ceramics公司在电子行业中崭露头角,首先得益于其在陶瓷材料技术方面的重大突破。公司研发了一种新型的陶瓷材料,具有优异的绝缘性能和高温稳定性,这为当时的电子行业提供了前所未有的解决方案。随着这种新型陶瓷材料在市场上的广泛应用,Anaren Ceramics公司的知名度逐渐提升,逐渐成为了行业内的佼佼者。

问答坊 | AI 解惑

电容隔直通交问题

对于电容器构造的简单描述是这样的:“一般由用电介质隔开的两个金属板构成。” 而关于电流的定义是这样的,“单位时间内通过导体横截面的电荷量。” 如果把电容看成一个横截面,那么 在电容两端加恒定电压U时,就会在两个金属板上分别积累正负 ...…

查看全部问答>

我的FLUKE196坏了,请大家给个建议。

fluke196示波表能做表,二个通道不示波,不知道是设置问题还是坏了,那位大虾指点一下 。…

查看全部问答>

有人询问NANDFLASH的寻址方式,简单说下

Nand Flash结构与读写分析 NAND Flash 的数据是以bit 的方式保存在memory cell,一般来说,一个cell 中只能存储一个bit。这些cell 以8 个或者16 个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device 的位宽。这些Line 会再 ...…

查看全部问答>

M22 如何发彩信

Atmega64 加明基M22gsm模块,如何实现彩信收发。也就是说与gprs连接需要发送那些数据?!!!。。。…

查看全部问答>

这个小程序有问题吗?

#include __CONFIG (INTRC & PROTECT & MCLREN & WDTEN); const unsigned char cs @ 0x1FF; void DelayUs( int  x)    // 32US {while(--x!=0)   { CLRWDT();     NOP();     unsigned ...…

查看全部问答>

求助:关于开发windows的实时控制系统

现在有一个应用程序,实时性不够,想在windows下加一个实时模块!经过查找资料,目前确定的方案是添加一个实时驱动模块,而这个模块就用一个内核模式驱动程序来实现!该程序通过接管实时定时器的中断,也就是系统时钟中断,然后先将控制权交给实时 ...…

查看全部问答>

请教EVC动态库调用方法

在EVC下开发程序,有一个基于MFC Extension的动态库,其中包含有多个对话框架及一个菜单项,现在创建一个MFC应用程序,不知怎么调用此动态库,求助一下大家,谢谢!…

查看全部问答>

请使用英文版 Visual studio 2005/2008的朋友帮个小忙,谢谢!

公司要找其它公司做应用软件,用WINCE生成的SDK还得附加个英文的使用说明,但是我的VS是中文版的,截图全是中文字,公司的人说不行,所以请使用英文版的朋友帮我截个图,非常感谢! 发到我的邮箱里就可以veabolho@126.com 截图的内容就像这张 …

查看全部问答>

如何将堆栈放置在RAM最尾端?

最近做项目的时候碰到了一个因为局部变量导致堆栈越界的问题,虽然最后靠扩大堆栈空间暂时解决了,但这也限制了全局变量的定义。有没有一种好的方法来解决这些问题了?看了看编译后的MAP文件,发现MDK将STACK放在了最后一个全局变量的后面。现 ...…

查看全部问答>

激电源及变压器设计

激电源及变压器设计…

查看全部问答>