【应用笔记】AN1082_APM32F4xx_SDRAM应用笔记

引言

本应用笔记提供如何在APM32F4xx系列上配置和应用DMC接口从而访问SDRAM的指南。

SDRAM简介

SDRAM全称为Synchronous Dynamic Random Access Memory,同步动态随机存储器。同步是指数据的传输共用一个时钟线作为基准;动态是指存储阵列需要不断的刷新来保证数据不丢失;随机是指数据不是线性依次存储,而是自由指定地址进行数据读写。

存储结构

SDRAM中,每个行列地址组合对应一个存储单元,存储单元的大小由SDRAM的规格决定,通常为16bit。一块SDRAM通常有2个Bank或4个Bank。一块SDRAM的容量计算是:(2^行地址位数)x(2^列地址位数)x(存储单元大小)x(Bank数量)。

SDRAM参数简述

CAS Latency

CAS指的是列地址选通信号,地址寻址先行地址再列地址,所以等地址选通之后,就确定了存储单元,接下来就是数据传输。CAS等待时间(CAS Latency)指的是CAS发出之后到第一笔数据输出的这一段时间。CAS Latency的数值不能超过芯片的设计规范,否则会导致内存的不稳定。

tRCD

tRCD即RAS to CAS Delay,翻译过来就是RAS到CAS延时,RAS为行地址选通信号,CAS为列地址选通信号。这是根据芯片存储阵列电子元件响应时间所定制的延迟。

tRP

在对SDRAM进行完读写操作后,如果要对同一个Bank的另一行进行寻址,就要将原来有效的行关闭,重新发送行/列地址。关闭现有工作行,准备打开新行的操作就是预充电(Precharge)。在发出预充电命令后,需要经过一段时间才能允许发送RAS信号打开新的工作行,这段时间称为tRP(RAS Precharge Time)。

tRAS

tRAS即Active to Precharge Command,表示行激活到预充电命令的间隔。

tWR

tWR即Write Recovery Time,可以保证数据的可靠写入。

突发长度

突发(Burst)是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输所涉及到存储单元的数量就是突发长度。

刷新

动态存储器要不断进行刷新(Refresh)才能保留住数据,因此它是SDRAM最重要的操作。刷新操作有固定的周期,依次对所有行进行操作,以保留那些久久没有经历重写的存储体中的数据。

两个刷新的间隔多长合适呢?目前公认的标准是,存储体中电容的数据有效保存期上限是64ms,也就是刷新所有行的时间是64ms,这样刷新速度就是:行数量/64ms。

刷新操作分为两种:自动刷新(Auto Refresh)与自刷新(Self Refresh)。两种刷新都不需要外部提供行地址信息,因为这是一个内部的自动操作。

对于自动刷新,SDRAM内部有一个行刷新计数器自动地依次生成行地址。由于刷新是针对一行中的所有存储体进行,所以无需列寻址,或者说CAS在RAS之前有效。所以,自动刷新又称为CBR式刷新。由于刷新涉及到所有Bank,因此在刷新过程中,所有Bank都停止工作,而每次刷新所占用的时间为9个时钟周期,之后就可以进入正常的工作状态,也就是说在这9个时钟周期内,所有工作指令只能等待而无法执行。64ms之后则再次对同一行进行刷新,如此周而复始进行循环刷新。

自刷新则主要用于休眠模式低功耗状态下的数据保存,这方面最著名的应用就是STR。在发出自动刷新命令时,将CKE置于无效状态,就进入了自刷新模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作。在自刷新期间除了CKE之外所有外部信号都是无效的,只有重新使能CKE才能退出自刷新模式并进入正常操作状态

 

DMC简介

DMC是一个动态存储控制器,通过它外接SDRAM能够实现SDRAM的读写。如下图1所示,通过DMC可以将SDRAM的数据与AHB总线进行传输。

图 1 DMC结构框图

DMC引脚定义

DMC的引脚定义如下表所示:

表格 1 DMC引脚定义

信号名称

输入/输出

管脚

功能

A0

输出

PF1

地址

A1

输出

PF2

地址

A2

输出

PF3

地址

A3

输出

PF4

地址

A4

输出

PF6

地址

A5

输出

PF7

地址

A6

输出

PF8

地址

A7

输出

PF9

地址

A8

输出

PF10

地址

A9

输出

PH3

地址

A10

输出

PF0

地址

D0

输入/输出

PG3

双向数据

D1

输入/输出

PG4

双向数据

D2

输入/输出

PG5

双向数据

D3

输入/输出

PG6

双向数据

D4

输入/输出

PG8

双向数据

D5

输入/输出

PH13

双向数据

D6

输入/输出

PH15

双向数据

D7

输入/输出

PI3

双向数据

D8

输入/输出

PH8

双向数据

D9

输入/输出

PH10

双向数据

D10

输入/输出

PD10

双向数据

D11

输入/输出

PD12

双向数据

D12

输入/输出

PD13

双向数据

D13

输入/输出

PD14

双向数据

D14

输入/输出

PD15

双向数据

D15

输入/输出

PG2

双向数据

BA

输出

PI11

Bank 地址

CKE

输出

PH5

时钟使能

CLK/CK

输出

PG1

时钟

LDQM

输入

PG15

16位数据写入

UNQM

输入

PF11

16位数据读取

NWE

输出

PI7

写使能

NCAS

输出

PI8

列地址位选通命令

NRAS

输出

PI9

行地址位选通命令

NCS

输出

PI10

片选

行列地址线共用引脚,当前APM32F407支持一根bank地址线,即可以支持2个bank。

DMC引脚初始化

DMC的引脚初始化可以参考如下代码示例,GPIO需要配置引脚复用:

    GPIO_Config_T gpioConfig;

    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOD);

    gpioConfig.speed = GPIO_SPEED_50MHz;

    gpioConfig.mode = GPIO_MODE_AF;

    gpioConfig.otype = GPIO_OTYPE_PP;

    gpioConfig.pupd = GPIO_PUPD_NOPULL;

gpioConfig.pin = GPIO_PIN_10;

/** PD10引脚作为配置参考,其他引脚类似 */

GPIO_Config(GPIOD, &gpioConfig);

/** 需要配置引脚复用为EMMC */

    GPIO_ConfigPinAF(GPIOD, GPIO_PIN_SOURCE_10, GPIO_AF_EMMC);

DMC的初始化及SDRAM访问

SDRAM应用的流程图:

图 2 程序流程图

初始化DMC

DMC初始化结构体

DMC_Config_T结构体定义在APM32F4xx_dmc.h文件中,具体定义如下:

/**

 * @brief DMC Config struct

 */

typedef struct

{

    DMC_BANK_WIDTH_T        bankWidth;     //!< Number of bank bits

    DMC_ROW_WIDTH_T         rowWidth;      //!< Number of row address bits

    DMC_COL_WIDTH_T         colWidth;      //!< Number of col address bits

    DMC_CLK_PHASE_T         clkPhase;      //!< Clock phase

    DMC_TimingConfig_T      timing;        //!< Timing

}DMC_Config_T;

结构体成员中:

bankWidth表示bank地址宽度,设置为1时,能支持2个bank,为2时,支持4个bank;

rowWidth 表示行地址宽度

colWidth表示行地址宽度

clkPhase表示时钟相位

timing为DMC的时序配置,对应DMC_TimingConfig_T结构体成员。

目前APM32F407DMC支持行地址11位,支持列地址8位,支持1bank,在存储单元为16bit数据即2bytes的情况下,支持的最大容量为2^11 * 2^8 * 2 * 2 = 2Mbytes

timing类型为DMC_TimingConfig_T结构体,其定义在APM32F4xx_dmc.h文件中,具体定义如下:

/**

 * @brief Timing config definition

 */

typedef struct

{

    uint32_t latencyCAS : 2;   //!< DMC_CAS_LATENCY_T

    uint32_t tRAS    : 4;       //!< DMC_RAS_MINIMUM_T

    uint32_t tRCD    : 3;       //!< DMC_DELAY_TIME_T

    uint32_t  tRP    : 3;       //!< DMC_PRECHARGE_T

    uint32_t  tWR    : 2;       //!< DMC_NEXT_PRECHARGE_T

    uint32_t  tARP   : 4;       //!< DMC_AUTO_REFRESH_T

    uint32_t  tCMD   : 4;       //!< DMC_ATA_CMD_T

    uint32_t  tXSR   : 9; //!< auto-refresh commands, can be 0x000 to 0x1FF

    uint16_t  tRFP   : 16;//!< Refresh period, can be 0x0000 to 0xFFFF

}DMC_TimingConfig_T;

结构体成员中:

latencyCAS表示CAS等待时间;

tRAS表示行激活和预充电的之间的最小时间;

tRCD表示RAS 到 CAS 的延迟时间;

tRP表示预充电周期;

tWR表示写最后一个数据到下一次预充电的时间;

tARP 表示两次自动刷新命令间的最小时间间隔;

tCMD 表示Active to active 命令周期;

tXSR 表示退出自刷新切换至激活命令或自动刷新读命令之间的最小间隔时间;

tRFP 表示连续两次刷新间隔;

上述参数的单位为DMC时钟周期,DMC的时钟由AHB时钟经过DMC分频而来。

 

DMC配置

配置DMC可以参考下方代码:

    uint32_t sdramCapacity;

    DMC_Config_T dmcConfig;

    DMC_TimingConfig_T timingConfig;

    RCM_EnableAHB3PeriphClock(RCM_AHB3_PERIPH_EMMC);

    timingConfig.latencyCAS = DMC_CAS_LATENCY_3;

    timingConfig.tARP       = DMC_AUTO_REFRESH_10;  

    timingConfig.tRAS       = DMC_RAS_MINIMUM_2;   

    timingConfig.tCMD       = DMC_ATA_CMD_1; 

    timingConfig.tRCD       = DMC_DELAY_TIME_1;

    timingConfig.tRP        = DMC_PRECHARGE_1; 

    timingConfig.tWR        = DMC_NEXT_PRECHARGE_2;   

    timingConfig.tXSR       = 3;                      

    timingConfig.tRFP       = 0x2F9;              

    dmcConfig.bankWidth     = DMC_BANK_WIDTH_1;   

    dmcConfig.clkPhase      = DMC_CLK_PHASE_REVERSE; 

    dmcConfig.rowWidth      = DMC_ROW_WIDTH_11;   

    dmcConfig.colWidth      = DMC_COL_WIDTH_8;      

    dmcConfig.timing        = timingConfig;

    DMC_Config(&dmcConfig);  //!< 配置DMC

    DMC_EnableAccelerateModule(); //!<开启DMC缓冲器,可以提升SDRAM读性能

    DMC_Enable(); //!< 使能DMC

在配置时序参数时需要根据SDRAM的数据手册,以及当前系统时钟分配到DMC外设的时钟频率来对各个参数进行合理配置。上述代码中的参数配置示例仅供参考。

SDRAM访问

SDRAM的起始地址为0x60000000,根据不同容量,其结束地址与之对应。例如容量为2Mbytes的SDRAM的结束地址为0x60200000。在程序中我们访问SDRAM可以通过地址直接访问,无需解锁。

例如对SDARM的地址0x60000000进行数据读取,读取大小为1个字节,则可以使用语句:

uint8_t data = *(uint8_t*) (0x6000000);

例如对SDARM的地址0x60000000写入一个字节,为0x55,则可以使用语句:

*(uint8_t*) (0x6000000) = 0x55;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值