嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

内存接口

和gpio接口以及uart类型的接口不同,内存类接口是一类比较特殊的接口类型;

 

S3c2440是一个片上系统,除了CPU里面还有各种控制器:

gpio控制器:控制相应的寄存器, 让引脚输出高低电平,类似于门电路

串口控制器(接有TXD,RXD引脚); 让若干引脚输出波形,相对复杂,属于协议类接口,类似的还有iic,iis,spi等

内存控制器:控制其他寄存器,上面的接口都不会把地址输出到外部,而内存类接口会把地址输出到外部,比如:norflash, sdram, 网卡等,

等等,,,,,

对于CPU来说,他是不管什么类型的接口的,它只写相应的寄存器,由寄存器去控制相应的引脚。Cpu只管发出地址,内存控制器根据地址选择不同的模块,然后从模块中得到数据或者写入数据。

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

内存控制器也是通过地址来选择不同的外设,如图,sdram, dm9000, norflash都接在jz2440的数据总线和地址总线上,cpu把数据和地址发送出去,然后内存控制器根据片选信号选择相应的设备接受地址和数据信号,互不干扰。

Gpio门电路接口,协议类接口,内存类接口都属于cpu统一编址, 对于NandFlash,在原理图上并没有地址线连接到cpu,所以他并不参入cpu的统一编址,但是他的数据线接到了数据总线上,为了防止干扰,它也有一个片选信号(CE),当CPU去访问nand flash时,nand flash控制器才会去片选nand flash,让其接受数据总线上的数据

比如当选择nor flash启动的时候,cpu发出的指令的地址范围处于0x00000000~0x0800 0000之间,内存控制器就会使得nGCS0处于低电平(片选引脚被选中)ànorflash被选中

当CPU发出的指令的地址范围处于0x2000 0000~0x2800 0000,内存控制器就会使nGCS4处于低电平,dm9000网卡被选中,

当cpu发出的指令的地址范围处于0x3000 0000~0x4000 0000 ,内存控制器就会使得nGCS7处于低电平,sdRAM 被选中

也就是说,内存控制器会根据不同的地址范围,选择不同的片选引脚,只有被片选的芯片才能正常工作,不被选中你的相片就和不存在一样,不工作。

 

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

对于norflash的空间,0x0000 0000 ~ 0x0800 0000 也就是(2^27位)128M,需要A0 ---A26, 总共27根地址线,但是cpu发出了32根地址线,内存控制器根据地址范围,片选相应的bank,将地址转化为27位。

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

不同位宽设备的连接

2440芯片手册上,可以看到内存接口与不同bit rom连接的示意图:

  • 8bit rom连接时,2440的A0与外部芯片的A0连接

 嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

  • 当与俩个8bit rom拼接成的一个16bit的rom连接时,2440的A1与外部芯片的A0连接,嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

 

  • 当与四个8bit rom组成的一个32bit的rom连接时, 2440的A2与外部芯片的A0连接

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

  • 当与一个16bit的rom连接时,2440的A1 与外部的A0连接

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

从上可以看出随着外接芯片的外宽发生变化时,地址线的接法也会有变化,

假设现在执行一个指令,从地址3的地方去读一个字节

         MOV R0, #3

         LDRB R1, [R0]

如图,从上面几种接法,可以看到内部结构也是有差别:

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

8bit组成一个字节,字节是计算机的最小的存储单位,所以我们读取的数据都是8bit的倍数

对于地址3 à A0=1; A1=1;

8bit的rom一次读写的最小单位是8位,刚好读取地址3的数据

16位的rom一次读写的最小单位是16位,à 对于rom的A0 = 0; A1=1;于是找到了rom上地址1的16位数据,包含我们所需要的数据,最后内存控制器会根据A0来帮我们挑选所需要的8bit数据

32位的rom一次读写的最小单位是32位,à 对于rom的A0=0, A1=0,于是找到了rom上地址为0的32位数据,这包含我们所需的数据,最后内存控制器会帮我们挑选所需要的8位数据;

ROM/bit

CPU发出地址

ROM收到地址

ROM返回数据

内存控制器挑选出数据给CPU

8bit(ROM)

000011

000011

编号3的存储单元中的8位数据

编号3的存储单元中的8bit数据

16bit(ROM)

000011

000001

编号1的存储单元中的16位数据

根据”A0=1”,挑出高8bit数据

32bit(ROM)

000011

000000

编号0的存储单元中的32位数据

根据“A0A1=11”,挑出高8bit数据

         于是接到芯片上的引脚用来确定读取芯片上那一单元的数据, 把这个单元的数据返回给内存控制器; 内存控制器会根据没有连接芯片的引脚,来确定返回那一单元的数据给CPU;

上面是读取一个字节的例子,读取四个字节的例子也是类似的:

         假设,去地址4读取四个字节

         MOV R0, #4

         LDR R1, [R0]

         对于8位的rom, CPU发出地址 0b100,内存控制器会将0b100, 0b101, 0b110, 0b111发给rom读取这些地址上的数据,然后rom会将数据返回给内存控制器,内存控制器会将收到的4个8位数据组装成一个32位数据返回给CPU;

         对于16位和32位的rom分析类似,不再细说。

时序图分析

以norflash为例, 2440和nor flash之间有地址线, 数据线, 还有读写, 片选信号等等

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

如图是2440 norflash控制器的读时序图, 根据外接芯片的性能进行设置参数, 对于芯片性能好,响应时间快,就可以将参数时间设置小一点,释放更好的性能。

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

下面是NorFlash芯片的读时序:

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

以及每个参数的参考范围:

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

         可以看出若想从norflash中读取数据,则:

         图二中:Taa:valid data output after address 意思是在发出地址信号后过了多长时间,data才有效,最大70ns意思就是极限等待就是70ns,对于有的好芯片可能只需要50ns, 也就是说这个时间是需要大于等于70ns的。于是:

发出片选信号(CE#)后,需要等待Tce(要求大于等于70ns),片选信号才有效,

         发出地址数据(Address)后, 需要等待Taa(要求大于70ns)时间, 地址数据才有效,

         发出读信号(OE#)后, 需要等待Toe(要求大于等于30ns)时间,读信号才有效

         参数太多比较复杂,可以将地址数据, 片选信号, 读信号, 同时发出, 然后让他们都等待70ns,(等待信号有效), 对应的就是s3c2440的norflash控制器的的地址信号(A[24:0]), 片选信号nGCS, 读信号nOE同时发出, 保持Tacc >= 70ns。

         2440的norflash是接在BANKCON0上的, 于是只需要设置BANKCON0即可

         Tacc的默认值是14clock,系统刚开始上电采用12MHZ的晶振, HCLK=12MHZ,tacc=1000/12 *14大约是1166ns,这个值很大,满足要求; 启动后的时钟HCLK设置为100MHZ, THclk=10ns, 也就是tacc设置的值需要大于100;

         嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

         嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

具体相关设置的代码如下:

         Init.c设置tacc的参数值

         嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

         Init.h设置函数的声明

         嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

         Main.c通过串口输入参数,改变tacc的值

         嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

         当输入0~4时, tacc小于70ns,无法读取nor flash上的数据,led不闪

         当输入5~7时, tacc大于70ns,可以读取norflash上的数据,led可闪,且越小,越快

SDRAM设置:

JZ2440上接有64M的SDRAM,但是如果要使用SDRAM,还是需要对其进行一定的设置;cpu将数据或地址发给内存控制器, 内存控制器再去访问外部SDRAM,其实就是设置内存控制器。

SDRAM结构如下:

SDRAM的内部是一个存储阵列,其阵列就如同表格一样, 将数据填入其中,一个单元格被成为存储的单元, 每个存储单元表示16位的数据, 一个表格就是逻辑bank或者L-Bank,SDRAM有四个L-Bank

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

访问数据:

  1. 发出一个片选信号,选中整个芯片,

  2. 发出bank地址,选中是哪一个bank(块,即表格),

  3. 发出行地址 row,

  4. 发出列地址column,à选中格子

可见若需要选中一个存储单元,需要发出很多信号,但是cpu只是简单地执行读写内存的命令, 而其他复杂的操作都是交给内存控制器来处理的。例如

LDR R0, 0X30000000

LDR R1, [R0]

         Cpu会先将0x3000 0000 发给内存控制器,内存控制器根据这个地址判断是属于哪一个范围, 发出相应的片选信号; 内存控制器根据类型(SDRAM 还是其他的flash)分成三个部分, bank , row, column但是2440是不知道外接sdram有多少row,多少column的需要我们对内存控制进行设置:

         根据原理图可知, ADDR24和ADDR25用来选中bank;行列公用地址线ADDR2-ADDR14;

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

         于是需要从用的芯片资料里找到用的列和行数:
         嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

4*4M*(8*2)bit= 32M byte 俩片加一起就是64M的字节;

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

行数13列数9

2440内存控制器设置:

         总共有13个寄存器,BANK0~BANK5只需要设置BWSCON和BANKCONx(x为0~5)俩个寄存器

         BANK6,BANK7可外接SDRAM,除了上面俩个寄存器需要进行设置,还需要设置几个寄存器,下面一一说明:

  • BWSCON(BUS WIDTH & WAITCONTROL REGISTER)—位宽和等待控制寄存器

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

         ST7[31]-DW7[29:28]         由于只接了片选6,所以不用设置,为零

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

         WS6[26]   等待信号。假设内存芯片的速度较慢,在内存控制器发出读写命令后还是不能准备好数据,可以发出一个等待信号,宽限一点时间,原理图中没有用到 。通常设置为 0

         DW6[25:24]     由于是俩个芯片组成的32位芯片,于是设置位 10-32bit

         于是BWSCON 寄存器设置为 0x2200 0000;

  • BANKCONx(BANK CONTROL REGISTER)—BANK控制寄存器

在8个bank中,只有bank6和bank7可以外接SRAM或者SDRAM

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

         MT[16:15] 外接是芯片类型, SDRAM :0B11

         Trcd [3:2] 内存控制器先发出行地址,再发出列地址, 之间间隔多少时间,芯片手册是上是20ns,设置时钟,HCLK是100MHZ,clock为10ns, 所以设置Trcd为00—2clocks

         嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

         SCAN [1:0] 列数 9位 à 0b01

         BANKCON6 – 0X18001

  • REFERESH刷新控制寄存器,

由于sdram不像SRAM那么可靠,需要不断刷新,保证数据的不丢失

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

REFEN [23]: 0-禁止SDRAM刷新, 1-开启SDRAM刷新 开启à 1

TREFD[22]: SDRAM的刷新功能, 设置默认刷新, 1- 一般是在系统休眠的时候使用,0

Trp[21:20]:行信号地址的充电时间,根据芯片手册,>= 20ns设置为0即可

Tsrc[19:18]:根据芯片手册,>=50ns 设置为0b01

Refresh Conuter[10:0]:即是R_CNT

SDRAM刷新周期 = (2^11 – R_CNT + 1 )/HCLK

R_CNT = 2^11 - SDRAM刷新周期*HCLK + 1; HCLK=100MHZ; 现在就是需要知道sdram的刷新周期

根据芯片手册可以得知SDRAM刷新周期,

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

这个意思应该是8192个刷新周期需要64ms,所以SDRAM刷新周期 = 64ms/8192 = 7.8125ms

可以算出 R_CNT 为0x4f5

故REFRESH = 0X8404F5;

  • BANKSIZE

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

BURST_EN[7]:突发访问,启动,就是可以一次访问多个字节1

SCKE_EN[5]:0-不使用SCKE信号令SDRAM进入省电模式; 1-使用SCKE信号令SDRAM进入省电模式1

SCLK_EN[4]:0-时刻发出SCLK信号, 1-仅在访问SDRAM的时候发出SCLK信号(推荐)1

BK76MAP[2:0]:设置bank6/7的大小,bank6外接64M,bank7没有使用,故为0b001,

                    bank0~5对于的地址空间大小都是固定的128M,但是bank6/7是可变的以保持这俩个空间的地址连续àbank7的起始地址会随着它们大小变化,

BANKSIZE = 0XB1

  • MRSRBx SDRAM模式设置寄存器

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

WBL[9] : 0

TM[8:7]: 00

CL[6:4]:内存控制读/写SDRAM的时候,发出bank地址,行地址,以及列地址,需要等一会儿,SDRAM才会有数据出来或者接收,

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

保守是2clock,

BT[3]: 0

BL[2:0]: 000

MRSRB6的值为0x20

代码:

  • Init.c

内存控制器寄存器一一设置,bank7没用,但是为了以后方便使用,可以一起设置,再写一个测试函数,先向里面连续写1000个数,然后读出对比;SDRAM的起始地址是0x3000 0000,由于是地址,所以需要强制类型转换,于是需要从这个地址之后开始读写,

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例

  • Main.c

依次调用即可,若对比的数都是一样,则灯亮闪,否则灭

嵌入式学习笔记之存储_1_存储控制器&SDRAM举例