GD32450i-EVAL学习笔记 11 - EXMC&SDRAM

21 篇文章 37 订阅

目录

1 硬件接法

2 IO初始化

3 EXMC初始化

3.1 RCU时钟使能

3.2 配置SDRAM 控制寄存器 (EXMC_SDCTLx) (x=0, 1)

3.2.1 设置SDCLK[1:0]

3.2.2 设置BRSTRD

3.2.3 设置PIPED[1:0]

3.2.4 设置CL[1:0]

3.2.4 设置NBK(Bank数量)

3.2.4 设置SDW[1:0] (数据总线宽度)

 3.3 配置SDRAM 时序寄存器 (EXMC_SDTCFGx) (x=0, 1)

3.3.1 设置RPD[3:0] (仅SDTCFG0)

3.3.2 设置WRD[3:0](仅SDTCFG0)

3.3.3 设置ARFD[3:0](仅SDTCFG0)

3.3.4 设置RCD[3:0]

3.3.5 设置RASD[3:0]

3.3.6 设置XSRD[3:0]

3.3.7 设置LMRD[3:0]

3.3.8 等待SDRAM Ready

3.5  SDRAM时钟使能

3.5.1 选择SDRAM

3.5.2 设置时钟使能命令

3.5.3 设置自动刷新个数

3.5.4 设置MRC[12:0]

3.5.5 等待EXMC Ready

3.6 配置自动刷新命令

3.7 配置加载模式寄存器命令

3.8 设置自动刷新间隔寄存器 (EXMC_SDARI)

3.9 确认初始化完成

4 SDRAM的访问

外部存储器控制器 EXMC功能与STM的FSMC类似。EXMC可以把AMBA协议转换为专用的片外 存储器通信协议,包括SRAM、ROM、NOR Flash、NAND Flash、PC Card 和SDRAM 。可以把EXMC理解为将外部设备映射到内部地址线上,这样不管外部设备的总线类型,用户都可以将这些设备当做变量读写(也可以理解成一个文件,类似Linux里面的设备管理方式),而实际的时序操作都交给EXMC处理。

EXMC中对应SDRAM的空间地址:

1 硬件接法

开发板上的SDRAM芯片型号MT48LC16M16A2P-6AIT,Micron的256Mbit(16Mx16位)的SDR SDRAM,时钟频率143/166MHz,存取时间6ns。

GD32F450 EXMC最大地址线是26位(最大只能找到EXMC_A25,不过EXMC SDRAM的寄存器中最大行地址只能设置为13位,列地址最大11位),最大数据线是32位(最大只能找到EXMC_D31)。

MT48LC16M16A2P-6AIT的地址线是13位,数据线是16位的。

可以在datasheet中的2.6.4. GD32F450xx pin alternate function中以EXMC_*找到对应的IO。

注意GD32450i-EVAL板子上SDRAM的CKE脚(PC5)是与ETH的RXD1脚公用的,需要将JP17跳到SDRAM。

2 IO初始化

EXMC的IO口都是AF12。

地址线A0-A12都是唯一的IO(PF0-5, PF12-15, PG0-2),无复用。

数据线D0-D15都是唯一的IO(PD14-15, PD0-1, PE7-PE15, PD8-10),无复用。

DQM0和DQM1都是唯一的IO(PE0-1),无复用。

SDCKE0: GPIOC3、GPIOC5、GPIOH2

SDCKE1: GPIOB5、GPIOH7

BA0和BA1用的是地址线A14/A15,对应PG4-5,无复用。

SDCLK是唯一的IO(GPIOG8),无复用。

SDNCAS是唯一的IO(GPIOG15),无复用。

SDNRAS是唯一的IO(GPIOF11),无复用。

SDCKE0:GPIOC3、GPIOC5、GPIOH2

SDCKE1:GPIOB5、GPIOH7

SDNE0:GPIOC2、GPIOC4、GPIOH3

SDNE1:GPIOB6、GPIOH6

SDNWE:GPIOA7、GPIOC0、GPIOH5

注意这些IO不能用PULL UP,否则会导致写入0出错。

3 EXMC初始化

3.1 RCU时钟使能

RCU_AHB3EN |= 0x01;

AHB的最大时钟为200MHz。

3.2 配置SDRAM 控制寄存器 (EXMC_SDCTLx) (x=0, 1)

这个寄存器分2个,分别对应硬件上链接的是SDCKE0还是SDCKE1,而EXMC_SDCTL1的位10到位14是保留位,对应的设置是设置到EXMC_SDCTL0,也就是说如果选择SDCKE1,这2个寄存器都需要设置。

3.2.1 设置SDCLK[1:0]

由于GD32F450的最大时钟才100MHz(AHB / 2),比SDRAM的频率小的多,所以一般情况这个设置是0x10。

*REG_EXMC_SDRAM_SDCTL0 |= ((uint32_t)0x02 << 10);

更新一个调试碰到的问题,读写SDRAM不稳定,多个字节就出错,发现把这个参数改为0b11,即3个HCLK解决问题。 

3.2.2 设置BRSTRD

 这个参数一般是使能的。

*REG_EXMC_SDRAM_SDCTL0 |= ((uint32_t)0x2 << 10) | ((uint32_t)0x1 << 12)

3.2.3 设置PIPED[1:0]

3.2.4 设置CL[1:0]

 

SDRAM的Datasheet中有芯片的CL值。如上图CL为3。

3.2.4 设置NBK(Bank数量)

设置Bank数。

SDRAM的Datasheet中有芯片的Bank数,如上图。

3.2.4 设置SDW[1:0] (数据总线宽度)

SDRAM的Datasheet中有芯片的数据总线宽度,如上图。

3.2.5 设置RAW[1:0] 行地址位宽

行地址位宽如上图红圈内,这里都是13位。 

3.2.5 设置CAW[1:0] (列地址位宽

 

 3.3 配置SDRAM 时序寄存器 (EXMC_SDTCFGx) (x=0, 1)

时序寄存器和上一个的控制寄存器一样,分2个寄存器,也有部分位只有SDTCFG0有含义,如果用SDTCFG1的情况下也需要设置SDTCFG0的相应位(位12到位23)。

3.3.1 设置RPD[3:0] (仅SDTCFG0)

在SDRAM的Datasheet找RPD

最小值是12ns,而SDRAM的时钟为100MHz,即10ns,所以这个值应该最少设置成2。

3.3.2 设置WRD[3:0](仅SDTCFG0)

在SDRAM的Datasheet找WRD,位置应该和RPD接近

因为1CLK是10ns,所以参数选择1CLK + 6ns(大于12ns),这个参数应该设置为2.

3.3.3 设置ARFD[3:0](仅SDTCFG0)

60ns即6个Clock。

3.3.4 设置RCD[3:0]

18ns即2个Clock。

3.3.5 设置RASD[3:0]

42ns即5个Clock。

3.3.6 设置XSRD[3:0]

67ns即7个Clock。

3.3.7 设置LMRD[3:0]

3.3.8 等待SDRAM Ready

写完时序寄存器后需要通过判断SDRAM状态寄存器 (EXMC_SDSTAT)的位5 NRDY获知EXMC是否准备好。

3.5  SDRAM时钟使能

操作命令寄存器 (EXMC_SDCMD)以实现时钟使能。

3.5.1 选择SDRAM

3.5.2 设置时钟使能命令

即CMD[2:0] = 001 

3.5.3 设置自动刷新个数

这个配置是指在发送自动刷新命令“011”后,EXMC会做几次自动刷新?不理解这个设定,应该都只需要做一次刷新吧?

这里设置为默认1个自动刷新周期。

3.5.4 设置MRC[12:0]

 在SDRAM的Datasheet中查找mode register,可以找到这个寄存器的说明,这里不需要处理,设置MRC = 0

3.5.5 等待EXMC Ready

写完命令寄存器后先等待10ms,然后也需要判断SDRAM状态寄存器 (EXMC_SDSTAT)的位5 NRDY等待EXMC准备好。

3.6 配置自动刷新命令

与时钟使能类似,写入EXMC_SDCMD的参数如下:

//Auto Refresh Command(0b011)
//NARF = 7, 8 auto refresh cycle
//MRC = 0

这里有个问题,NARF设置为7,但是Datasheet上不是写了只有CMD=0b011时才意义,为什么这里还需要设置这个参数?

3.7 配置加载模式寄存器命令

这个命令需要对应到SDRAM的Datasheet中的Mode Register,即需要配置EXMC_SDCMD的MRC区域

主要是CASLatency需要设置为之前的CL配置值,之前CL配置为3,这里也需要设置为3.

还有第9位WB设置为1,意思如下图:

所以MRC = 0x230

3.8 设置自动刷新间隔寄存器 (EXMC_SDARI)

计算刷新每行需要的时间

下图中Row告知了SDRAM有8192行。

SDRAM的Datasheet中有说明,如下图

工规和商规是64ms,而车规是16ms。

这里用的是工规,所以取值64ms。

每行需要的时间 = 64 * 1000 / 8192 = 7.81us

SDRAM的时钟是100MHz,ARINTV = 7.81 * 100 - 20 = 761

3.9 确认初始化完成

可以通过读写一次SDRAM以确认SDRAM已经初始化OK。

4 SDRAM的访问

最简单直接的办法是使用指针,指针的地址指向SDRAM所在的地址即可。

if(SDRAMSetting.SDCKE == 0)
    pRegAddr = (uint32_t *)EXMC_SDRAM_ADDR0;
else
    pRegAddr = (uint32_t *)EXMC_SDRAM_ADDR1;
timeout = 10;
do
{
    delayms(100);
    *pRegAddr = 0xAA55A55A;
    if(*pRegAddr == 0xAA55A55A)
        break;
}while(--timeout > 0);
if(timeout == 0)
{
        EXMCSD_INFO(Printf("SDRAM Initial Fail\n"));
}
EXMCSD_INFO(Printf("SDRAM Initial Done:0x%x\n", pRegAddr));

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值