当前位置: 首页 > news >正文

JZ2440开发板——S3C2440的存储控制器

以下内容源于韦东山课程的学习与整理,如有侵权请告知删除。

课程中说的“内存控制器”,准确来说是“存储控制器”,其配套书籍写的也是“存储控制器”。

另外“Nor Flash控制器”,说的也是“存储控制器”,或者“存储控制器”中的某个BANK的控制逻辑。

一、内存接口

1.1 GPIO/门电路接口、协议类接口

在讲述内存接口之前,首先来分析一下操作GPIO控制器与操作UART控制器,这两者的区别。

S3C2440是一款SoC,配置有GPIO控制器(接有GPIO管脚)、串口控制器(接有TXD、RXD引脚),如下图所示:

通过配置GPIO控制器相应的寄存器(比如GPFCON、GPFDAT),可以让引脚输出高低电平;

通过配置UART控制器相应的寄存器(比如UCON0、UTXH0),可以让引脚输出波形。

前者相对简单,类似门电路,后者相对复杂,属于协议类接口(类似的协议类接口还有iic、iis、spi等)。

1.2 内存类接口 

所谓内存类接口,你可以简单地理解为:拥有地址总线、数据总线的接口,类似于操作内存。

前面的GPIO/门电路接口、协议类接口,不会把地址输出到外部;而内存类接口会把地址输出到外部,比如SDRAM(由两个16bit组成32bit的)、DM9000网卡(16bit的)、Nor Flash(16bit的),都接在JZ2440的数据总线和地址总线上。

那么CPU如何访问各个不同模块的寄存器?CPU把数据和地址发送出去,存储控制器再根据这个地址来发出片选信号,选择相应的模块来接收地址和数据信号,互不干扰。

片选信号与地址的关系是怎样的,即存储控制器如何根据一个地址来选定某个片选信号?这个是由S3C2440的芯片特性决定的,下图是存储控制器的地址空间分布图:

由此可知:当选择Nor Flash启动时,CPU发出的指令的地址范围处于0x0000000-0x08000000,存储控制器就会使nGCS0处于低电平(片选引脚被选中),Nor Flash被选中。当CPU发出的指令的地址范围处于0x20000000 -0x28000000,存储控制器就会使nGCS4处于低电平(片选引脚被选中),网卡被选中。当CPU发出的指令的地址范围处于0x30000000-0x38000000,存储控制器就会使nGCS6处于低电平(片选引脚被选中),SDRAM被选中。

存储控制器根据不同的地址范围,选择不同的片选引脚,只有被片选引脚选中的芯片才能正常工作,不被选中的芯片不工作。

上面提到的GPIO/门电路接口、协议类接口、内存类接口都属于CPU的统一编址,如下图所示:

而对于Nand Flash,在原理图上它的地址线并没有连接到CPU(好像没有地址线),因此它不参与CPU的统一编址;但它的数据线 LDATA[7:0] 也接到了数据总线上,为了防止干扰,它也有一个片选信号(CE)。当CPU要访问Nand Flash时,Nand Flash控制器才会发出CE信号来片选Nand Flash,让其接收数据总线上的数据。如下图所示:

二、不同位宽设备的连线

2.1 128MB空间对应27根地址线 

 由上面的存储控制器的地址空间分布图可知,每一个片选信号可以选择的空间为128MB。

128MB = 2^7 * 2^20 = 2^27,也就是需要A0,A1,…,A26 共27根地址线。我们在S3C2440数据手册上只能搜索到addr26,不能搜索到addr27;另外在原理图上也只有LADDR[26:0],也就是说从内存控制器中只引出27根地址线:

比如有如下指令:

ldr r0,=addr
str r1,[r0]
ldr r1,[r0]

则CPU会发出 32 位的地址 addr,然后存储控制器根据这个addr的地址范围,片选相应的BANK,并将32位的地址转化为27位。如下所示:

值得一提的是,这27位的地址信号线,不一定都接到设备上面。 

2.2 不同位宽设备的连线方式

参考2440芯片手册,可以看到内存接口与8-bit ROM连接时,2440的A0与外部芯片的A0相连:

当内存接口与两个 8-bit ROM 拼成的一个16-bit ROM连接时,2440的A1与外部芯片的A0相连:

当内存接口与四个 8-bit ROM 拼成的一个 32-bit ROM连接时,2440的A2与外部芯片的A0相连:

当与一个16-bit ROM连接时,2440的A1与外部芯片的A0相连:

由此可以看出外接芯片的位宽(每个外接芯片的数据位的位数+多少个芯片)有变化时,地址线的接法也会有变化。那这个变化有什么规律呢?

(1)例1:从内存地址3处读出一个字节的数据

假如CPU要执行下面的指令: 

MOV R0,#3
LDRB R1,[R0]

下图是 8-bit ROM、16-bit ROM、32-bit ROM的连接方式。 

 

首先,8个bit组成一个字节,而字节是计算机的最小的存储单位,因此我们读取数据肯定都是8bit的倍数。

  • 对于 8-bit ROM,8bit是一次读写的最小单位,即地址0是第一个 8bit,地址1是第二个8bit;CPU发出的命令是读取地址3上的数据,A3:A0=0b0011;根据接线方式,8 bit ROM的 A0 和 A1 收到的也都是1,于是找到了ROM上地址3的8bit数据,它就是我们需要的数据。
  • 对于16-bit ROM,16bit是一次读写的最小单位,即地址0是第一个16bit,里面有两个8bit数据;CPU发出的命令是读取地址为3上的数据,A3:A0=0b0011;根据接线方式,16bit ROM的A0和A1分别收到的是1和0,于是找到了ROM上地址为1的16bit数据,它包含了我们需要的数据,最后存储控制器再帮我们挑选出所需的8bit数据。
  • 对于 32-bit ROM,32bit是一次读写的最小单位,即地址0是第一个32bit,里面有四个8bit数据;CPU发出的命令是读取地址为3上的数据,A3:A0=0b0011;根据接线方式,32bitROM的A0和A1收到的都是0,于是找到了ROM上地址为0的32bit数据,它包含了我们需要的数据,最后存储控制器再帮我们挑选出所需的8bit数据。

过程如下图所示: 

或者这样理解,对于 32-bit ROM,假设要取出内存地址0,1,2,3处的数据。则对于A3:A0,CPU分别发出0b0000,0b0001,0b0010,0b0011这四个地址,但是由于32-bit ROM的连接方式(CPU发出的A1:A0没有接到ROM中),低位标红的两 bit 数字其实是没有用的(32-bit ROM说,我管你低位的两 bit 数字是多少,反正没有接到我身上,我只知道四次收到的地址都是00),也就是说,这四个地址其实访问的都是ROM中同一个地址的内容,然后由存储控制器帮我们挑选出所需数据。

虽然CPU发出的A1:A0没有连接到 32-bit ROM,但是还是有作用的,比如存储控制器根据A1:A0=11挑选出最低8bit的数据。

(2)例2:从内存地址4处读出4字节的数据

假如CPU要执行下面的指令,也就是从内存地址4处开始,读取4,5,6,7这四个字节。

MOV R0,#4
LLDR R1,[R0]

则执行过程如下(可见CPU只管发出一个地址000100,累死累活的是存储控制器):

32bitROM:当CPU发出地址(000100),存储控制器会把0001处的地址发送给ROM,ROM会把得到的地址0001上的数据返回给存储控制器,存储控制器会把得到的1个32bit数据返回给CPU。

16bitROM:当CPU发出地址(000100),存储控制器会把00010,00011处的地址转发给ROM,ROM会把得到的地址00010,00011上的数据返回给存储控制器,存储控制器会把得到的2个16bit的数据组装成一个32位的数据返回给CPU。

8bitROM:当CPU发出地址(000100),存储控制器会把000100,000101,000110,000111处的地址转发给ROM,ROM会把得到的地址000100,000101,000110,000111上的数据返回给存储控制器,存储控制器会把得到的4个8bit的数据组装成一个32位的数据返回给CPU。

ROMCPU发出地址内存控制器发给ROM的地址ROM返回数据内存控制器组装数据,并返回给CPU
32bit0001000001       得到地址1处的32bit数据直接给CPU
16bit000100

0010

得到地址2处的16bit数据

组成32bit数据给CPU
0011得到地址3处的16bit数据
8bit000100000100得到地址4处的8bit数据组成32bit数据给CPU
000101得到地址5处的8bit数据
000110得到地址6处的8bit数据
000111得到地址7处的8bit数据

2.3 如何确定芯片的访问地址?

怎样确定芯片的访问地址?

先根据(芯片手册)片选信号确定基地址,然后根据(原理图)芯片所接地址线确定范围。

(1)实例1:Nor Flash

首先,由上面的存储控制器的地址空间分布图可知,Nor Flash使用的是片选0(nGCS0),所以它的基地址为0。

然后,由上面的底板原理图可知,Nor Flash用到了CPU发出的A20、A19…A1、A0共21条地址线信号(虽然A0没有接到Nor Flash中,但A0是给存储控制器使用的,用来选择NorFlash的16bit输出中的低8bit还是高8bit),2^21=2MB,2MB对应着 0x00000000~0x1FFFFF。

最后加上基地址,则Nor Flash的地址范围为:0x00000000 ~ 0x001FFFFF。

(2)实例2:网卡

首先,网卡使用的是片选4(nGCS4),所以它的基地址为0x20000000。

然后,网卡只用到A2、A0共2根地址线(虽然CPU发出的A0地址线没有接到网卡,但存储控制器需要根据A0来判断是读取低8bit还是高8bit数据),则0b0x0~0b1x1,这里x表示不关心A1的值,我们假设x是0,则0b000~0b101,即0x0~0x5,。

最后加上基地址,则网卡的地址范围为:0x20000000~0x20000005。

(3)实例3:SDRAM

首先,SDRAM使用的是片选6(nGCS6),所以它的基地址为0x30000000。

但是根据原理图,它总共只用了17条地址线(LADDR0\1\2~14\24\25),按理2^17=128KB,似乎不能访问完64MB的SDRAM。但实际上SDRAM的寻址需要行地址与列地址,这些地址线需要用到两次,才能真正组成一个地址。这情况比较特殊,后面再讲。

总结如下: 

2.4 总结 

CPU是大爷,只是简单地发出一个操作内存的命令而已;而存储控制器劳苦功高,需要根据外接的芯片类型进行相应的设置,比如对于SDRAM,要进行行地址与列地址的拆分。

三、Nor Flash 的时序分析与设置

从上面我们知道,不同类型的内存类设备是如何与S3C2440芯片进行连接的。但是还没有弄清楚这些连接线中的信号是如何协调工作的,也就是时序关系。本节来讲解这个内容。

3.1 S3C2440 和 Nor Flash 之间的连接

以Nor Flash为例,2440和Nor Flash之间有地址线,数据线,还有各种数据线连接,如下所示:

3.2 S3C2440的Nor Flash控制器的读时序图

下图是【S3C2440的Nor Flash控制器】的【读时序图】(位于2440数据手册P205)。

3.2.1 如何理解时序图中相关参数的含义

首先从时序图上,知道它的起始位置和终止位置,然后看起始位置是相对于哪个量来说的。

(1)比如参数Tacs,起始位置位于A[24:0]开始发出的时刻,终止位置是nGCS由高变低的时刻,那么Tace大概的含义应该就是(发出A[24:0]地址信号之后,至少要等待Tacs这么长的时间,才能发出nGCS信号)。居然可以设置为0!

(2)比如参数Tacc,起始位置位于nOE信号由高变低(或者发出读信号)的时刻,终止位置位于D[31:0]框(我是这样理解的:一个框表示可能高电平,可能低电平)中发生变化的时刻(发生变化表示什么含义呢?),那么Tacc大概的含义应该是(发出读信号nOE之后,至少要等待Tacc时间(毕竟你发出读请求之后,我也需要时间去准备数据),才能从数据线D[31:0]上面读取数据)。

另外2440的数据手册也会提供这些参数的解释(实际上没有直接提供,而是在BANKCONn寄存器的位含义中解释了这些参数的含义,如下图所示),与之外接的NorFlash芯片的数据手册也会有对应的时序图,时序图上也有这些参数,但表示方法可能不一样。

3.2.2 根据外接芯片的性能设置相关参数

时序图里面的很多参数,都需要根据外接芯片的性能进行设置。有的芯片性能好(差)、响应时间快(慢),就可以把参数时间设置小(大)一点,释放更好的性能。

比如有些外接芯片的响应时间慢一些,2440发出读信号之后,它磨磨蹭蹭地准备数据,这种情况你就可以把Tacc设置得大一些,以便外接芯片准备好数据。

3.3 JZ2440开发板上的NorFlash芯片的读时序图

下图是【JZ2440开发板上的NorFlash芯片】的【读时序图】(这款芯片型号是MX29LV160DBTI,其数据手册位于开发板配套资料的“\003_芯片手册”目录下,读时序图位于该数据手册的P34):

每个参数的含义、参考范围,可以在数据手册中“AC CHARACTERISTICS”(P32)目录中得到:

结合这两张图,可以得到如下信息:

(1)发出地址数据(Addresses)后,需要等待Taa时间(无论哪一种芯片,当Taa大于等于70ns时就能够保证地址数据有效,当Taa小于70ns时不能够保证地址数据稳定有效,这就是Max=70的含义;当然有些芯片可能性能比较好,此时Taa可以设置小于70ns的数值),地址数据才有效。

(2)发出片选信号(CE#)后,需要等待Tce时间(大于等于70ns就能保证片选信号有效),片选信号才有效。

(3)发出读信号(OE#)后,需要等待Toe时间(大于等于30ns就能保证读信号有效),读信号才有效。

(4)Toh,表示(在CE#第一个上升沿之后)在数据线上进行数据保持的时间,这里设置为0,表示不需要进行数据保持。

(5)Tdf,表示在Tdf这段时间内容,CPU不能访问其他芯片(因为NorFlash数据线上的数据还没有稳定下来,数据线还不是高阻状态;如果你此时执意要访问其他芯片,那NorFlash芯片可能会影响你)。这里设置为30ns。实际上这个参数一般不需要理会,因为我们访问完一次NorFlash之后立刻进行第二次访问时,需要重新发出OE#、CE#等信号,等待这些信号有效的时间(70ns、30ns)早就满足Tdf的条件了。

(6)Trc,表示读一次NorFlash所花费的时间。它最小是70ns,也就是说,70ns是这款芯片最佳的性能了,你如果将这个Trc设置得更小,那么这款芯片就反应不过来了。

3.4 设置Nor Flash控制器的时序

分析完时序图,接下来就是设置S3C2440的Nor Flash控制器的时序来满足Nor Flash芯片的时序。

为了简单起见,在Nor Flash芯片的时序图上,我们让Addresses、CE#、OE#同时发出,那么等待70ns(以等待信号有效)就能满足时序要求。对应S3C2440的Nor Flash控制器的读时序图,需要让地址信号A[24:0]、片选信号nGCS、读信号nOE同时发出(这样操作不违背时序关系吗?或者说时序图中Tacs、Tcos这两个参数可以设置为0从而可以同时发出?的确可以设置为0!由下面的寄存器BANKCON0[14:13][12:11]的描述可知),保持Tacc大于等于70ns。

从2440的数据手册可知Nor Flash接在BANK0上,我们关注一下与BANK0有关的寄存器。

3.4.1 设置BANKCONn寄存器(用来控制BANKn外接设备的访问时序)

BANKCONn寄存器用来控制BANKn外接设备的访问时序,该寄存器的位含义如下所示:

由于Tacs、Tcos上电初始值为0,满足我们让地址信号A[24:0]、片选信号nGCS、读信号nOE同时发出的要求,不需要进行设置(当然你给BANKCON0[14:13][12:11]赋值为0也行)。

现在我们需要设置Tacc的值(通过BANKCON0[10:8]来设置clocks数目,然后乘以时钟周期)。

由上图可知,Tacc上电初始值是111,对应着14个clocks。系统刚上电时采用12MHz的晶振,(存储控制器的时钟源是HCLK,刚上电时PLL还没有工作,故HCLK=FCLK=12MHz)HCLK=12MHz,此时的 Tacc 的计算方式为(计算得到的1166ns这个值很大,几乎可以满足所有Nor Flash的要求):

频率:f = 12*10^6Hz
时钟周期:T = 1/f = 1/(12*10^6) (s)(单位为秒)
14个时钟的时长 t = 14* T (s)= 14 * T * 10^9 (ns) = (1000/12*14) (ns) ≈ 1166(ns)

当2440完全启动后,将HCLK设置为100MHz,此时T=1/(100*10^6) (s)=10(ns)。由于Tacc需要≥70ns,则将 BANKCON0[10:8] 设置为 0b101 即可(对应着8个clocks,此时Tacc=80ns,满足要求)。

3.4.2 设置BWSCON寄存器(主要用来设置BANK的位宽)

该寄存器的每4bit控制一个BANK,最高4bit控制BANK7,接下来4bit控制BANK6,以此类推。 

由于Nor Flash接在BANK0,我们只关心BANK0的配置。 由上面可知,BWSCON[2:1]的值由硬件引脚OM[1:0]决定(而且这个值是只读的,我们不能通过程序修改它)。那OM[1:0]是怎样的?如下图所示,可知OM[1]=1,OM[0]等于多少?(但目前至少可知BANK0的位宽是32bit了!)

由图可知我们根本不需要设置BWSCON寄存器!

3.5 编程实践

3.5.1 代码编写

我们在前面uart实验的源码基础上,新建init.c和init.h两个文件。

init.c文件内容如下(只需要设置BANKCON0寄存器即可):

#include "s3c2440_soc.h"void bank0_tacc_set(int val)
{BANKCON0 = val << 8;//只需要设置Tacc即可,其他Txxx采用默认值
}

init.h文件内容如下(进行函数声明):

#ifndef _INIT_H
#define _INIT_Hvoid bank0_tacc_set(int val);#endif

main.c文件内容修改如下(通过串口获取输入的值,传入bank0_tacc_set 函数中来设置Tacc,然后再读取Nor Flash上的闪灯程序。这说明需要将生成的bin文件烧写到NorFlash中运行。不过这里不是修改了Nor Flash的数据,比如局部变量c?NorFlash能这样直接修改吗?后面需要学习一下NorFlash如何读写方面的内容):

#include "s3c2440_soc.h"
#include "uart.h"
#include "init.h"int main(void)
{unsigned char c;uart0_init();puts("Enter the Tacc val: \n\r");while(1){c = getchar();putchar(c);if (c >= '0' && c <= '7'){bank0_tacc_set(c - '0');led_test();}else{puts("Error, val should between 0~7\n\r");puts("Enter the Tacc val: \n\r");}}return 0;
}

3.5.2 实验现象

将上面编译得到的bin文件,利用Jlink烧写到NorFlash中(或者利用带有烧写NorFlash功能的uboot与“dnw+usb下载线”配合进行烧写),然后以NorFlash方式启动。

在串口上输入0~4之间的一个数字(意味着Tacc小于70ns),发现无法读取Nor Flash上数据,LED不能闪烁;(需要复位,因为led_test中有个while循环不会跳出)在串口上输入4~7之间的一个数字(意味着Tacc大于70ns),发现可以读取Nor Flash上数据,LED不断闪烁,而且值越小越快(但是区别不明显)。

四、SDRAM 的分析与设置

如果想对内存有更多了解,可以看这篇文档《终极内存技术指南》。

在JZ2440上接有64M的SDRAM,如果想要使用SDRAM,需要对存储控制器做一些设置。在1.2节讲到,CPU是大爷,它将数据或地址发给存储控制器,由存储控制器再去访问外部的SDRAM,因此设置存储控制器就是本节的核心。

4.1 SDRAM 存储结构逻辑图

如下所示,SDRAM的内部是一个存储阵列,阵列就如同表格一样,将数据“填”进去。和表格的检索原理一样,先指定一个行(Row),再指定一个列(Column),就可以准确地找到所需要的单元格。这就是SDRAM寻址的基本原理。这个单元格被称为存储单元(每个单元格表示的是16bit数据,因为2440接有2片SDRAM,每片SDRAM一次提供16bit数据),这个表格就是逻辑块(Logical Banks,下文简称L-Bank,注意别和存储控制器的Bank混淆了)。

SDRAM总共有4个L-Bank,如下所示:

4.2 对 SDRAM 的访问步骤 

对SDRAM的访问,其过程可以形像地比作访问上图中的某个格子。

比如执行下面的指令:

//读取地址30000000(该地址位于SDRAM中) 处的4字节内容给 R1
LDR R0,=0x30000000 
LDR R1,[R0]

(1)首先,CPU将0x30000000这个地址发给存储控制器,而存储控制器根据收到地址的范围,发出相应的片选信号nGCS6;

(3)然后,存储控制器发现它外接的芯片类型是SDRAM(根据外接的芯片类型是SDRAM),将地址拆分为3部分:

  1. 发出Logical Bank地址(表示选择这4块Logical Bank中的哪一块);
  2. 发出行地址;
  3. 发出列地址

(4)最后,存储控制器读取数据并交给CPU。 

4.3 如何拆分地址

现在问题是,该如何拆分一个地址:行地址有几条线?列地址有几条线?这可以通过存储控制器里面相关的寄存器来进行配置。

我们重新梳理一下,对SDRAM的访问,可以分为以下步骤:

1、CPU发出的片选信号nSCS6有效,表示选中SDRAM芯片。

2、SDRAM中有4个L-Bank,需要两根地址信号来选中其中之一。根据原理图,可知使用ADDR24、ADDR25作为L-Bank的选择信号。

3、对被选中的芯片进行统一的 行\列 寻址。

根据 SDRAM 芯片的 列地址线数目 设置CPU的相关寄存器后,CPU就会从32位的地址中自动分出L_Bank片选信号、行地址信号、列地址信号,然后先后发出行地址信号、列地址信号。L_Bank选择信号在发出行地址信号的同时发出,并维持到列地址信号结束。

根据原理图可知:

地址、列地址共用地线ADDR2—ADDRI4(BANK6位宽为32,ADDRO/I没有使用),使用nSRAS、nSCAS两个信号来区分它们。

比如本开发板中,使用两根地址线ADDR24、ADDR25作为L-Bank的选择信号:SDRAM芯片K4s5m632的行地址数为13,列地址数为9,所以当nSRAS信号有时,ADDR2—ADDR14上发出是行地址信号,它对应32位地址空间的b可23m]:当nSCAS信号有效时,ADDR2—ADDR10上发出的是列地址信号,它对应32位地址空间的bit[0:2];由于BANK6以32位的宽度外接DRAM,ADDRO、ADDR1恒为0,不参与译码。

4、找到了存储单元后,被选中的芯片就要进行统一的数据传输了。

开发板中使用两片16位的SDRAM芯片并联组成32位的位宽,与CPU的32根数据线(DATAO—DATA31)相连。BANK6的起始地址为0x30000000,所以SDRAM的访问地址为0x30000000~低0x33FFFFFF,共64MB。

4.4 寄存器的设置

由2440数据手册可知,存储控制器共有13个寄存器,如下所示:

对于 BANKn(n为0~5中的某个数字),只需要设置 BWSCON 和 BANKCONn两个寄存器;

对于 BANKn(n为6或7),其外接 SDRAM 时,除了要设置 BWSCON 和 BANKCONn 这两个寄存器外,还要设置 REFRESH、BANKSIZE、MRSRBn寄存器。

下面分类说明各个寄存器的设置(由于我们只关心BANK7、BANK6,下面只截图这两个BANK的内容)。

4.4.1 BWSCON寄存器(主要用于设置BANK的位宽)

BWSCON中每4位控制一个BANK,最高4位对应BANK7(没有使用),接下来4位对应BANK6。

(1)ST6[27]:启动/禁止SDRAM的数据掩码引脚,对于SDRAM,此位为0;对于SRAM此位为1。

(2)WS6[26]:是否使用存储器的WAIT信号,通常设为0。

(3)DW6[25:24]:使用两位来设置相应BANK的位宽,0b00对应8位、0b01对应16位、0b10对应32位(开发板使用的就是32bit)、0b11表示保留。

因此 BWSCON 寄存器的值可以设置为 0x22000000(BANK7虽然没有使用,但也设为32bit的位宽)。

 4.4.2 BANKCON6寄存器(设置外接设备的访问时序、SDRAM的列地址位数)

在8个BANK中,只有 BANK6 和 BANK7 可以外接SRAM或者SDRAM。

(1)BANKCON6[16:15](MT),用于设置这个BANK外接的是ROM/SRAM,还是SDRAM。当设为0b11时,表示外接的是SDRAM。这里将[16:15]设置为0b11。

(2)BANKCON6[3:2](Trcd),表示行地址和列地址间隔多长时间。看SDRAM芯片手册,Trcd是20ns。开发板的HCLK是100MHZ,则clocks为10ns,所以可以将[3:2]设置为0b00(书上设置为0b01,更保守一些),表示2clocks即20ns。

(3)BANKCON6[1:0](SCAN),表示 SDRAM 的列地址位数。0b00表示8位,0b01表示9位,0b10表示10位。本开发板使用SDRAMK4S561632,其列地址位数为9,所以这里将[1:0]设置0b01。如果使用其他型号的SDRAM,需要查看其数据手册,来决定 SCAN 的取值。

综上所述,本开发板中 BANKCON6 寄存器的值应该设为 0x018001。

4.4.3 REFRESH寄存器(用于设置SDRAM的刷新功能)

(1)REFRESH[23](REFEN),用于设置是否开启SDRAM的刷新功能。=0时禁止SDRAM的刷新功能,=1时开启SDRAM的刷新功能。这里设置为1

(2)REFRESH[22](TREFMD),用于设置SDRAM的刷新模式。=0时是CBR/AutoRefresh,=1时是SelfRefresh(这个模式一般在系统休眠时使用)。我们设置为默认值0

(3)REFRESH[21:20](Trp),根据芯片手册设为0b00即可

(4)REFRESH[19:18](Tsrc),根据芯片手册设为0b01即可书上设为0b11,更保守一些)。

(5)REFRESH[10:0](RefreshCounter),假设[10:0]表示的数值为R_CNT,则R_CNT的计算方式如下:

R_CNT = 2^11 +1 - SDRAM的时钟频率(MHZ)* SDRAM刷新周期(us)

SDRAM的时钟频率:SDRAM的时钟频率就是HCLK。在没有使用PLL时等于晶振频率12MHz;在时钟体系那个章节里我们设置HCLK为100MH,这里就以100MHz计算即可。

SDRAM刷新周期:一般在SDRAM的数据手册上有标明。比如本开发板使用的SDRAMK4S561632的数据手册上,有“64ms refresh period(8KCycle)”,这意味着64ms对应着8*1024个周期,那么每个周期 T=64ms/(8*1024)(ms)=7.8125(us)。

由此可以计算出 R_CNT=2^11 +1 - 100 * 7.8 = 0x4F5=0b100 1111 0101 。

综上所述,本开发板中 REFRESH 寄存器的值应该设为 0x008404f5。

4.4.4 BANKSIZE寄存器(用于设置突发传输、省电模式、)

(1)BANKSIZE[7](BURST_EN),用于设置是否支持突发传输。=0时表示ARM核禁上突发传输,=1是表示ARM核支持突发传输(推荐)。这里设置为1。

(2)BANKSIZE[5](SCKEEN),用于设置是否使用SCKE信号令SDRAM进入省电模式。=1时表示使用SCKE信号令SDRAM进入省电模式(推荐)。这里设置为1。

(3)BANKSIZE[4](SCLK-EN),=0表示时刻发出SCLK信号,=1表示仅在访问SDRAM期间发出SCLK信号(推荐)。这里设置为1。

(4)BANKSIZE[2:0](BK76MAP),用于设置 BANK6(同时也会设置BANK7,虽然BANK7没有使用到)外接设备的容量。由于本开发板 BANK6 外接有 64MB 的 SDRAM,所以[2:0]应该设置为0b001,表示BANK6、BANK7外接设备的容量都是64MB。

综上所示,本开发板中 BANKSIZE 寄存器的值应该设为0xB1。

4.4.5 MRSRB6寄存器(主要用于设置等待多久才收到数据)

对于这个寄存器,我们只能修改 MRSRB6[6:4](CL)。CL是 SDRAM 时序的一个时间参数,表示发出行、列地址后,需要等待多久才返回收到数据。CL可以取值为 2clocks(MRSRB6[6:4]=0b010时),或者 3clocks(MRSRB6[6:4]=0b011时)。

本开发板取最保守的值0b011,因此 MRSRB6 寄存器的值应该设为0x30。

4.5 编程实践

暂无。


http://www.mrgr.cn/news/30563.html

相关文章:

  • 安科瑞工业绝缘监测装置:保障煤矿井下6kV供电系统安全运行的关键应用——安科瑞 丁佳雯
  • VScode下脚本被禁止运行的原因及解决方案
  • 操作系统——进程调度
  • 华为私有接口类型hybrid
  • 【Python】轻松实现机器翻译:Transformers库使用教程
  • PHP反序列化靶场(php-SER-libs-main 第一部分)
  • C++ prime plus-3-编程练习
  • C++标准的一些特性记录:C++11的auto和decltype
  • 每天五分钟深度学习框架pytorch:pytorch中已经定义好的损失函数
  • 【洛谷】P1546 [USACO3.1] 最短网络 Agri-Net 的题解
  • 倍增练习(1)
  • pg入门3—详解tablespaces1
  • 恶意Bot流量识别分析实践
  • 计算机毕业设计 奖学金评定管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
  • Python 入门教程(4)数据类型 | 4.6、列表
  • vulnhub靶机:Breach 2.1详细过程
  • [Unity Demo]从零开始制作空洞骑士Hollow Knight第四集:制作更多的敌人
  • keep-alive的应用场景
  • C8T6--SPI读FLASH和双通信
  • 目前人工智能时代,程序员如何保持核心竞争力?
  • 项目小总结
  • Web开发:ABP框架2——入门级别的增删改查Demo
  • C++ Primer Plus(速记版)-类和数据抽象
  • LeetCode 876
  • Mysql中DML和DQL
  • 代码随想录八股训练营第四十天| C++