在线时间717 小时
UID3469866
注册时间2018-4-19
NXP金币3753

TA的每日心情 | 慵懒 2025-5-7 08:45 |
---|
签到天数: 279 天 连续签到: 1 天 [LV.8]以坛为家I
版主
  
- 积分
- 11046

- 最后登录
- 2025-8-15
|
本帖最后由 az158 于 2021-8-23 18:41 编辑
今天试试SDRAM部分好不好使。官方原设计是使用两颗16位TSOP的SDRAM组成32位共计64MB,主频可以跑到200MHz。这里我因为想要设计的更加小巧,就换成了单颗32位BGA封装的SDRAM,容量32MB,主频可以跑到166MHz,这里硬件改动是比较大的,需要修改例程代码。先看一下原理图。
然后对官方提供的SDRAM例程进行修改,使用MCUXpresso Config Tools配合生成部分代码(不知道为什么,MCUXpresso Config Tools无法设置SDRAM为32位,也没有细研究为啥,有知道的大佬可以交流一下)。
下面贴出主要代码,注意SDRAM外设主频已被降到166以内(下文代码未体现)。
- semc_config_t SEMC_config = {
- .dqsMode = kSEMC_Loopbackdqspad,
- .cmdTimeoutCycles = 0U,
- .busTimeoutCycles = 0U,
- .queueWeight = {
- .queueaEnable = true,
- .queueaWeight = {
- .queueaConfig = {
- .qos = 0UL,
- .aging = 0UL,
- .slaveHitSwith = 0UL,
- .slaveHitNoswitch = 0UL
- },
- },
- .queuebEnable = true,
- .queuebWeight = {
- .queuebConfig = {
- .qos = 0UL,
- .aging = 0UL,
- .slaveHitSwith = 0UL,
- .weightPagehit = 0UL,
- .bankRotation = 0UL
- },
- }
- }
- };
- semc_sdram_config_t SEMC_sdram_struct = {
- .csxPinMux = kSEMC_MUXCSX0,
- .address = 0x80000000UL,
- .memsize_kbytes = 32768,
- .portSize = kSEMC_PortSize16Bit,
- .burstLen = kSEMC_Sdram_BurstLen8,
- .columnAddrBitNum = kSEMC_SdramColunm_9bit,
- .casLatency = kSEMC_LatencyThree,
- .tPrecharge2Act_Ns = 18U,
- .tAct2ReadWrite_Ns = 18U,
- .tRefreshRecovery_Ns = 127U,
- .tWriteRecovery_Ns = 12U,
- .tCkeOff_Ns = 42U,
- .tAct2Prechage_Ns = 42U,
- .tSelfRefRecovery_Ns = 67U,
- .tRefresh2Refresh_Ns = 60U,
- .tAct2Act_Ns = 60U,
- .tPrescalePeriod_Ns = 160UL,
- .tIdleTimeout_Ns = 91UL,
- .refreshPeriod_nsPerRow = 64UL,
- .refreshUrgThreshold = 64UL,
- .refreshBurstLen = 1U,
- .delayChain = 0U
- };
- status_t BOARD_InitSEMC(void)
- {
- semc_config_t config;
- semc_sdram_config_t sdramconfig;
- uint32_t clockFrq = EXAMPLE_SEMC_CLK_FREQ;
- /* Initializes the MAC configure structure to zero. */
- memset(&config, 0, sizeof(semc_config_t));
- memset(&sdramconfig, 0, sizeof(semc_sdram_config_t));
- /* Initialize SEMC. */
- SEMC_GetDefaultConfig(&config);
- config.dqsMode = kSEMC_Loopbackdqspad; /* For more accurate timing. */
- SEMC_Init(SEMC, &config);
- /* Configure SDRAM. */
- sdramconfig.csxPinMux = kSEMC_MUXCSX0;
- sdramconfig.address = 0x80000000;
- sdramconfig.memsize_kbytes = 32 * 1024; /* 32MB = 32*1024*1KBytes*/
- sdramconfig.portSize = kSEMC_PortSize32Bit;
- sdramconfig.burstLen = kSEMC_Sdram_BurstLen8;
- sdramconfig.columnAddrBitNum = kSEMC_SdramColunm_9bit;
- sdramconfig.casLatency = kSEMC_LatencyThree;
- sdramconfig.tPrecharge2Act_Ns = 18; /* Trp 18ns */
- sdramconfig.tAct2ReadWrite_Ns = 18; /* Trcd 18ns */
- sdramconfig.tRefreshRecovery_Ns = 70; /* Use the maximum of the (Trfc , Txsr). */
- sdramconfig.tWriteRecovery_Ns = 12; /* 12ns */
- sdramconfig.tCkeOff_Ns =
- 42; /* The minimum cycle of SDRAM CLK off state. CKE is off in self refresh at a minimum period tRAS.*/
- sdramconfig.tAct2Prechage_Ns = 42; /* Tras 42ns */
- sdramconfig.tSelfRefRecovery_Ns = 70;
- sdramconfig.tRefresh2Refresh_Ns = 60;
- sdramconfig.tAct2Act_Ns = 60;
- sdramconfig.tPrescalePeriod_Ns = 160 * (1000000000 / clockFrq);
- sdramconfig.refreshPeriod_nsPerRow = 64 * 1000000 / 4096; /* 64ms/8192 */
- sdramconfig.refreshUrgThreshold = sdramconfig.refreshPeriod_nsPerRow;
- sdramconfig.refreshBurstLen = 1;
- sdramconfig.delayChain = 2;
- sdramconfig.tIdleTimeout_Ns = 92;
- return SEMC_ConfigureSDRAM(SEMC, kSEMC_SDRAM_CS0, &sdramconfig, clockFrq);
- }</font>
复制代码
运行效果,看到这一排Succeed太舒服了。没翻车,nice。
最后补充一下,因为SDRAM部分占用引脚实在过多,而且SDRAM高16位数据线引脚的电源域(EMC2)是独立的(这点设计要给NXP工程师点赞,太贴心了)。有需求更多引脚的情况,可以使用单颗16位的SDRAM,这样可以空出更多的io用作他用。
|
|