大部分内容来自韦东山老师视频及博客:https://blog.csdn.net/thisway_diy/article/details/79389530
一个可参考的很好很详细的博客文档:https://www.cnblogs.com/biaohc/p/6346878.html

内存接口和内存控制器

内存控制器的时钟信号由HCLK时钟信号提供,假设设置的HCLK的值为100M,1clock = 10ns,后续有些时序计算要用到。
S3C2440是个片上系统,有GPIO控制器(接有GPIO管脚),有串口控制器 (接有TXD RXD引脚)。

配置GPIO控制器相应的寄存器,即可让引脚输出高低电平;配置UART控制器相应的寄存器,即可让引脚输出波形。前者相对简单,类似门电路,后者相对复杂,属于协议类接口。类似的协议类接口还有iic、iis、spi等。
对于CPU是不管什么接口的,它只写相应的寄存器,由控制器根据寄存器的配置去控制具体的引脚。

那么CPU是如何访问各个不同的寄存器的呢?
GPIO(门电路),uart(协议类接口)都是通过寄存器控制,寄存器都是内存有地址,继而必须引入一个内存控制器。
作用:cpu发出地址给内存控制器,内存控制器根据地址选择不同模块,(进行操作)把数据发给模块或者从模块中取出数据,最终可以返回数据给CPU。

上面这两个是一类,GPIO/门电路接口、协议类接口,都不会把地址输出到外部。
但是还有一类:内存类接口,会把地址输出到外部,比如Nor Flash、网卡、SDRAM。
cpu给内存控制器,cpu-内存控制线传出的地址直接给内存类设备(芯片)(如nor flash,网卡,内存)
也就是芯片有地址线控制的,接到arm的addr[]线那种
而上面两种cpu给出的地址仅仅就是为了寻找控制寄存器的。

注意:nandflash不同哦!不属于内存接口
gpio,iic,uart以及片外的nor等都是cpu统一编址,但是nand不是,并不会用到上述那种芯片的addr[]地址线!
在原理图上它的地址线并没有连接到CPU,因此它不参与CPU的统一编址。但它的数据线也接到了数据总线上,为了防止干扰,它肯定也有一个片选信号(CE)。这个片选信号不是内存控制器直接给,而是nand控制器发出,只有当CPU访问Nand Flash时,(cpu发出的地址控制到了nand控制器其中的某个寄存器),nand控制器才会发出片选信号使能nand芯片的片选,让其接收数据总线上的数据。

SDRAM、DM9000网卡、Nor Flash都接在JZ2440的数据总线和地址总线上,CPU把数据和地址发送出去,然后内存控制器根据片选信号选择相应的设备接收地址和数据信号,互不干扰。

地址线可能会接很多设备,是通过片选选定的,片选是如何产生呢?!!!!
cpu把地址(片选也是地址决定的,包含的)发给内存控制器,内存控制器根据不同的地址决定发出哪个片选信号。(也就是让芯片的那个引脚作用)
这个地址信号和外接的芯片(其实是和arm芯片的片选引脚)怎么对应呢,哪个地址内容对应哪个片选引脚作用?

S3C2440将1GB的外部存储地址空间分成了8个BANKS
每个BANK的地址空间为128M,总共1GB(8 BANKs)
外部存取器地址总共就1GB地址空间,再之上的40000000-FFFFFFFF的3g空间是外设寄存器如GPH0CON等的地址空间,其实也并没有都用完。总共4G,这是由32位机器32个地址线决定的,)
可编程控制的总线位宽(8/16/32bit),不过BANK0只能选择两种位宽(16/32bit)。
总共8个BANK,BANK0-BANK5可以外接ROM,SRAM等,BANK6-BANK7除可以支持ROM, SRAM外还支持SDRAM等。
S3C2440芯片性质决定了,SDRAM类型的内存条只能焊在 Bank6~Bank7上,最大支持内存 256M,即0x30000000–0x3FFFFFFF !!!!!!!!

当选择Nor Flash启动时,发出的地址信号范围是0-0x08000000范围呢,就会让nGCS0引脚处于低电平,硬件中就是Nor Flash被选中。
这是由内存控制器根据cpu提供的地址发出片选信号的。

内存控制器根据不同的地址地址范围,发出不同的片选引脚,只有被片选引脚选中的芯片才能正常工作,不被选中的芯片就像不存在一样,不工作。

cpu给出32位的地址后,内存控制器根据地址发出片选信号和addr0-addr26(共27地址线)。(虽然是32位,但只有27个地址线,够用。
为什么呢?
比如,0x00000000 -0x08000000,为128M,即每一个片选信号可以选择的空间是128M=2^27,也就需要A0、A1……A26,共27根地址线。外加一个片选线就行了。

补充:
1) 关于nor 和nand,两种不同的启动过程,!!参考第008课的博客内容!!!!
2) 视频中没讲到的重点内容:
我们常说的寄存器的地址位于哪里呢?

2440总共能够寻址的4GB空间,除了0-40000000这个1GB的范围是本节所讲的外设内存地址空间,再就是CPU内部使用的这些特殊功能寄存器地址空间(地址范围为0x4800 0000–0x5FFF FFFF),其余的地址空间没有使用!!

S3C2440A的ARM核内还有31个通用寄存器和6个程序状态寄存器(r0那些),该部分没有被编入我们通常所说的地址空间、即32位地址之中;通过逻辑电路直接给出操作地址(不是很明白???)。 这些寄存器只有通过汇编语言才可以访问;访问时,直接使用他们的名字即可。

下图可能是摘抄自别的板子的外设的内存分配:

值得注意的是nor都是从0地址开始的。SDRAM的3FF FFFF 共 26根地址线,也就是 2^6=64 2^20=1M 那么就是 64M。
我们的板子,提到外部内存设备,貌似就是三个:sdram,DM9000网卡,nor flash。也就是说这三个公用地址总线和数据总线,通过片选分时复用。

CPU是怎样发出地址信号的呢?下面这两个读写指令!!!!!!!!!就会让cpu把32位的地址发给内存控制器。

CPU是大爷,只需要发出指令,把地址给了内存控制器,内存控制器就会跑断腿做一系列操作。

不同位宽设备的连接



注意,个人理解,nbit指的是芯片内部一个地址对应n位,也就是n/8字节。跟这个芯片的存储大小是无关的。换句话说,n位的含义:芯片一次可以对外提供n位数据。
对于不同位数设备,CPU发出的地址是相同的,不过是因为接线空出(0/1地址线)使得rom接收到的地址不同,但最终得到的第几个字节是一样的。

假设CUP执行:
MOV R0, #3 @去地址为3的内存上
LDRB R1, [R0] @ 从内存为3的地址上,读出一个字节

假如传递一个32位的数据时
MOV R0, #4
LDR R1, [R0] @LDR代表读4字节,去地址4读四个字节(4,5,6,7)

执行过程如下:
8bitROM: 当CPU发出地址(000100),内存控制器会把000100,000101,000110,000111处的地址转发给ROM,ROM会把得到的地址000100,000101,000110,000111,上的数据返回给内存控制器,内存控制器会把得到的4个8bit的数据组装成一个32位的数据返回给CPU。
16bitROM: 当CPU发出地址(000100),内存控制器会把00010,00011处的地址转发给ROM,ROM会把得到的地址00010,00011,上的数据返回给内存控制器,内存控制器会把得到的2个16bit的数据组装成一个32位的数据返回给CPU。
32bitROM: 当CPU发出地址(000100),内存控制器会把0001处的地址发送给ROM,ROM会把得到的地址0001上的数据返回给内存控制器,内存控制器会把得到的1个32bit数据返回给CPU。

(cpu只是发给内存控制器一个地址码???应该不是把????那内存控制器怎么知道cpu要的是多少字节的?????)
(内存控制器知道自己接的是多少位的设备??????它怎么知道发几次地址出去?????????)

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

  1. 根据片选信号确定基地址,
  2. 根据芯片所接地址线确定范围
    (比stm32简单呀,stm32还得考虑哪个片选线,片选线参与地址的计算,这里直接查出基地址就行了)
    实例:
    Nor Flash 使用的是片选0(nGCS0),基地址为0,用到A20,A19……A1,A0共21条地址线,所以地址范围为0x00000000 ~ 0x1FFFFF也就是2M的空间大小。

网卡(Net)使用的是片选4(nGCS4),基地址为0x20000000,地址线用了一个laddr2,但是这里还要用到laddr0判断读取的是高8位还是低8位(??????参考网卡dm9000章节) 。所以说共用到A2,A0共2根地址线,所以地址范围为0x20000000 ~ 0x20000005(ob101),(基址由所接片选线确定)。看数据线有16个知道是16位设备!!!!
(片选线不属于地址线中的一根,单独的)(ob表示二进制,)

SDRAM使用的是片选6(nGCS6),基地址为0x30000000。
SDRAM用了17个地址线(加上a0a1),这样计算地址范围难道是128k?(因为本来能访问的地址范围其实就是芯片的内存大小)
而我们用的SDRAM芯片是64M,显然不对。因为这里特殊,SDRAM发出的地址信号会分为列地址行地址,访问一次要发两次地址信号,地址线用两次(参考对应章节)。

内存类设备(地址+数据总线)时序图

信号之间是怎样一起工作的,以Nor Flash 为例。
2440和Nor Flash 之间有地址线,数据线,还有各种数据线连接。

下图是2440内存控制器的读写时序(对应手册图5-12 ngcs timing diagram):

下图是Nor Flash芯片的读时序。

芯片建议的时间,每个参数的参考范围可以通过芯片的AC CHARACTERISTICS得到。

我们需要做的就是设置S3C2440的Nor Flash控制器(应该也就是内存控制器)时序去满足Nor Flash芯片的时序。

易错点:上图中Taa max 70是什么意思呢?这里标注的是芯片的特性!!!!
指的是这段时间最大可能需要70那么久,所以控制器控制的这段时间要大于70。
而不是说,控制器给的这段时间最大是70。

Taa表示的是addr信号发出多久后data数据才有效,芯片需要taa这段时间准备,而准备时间可能最大需要到70ns,所以控制器得比这个时间长!
Tdf 表示在Tdf内数据不稳定,也就是不允许访问其他芯片,30ns。一般不需要理会这个,因为再次访问的时候,还需要时序前面的Taa。等到稳定的时候,数据已经稳定了。

编程:
为了简单我们把地址数据(Addresses),片选信号(CE#),读信号(OE#),同时发出,然后让它们都等待70ns(等待信号有效)。对应S3C2440的Nor Flash控制器的读时序图,需要让地址信号A[24:0]、片选信号nGCS、读信号nOE同时发出,保持Tacc大于等于70ns。

Nor Flash是接在BANKCON0上的,因此只需要设置BANKCON0即可。

( 当选择外接SDRAM时,地址才会被拆分为BANK地址,行地址,列地址。如果不是的话地址会一次性发出去。)

可以看到Tacc上电初始值是111,对应14个clocks。系统上电采用12MHz的晶振,HCLK=12MHz,Tacc=(1000/12*14)≈1166ns,这个值很大,几乎可以满足所有Nor Flash的要求,这的意思也就是上电后设置最大值可以读取所有的nor flash,不至于程序不能运行。我们可以调小,大于70ns即可,否则性能太弱了。
实际中,我们启动后,将HCLK设置为100MHz,T=1000/100=10ns,Tacc需要大于等于70ns,因此设置Tacc等于101,8个clocks即可。

参考其他资料:
BANK0~BANK5 只需要设置BWSCON和BANKCONx这两个寄存器
BANK6~BANK7 外接SDRAM时,除BWSCON和BANKCONx还要设置REFRESH,BANKSIZE, MRSRB6, MRSRB7等4个寄存器。

BWSCON:总线宽度和等待控制寄存器

(韦老师这里没有设置,因为使用默认值即可)
STx:对于SDRAM,此位为0。对于SRAM,此位为1。
WS1: 内存芯片驱动的非常慢,当CPU发出信息后,内存芯片在规定时间内未准备好。此时可以先CPU发出一个等待信号。wait信号是内存芯片向2440CPU发出的。

补充:SRAM使用UB/LB什么意思?(因为我们课程没有外接sram,没有讲这个)
搜索资料,大概如下:
在16位宽的数据线上分开访问高/低字节时要用到。当用SRAM时配置了外部存储器的宽度为16位时,如果程序需要以8位宽度访问外部存储器时,如果要单独写一个字节,就需要处理器有高、低字节选通的控制线,这两条信号线会由硬件自动产生。这样不但可以访问字,还可以访问字节。
(下文sdram配置寄存器的部分详细介绍了这个)

后续插入一个内容:

sdram需要初始化才能读写,实际是配置些寄存器满足时序。
nor flash呢?
要读些nor flash也是要配置寄存器满足时序的,我们前面的代码中都没有配置,因为nor只需要配置bank0的寄存器,只有两个需要设置,默认值却都可以工作,所以没有配置。
而是直接可读:    volatile unsigned short *p = (volatile unsigned short *)(base + offset);         return *p;
(寄存器配置见内存控制器章节,nor和sdram同属于内存控制器管理,用一套寄存器。只不过sdram寄存器设置更复杂,需要专门初始化用来配置时序)
但是我们的代码放在nor可以直接启动,貌似xip片内执行代码就不需要配置时序了??????
(可能也是因为不需要配置就可以读吧,毕竟CPU也是要从nor中读取指令运行的。)eXecute In Place,即芯片内执行,指应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中。flash内执行是指nor flash 不需要初始化,可以直接在flash内执行代码。但往往只执行部分代码,比如初始化RAM.
(注:**片内执行不是说程序在存储器内执行哦,CPU的基本功能就是取指、译码和执行。norflash能在芯片内执行,就是指CPU的取指模块能够直接从norflash中把指令取出来,供后面的译码和执行模块使用。**)那么为什么norflash可以实现XIP,而nandflash就不可以呢?
芯片内执行主要是是看芯片可不可以线性存储代码(假如硬件支持芯片接口),只要能保证芯片的存储空间是线性的(也就是无坏块),都可以片上执行
在读取Flash时候,容易出现“位翻转(bitconvert)
在Flash的位翻转(一个bit位发生翻转)现象上,NAND的出现几率要比NorFlash大得多。这个问题在Flash存储关键文件时是致命的,所以在使用NandFlash时建议同时使用EDC/ECC等校验算法。 ”
但是,如果能保证不出错,也还是可以进行XIP,可以在其上执行代码的:
“所谓XIP,就是CODE是在FLASH上直接运行. NANDFLASH只是不适合做XIP,但并不是不能做XIP“
部分摘自原文链接:https://blog.csdn.net/yjzh_td/article/details/72870044

在前面uart实验的源码基础上,新建init.c和init.h两个文件。在init.c里面只需要设置BANKCON0寄存器即可。

#include "s3c2440_soc.h"
void bank0_tacc_set(int val)
{BANKCON0 = val << 8;
}

写一个测试程序:

#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;
}

在主函数里面,通过串口获取输入的值,传入bank0_tacc_set()函数里,设置Tacc,然后再读取Nor Flash上的闪灯程序。
这个程序设置的是nor的访问时序,这个程序必须烧到nor中同时是nor启动才有效果!!板子在nor上面执行这些程序的时候,效率会发生变化。
实验效果:
输入0~4,Tacc小于70ns,无法读取Nor Flash上数据,LED不能闪烁。
输入4~7,Tacc大于70ns,可以读取Nor Flash上数据,LED不断闪烁,且值越小越快(区别不明显)。

Nor flash知识点

补:https://www.cnblogs.com/053179hu/p/10635601.html
在这里详细介绍一下nor flash吧,韦老师课程中没有详细介绍。
NOR Flash最早是由Intel公司于1988年开发出的,是现在市场上两种主要的非易失性存储器之一,它的出现彻底改变了存储器市场上由EPROM(Erasable Programmable Read-Only-Memory电可编程序只读存储器)和EEPROM(电可擦只读存储器Electrically Erasable Programmable Read - Only Memory)一统天下的局面。NOR Flash最大特点是支持XIP(Execute On Chip),既程序可以直接在NOR flash的片内执行,在NOR Flash中的代码运行时不需要重定位复制到RAM内。NOR Flash的地址线和数据线分开,数据的读取和RAM很类似,只要能够提供数据地址,数据总线就能正确给出数据。不过不能直接对它进行写操作,执行写操作之前需要先发送固定的命令序列,然后发送写操作的地址和数据。

NOR Flash存储器的最小访问单元一般分为8位和16位的,也有一些NOR Flash器件同时支持8位和16位模式,这种Flash的位宽可以在设计硬件时选择,当芯片的BYTE#引脚接为高电平,芯片工作在位宽16位模式,BYTE#引脚设为低电平时,芯片工作在位宽8位模式。

NOR Flash一般有多个扇区,扇区是NOR Flash擦除的最小单位,Nor Flash中每个扇区的大小也不是固定的,扇区的排放一般分为两种模式Top Boot part 和Bottom Boot part 。这两种形式的区别是小块的扇区在NOR Flash芯片中放置的位置不同,Bottom Boot类型的NOR Flash小块地址位于芯片0地址,而Top Boot part类型的NOR Flash小块地址位于芯片的高地址上。

内存控制器的时钟信号由HCLK时钟信号提供,假设设置的HCLK的值为100M,1clock = 10ns。注意,开机时时钟是12MHZ,如果我们在start.s中设置了时钟那么常用的HCLK是100MHZ。

NOR Flash的读操作:

unsigned int nor_read_word(unsigned int base, unsigned int offset)
{volatile unsigned short *p = (volatile unsigned short *)(base + offset);return *p;
}unsigned int nor_dat(unsigned int offset)
{return nor_read_word(NOR_FLASH_BASE, offset);
}

NOR Flash的扇区擦除:
擦除NOR Flash扇区时,应先发送相应的命令,发送命令的顺序如下:
第1个总线周期:往555地址中写入AA
第2个总线周期:往2AA地址中写入55
第3个总线周期:往555地址中写入80
第4个总线周期:往555地址中写入AA
第5个总线周期:往2AA地址中写入55
第6个总线周期:往要擦除的扇区写入30

void nor_write_word(unsigned int base, unsigned int offset, unsigned int val)
{volatile unsigned short *p = (volatile unsigned short *)(base + offset);*p = val;
}/* offset是基于cpu的角度看到 */
void nor_cmd(unsigned int offset, unsigned int cmd)
{nor_write_word(NOR_FLASH_BASE, offset, cmd);
}/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */
void wait_ready(unsigned int addr)
{unsigned int val;unsigned int pre;pre = nor_dat(addr);val = nor_dat(addr);while ((val & (1<<6)) != (pre & (1<<6))){pre = val;val = nor_dat(addr);        }
}void erase_nor_flash_sector(unsigned int addr)
{printf("erasing ...\n\r");nor_cmd(0x555<<1, 0xaa);    /* 解锁 */nor_cmd(0x2aa<<1, 0x55); nor_cmd(0x555<<1, 0x80);     /* erase sector */nor_cmd(0x555<<1, 0xaa);    /* 解锁 */nor_cmd(0x2aa<<1, 0x55); nor_cmd(addr, 0x30);     /* 发出扇区地址 */wait_ready(addr);  /* 等待操作完成 */
}

CPU外接NOR Flash,实际上就是将NOR Flash地址映射为CPU的统一编址。由于nor_cmd函数的offset是基于CPU的角度看到地址,而芯片手册上NOR Flash写入命令的地址从NOR Flash的实际物理地址,NOR Flash是16位的,它的0地址应该对应CPU的0地址和1地址。因此,NOR Flash的物理地址从CPU的角度来看,地址值应该是NOR Flash角度来看的两倍,所以在向某地址写入命令时,要将NOR Flash角度来看的地址右移一位。
擦除是把内容都写成1!!!!!!!!!!

NOR Flash的写操作:

void write_nor_flash(unsigned int addr,unsigned int val)
{/* 烧写 */nor_cmd(0x555<<1, 0xaa);     /* 解锁 */nor_cmd(0x2aa<<1, 0x55); nor_cmd(0x555<<1, 0xa0);     /* program */nor_cmd(addr, val);/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */wait_ready(addr);
}

写操作时值得注意的是,只有写入的目标的地址内容为0xff时,数据才能正确的写入,因此,一般情况下NOR Flash在写入时要对扇区进行擦除操作。
NOR Flash在写入数据时只能将地址中的某位由1变0,而不能将某位由0变1。

假设NOR Flash某地址中存放字符a(0x61),如果未进行擦除前向该地址中写入字符G(0x47),最后该地址内容为A(0x41),发生错误,和我们预期不同。原因如下:
  字符a化为二进制—>1100001
  字符G化为二进制—>1000111
由于写入时数据位只能由0变为1,最终结果100001,相当于执行原始数据和新写入数据进行&操作。

SDRAM知识、原理图

SDRAM参考文档: 高手进阶,终极内存技术指南——完整/进阶版
一个很好的博客文档:https://www.cnblogs.com/biaohc/p/6346878.html

CPU是大爷,只需要发出指令,把地址给了内存控制器,内存控制器就会跑断腿做一系列操作。

SDRAM总共有4个块(Banks),可以认为每个块就是一个表格,里面的每个格子表示的是16bit数据。

问题1:怎样访问里面的某个格子呢?
首先发出一个片选信号,选中整个芯片;
发出Bank地址,选择是哪一个Bank(块,即表格);
发出行地址;
最后发出列地址,才能选中是个格子;

问题2:那么多的信号有谁发出呢?
由内存控制器发出,所以我们需要设置内存控制器,CPU只是简单的执行读写内存的命令,其他的都交给内存控制起来处理。换句话说,CPU将数据或地址发给内存控制器,内存控制器再去访问外部的SDRAM。

要控制sdram,设置内存控制器的寄存器是核心内容,寄存器配置好了,时序会自动搞定。

例如:
LDR R0,=0x30000000
LDR R1,[R0]

CPU把0x30000000这个地址发给内存控制器,内存控制器根据这个地址,判断属于哪个范围,然后发出相应的片选信号。

**内存控制器根据类型(比如SDRAM)**拆分成三部分:发出Bank地址、发出行地址、发出列地址。(不同于sram nor 网卡等的地方!!!)

对于上面的三个,怎样拆分呢?
行地址线有几条,列地址线有几条,都要设置内存控制器里面相关寄存器。

先看原理图:

隐藏了很多重点知识点:
1) 开发板中使用两片16位的SDRAM芯片并联组成32位的位宽,与CPU的32根数据线(DATA0—DATA31)相连。
BANK6的起始地址为0x30000000,范围是0x30000000~0x38000000。
但是SDRAM没有都用到,其访问地址为0x30000000~0x33FFFFFF,共64MB!!!!
2) 上面地址线只用了2-14,理论上可以寻址4(bank)乘2的15次方(32位)=128K,怎么会变成64M呢?
因为sdram特殊,地址是分两次送出,分为行地址和列地址,行地址和列地址公用地址线!
先送出行地址(实际地址线个数那么多位),然后送出列地址,列地址不会占用全部地址线的,占用多少根线呢?是有sdram芯片决定的,我们的是9bit的列地址,所以在程序中寄存器BWSCON的SCAN[1:0]设为0b01表示9位。
所以可寻址的范围就是4(bank)乘2的(15+9)次方=2^26=64M。

SDRAM芯片K4s5m632的行地址数为13,列地址数为9,所以当nSRAS信号有时,ADDR2—ADDR14上发出是行地址信号,它对应32位地址空间的b可23m]:当nSCAS信号有效时,ADDR2—ADDR10上发出的是列地址信号,它对应32位地址空间的bit[0:2];由于BANK6以32位的宽度外接DRAM,ADDR0、ADDR1恒为0,不参与译码。

不用设置行地址吗????控制器知道我们外面接的sdram是用多少地址线吗???
我猜,它是知道的,因为寄存器BANKSIZE中我们有BK76MAP[2:0]:设置BANK6的大小,设为了64M。
补:看一下sdram芯片手册的行列地址的说明:

我们的芯片是:

算起来也就是32M,两片加起来就是64M。

3) 为什么使用ADDR24,ADDR25作为sdram中L-Bank的选择信号。这个地址线怎么选定的呢?
我的理解:行地址线和列地址线的选择没有通过一个专门的IO线去区分。
sdram地址范围:0x30000000~0x33FFFFFF。正好地址中bit24-25是两位,可作为四位的选择。CPU通过给出的地址中这两位的数据,就可以正好区分四个BANK。

4) 其余一些看不懂的控制线是什么意思呢??
据我查看,2440内存控制器的相关寄存器并没有配置这些引脚的,这些引脚好像也不是GPIO,应该是sdram专用的把,它们会自动的按照时序发出信号,我们不用管。
(注:sdram就是内存,不可能想着像单片机自己控制io引脚去控制它!!都是芯片有控制器才能搞定!
而且SDRAM需要一直动态刷新。SDRAM不像静态内存SRAM那么可靠,在使用过程中需要不断去刷新,否则里面的数据会丢失,所以寄存器设置中还有个刷新寄存器。

由于存储芯片位宽为16位,一次可以进行两个字节的读取。但是,通常操作系统里最小寻址单位是1字节,因此内存控制器必须要保证可以访问内存里每一个字节。UDQM ,LDQM分别代表16位数据的高,低字节读取信号,当读取数据时,LDQM /UDQM分别用来控制16位数据中高低字节能否被读取,当LDQM /UDQM为低电平时,对应的高/低字节就可以被读取,如果LDQM /UDQM为高电平时,对应的高/低字节就不能被读取。当向内存里写入数据时,LDQM /UDQM控制数据能否被写入,当LDQM /UDQM为低电平时,对应的高/低字节就可以被写入,如果LDQM /UDQM为高电平时,对应的高/低字节就不能被写入。通过对LDQM /UDQM信号的控制可以控制对两个存储芯片存储数据,由于两个存储单元的地址线是通用的,他们都能接收到CPU发出的地址信号,但是,发给两个存储单元的LDQM /UDQM信号是不同的,以此来区分一个字的高低字节。

S3C2440A为32位CPU,也就是说其数据总线和地址总线宽度都是32位(可以理解为32根线一端连接CPU内部,另外一端连接向内存控制器),那么内存数据的输入/输出端也要保证是32位总线,MINI2440上采用两片16位宽总线内存芯片并联构成32位总线。其中一个芯片连接到CPU数据总线的低16位,另外一个芯片连接到数据总线上的高16位,并联成32位总线,因此两个芯片的输入/输出总线连接到CPU总线上的不同管脚上。
更详细的文档https://www.cnblogs.com/biaohc/p/6346878.html

寄存器设置

不论是nor还是sdram,用的都是同一个内存控制器。不论说到nor控制器还是sdram控制器,其实都是这一套内存控制器,公用一套寄存器。
不过是不同的bank对应的con控制寄存器BANKCONx不同。

内存控制器共有13个寄存器:
BANK0–BANK5只需要设置BWSCON和BANKCONx(x为0~5)两个寄存器;
BANK6、BANK7外接SDRAM时,除BWSCON和BANKCONx(x为6、7)外,还要设置REFRESH、BANKSIZE、MRSRB6、MRSRB7等4个寄存器。

下面依次介绍寄存器:
BWSCON:总线宽度和等待控制寄存器
上面配置nor的时候也讲过,可以结合看。

WAIT信号是芯片向2440发出的,芯片非常慢的时候,cpu发出读写命令后,内存控制器开始操作引脚,在那些时序图规定的时间之内外部芯片还是没有没准备好,就可以发这个信号给内存控制器!!!让它多给大时间。但是我们的原理图没用到这个信号,所以不用管。

关于ST6引脚,是给SRAM用的,我们是sdram,不用。
(如果不想看下面那么多,就用上面这句话来选择就行了!!!)
nWBE和nBE怎么选择呢?
参考:https://blog.csdn.net/liukun321/article/details/5595569
nWE, nWBE, nBE三者之间的关系:
(1)nWE为写使能信号。
(2)nWBE为“写字节使能(write byte enable)”信号,而nBE 为高/低字节选择信号。
nWBE与nBE共用引脚,可以通过对相关寄存器设置来进行功能选择。重点来了:
听老师的视频讲解,貌似nWBE为写字节使能信号,而nBE是读/写字节使能信号(包括了nWBE的功能了)!!
我们的sdram内存是32位的,(两个16位的拼起来也是算32位!!!),如果想去写某个字节的时候,控制器传给内存芯片的也是32位的数据,就需要写字节使能信号控制写在哪里了。但是想读某个字节的时候,不用管这么多,把32位的数据都收上来,内存控制器会挑出我们感兴趣的字节,所以并不需要芯片屏蔽某些位,也就用不着nBE了!!!!!
为什么sram用呢?
我猜想,虽然都是一个内存控制器,不过接的bank不同,对应寄存器设置也不同,bank6-7用来接sdram,可能功能就是强大一点吧,像上面nor的配置那样,ban0-5需要配置的寄存器少,功能可能没那么强大,sram读字节的时候也要自己来用这个nBE信号了。
(3)什么时候需要nWBE而不是nWE?
nWE和nWBE都带有写使能的功能。但既然有nWE,为什么还需要nWBE?这是因为,当使用几片储存芯片进行数据位扩展时,有时需要对芯片分开写数据,此时可使用nWBE。
(比如仅有一片8bit的ROM,因此仅需要nWE,而不需要nWBE。用了2片8bit的ROM,如果不使用nWBE,则写操作是对2片ROM同时进行的,这样,当执行写字节指令时可能会破坏另一芯片中的数据。注意nWBE的信号是自动产生的。从这个角度来说,nWBE有字节数据屏蔽的功能。)

从原理图中我们也可以看到用的是nWBE引脚。

两个16位的sdram分别接了LnWBE[0-1]和LnWBE[2-3],怎么协调呢,我估计呀,相关时序控制都是控制器自己就完成了。如果就一个sdram,32位的,可能芯片上也是LnWBE[0-3]这四个引脚。一样的操控方式。

②BANKCONx:控制寄存器

MT[16:15]:用于设置本BANK外接的是ROM/SRAM还是SDRAM。
SRAM:0b00,SDRAM:0b11(开发板使用的是SDRAM)。
只有这里设置为sdram后,地址才会被拆分成行地址列地址!
当MT[16:15]设置为00时,此寄存器与BANKC0N0、BANKCON5类似。对于bankcon0-5寄存器,bit16-15是空,不用管。我们这里省略给出BANKC0N0的,只给BANKC0N6。
而对于sdram,设置BANKC0N6的时候,除了MT[16:15],只需要设置后面这三个位就可以了!超简便。

先发行地址,再发列地址,中间肯定是有个delay时间的,即是trcd位。
问:为什么这里就是HCLK,100mhz了呢?????我记得前面有个地方计算用的是晶振大小12Mhz。

③ 刷新控制寄存器REFRESH(REFRESHCONTROLREGISTER)

(1)REFEN[23]:0=禁止SDRAM的刷新功能,1:开启SDRAM的刷新功能(设置开启SDRAM的刷新功能)。
(2)TREFMD[22]:SDRAM的刷新模式,0=CBR/AutoRefresh,1=SelfRefresh(一般在系统休眠时使用),我们设置默认值,自动刷新。
(3)Trp[21:20]:根据芯片手册设为0即可。芯片手册会推荐一个值,假设是max 20ns,根据系统的时钟算出需要设置成00,2clock就行了,上电默认是最大的,4clock。
(4)Tsrc[19:18]:根据芯片手册设为默认值0b01即可。和上面同理,在芯片手册搜索这个Trp/Trc看看人家有没有典型值就行了,不用深究什么意思了。(查到Trc是70ns,按照上图的说法Tsrc就是70-20=50ns了)。
(5)RefreshCounter[10:0]:即R_CNT
SDRAM的刷新周期在SDRAM的数据手册上有标明,在本开发板使用的SDRAM:K4S561632的数据手册上,可看见这么一行“64msrefreshpenod(8KCycle)所以,刷新周期=64ms/8192=7.8125us。
Refreshcount=2^11+1-100x7.8=1269=0x4F5。
因此,本开发板中REFRESH设为0x8404F5。

④ BANKSIZE寄存器

⑤ 模式设置寄存器MRSR

能修改的只有位CL[6:4],这是SDRAM时序的一个时间参数,表示发出行、列地址后,等一会才返回数据,等多久呢?看芯片手册,可以等2/3个clock,这是可编程的**,我们在寄存器这里设置了这个值,它是会传递给sdram芯片的!sdram中有一个寄存器会保存这个时间值,以后会在收到列地址后再等这段时间才会向2440返回数据。**
(这些知识就来源于上面推荐的《高手进阶,终极内存技术指南——完整/进阶版》)
CL可以取值为0b0l0(2 clocks)或0b011(3 clocks)。
本开发板取最保守的值0b010,所以MRSRB6的值为0x20。

(补:SRAM可以立刻返回数据的,sdram是个性能不怎么样的芯片,要等一会时间才可以)

SDRAM测试程序

init.c:


#include "s3c2440_soc.h"void sdram_init(void)
{BWSCON   = 0x22000000;BANKCON6 = 0x18001;BANKCON7 = 0x18001;REFRESH  = 0x008404f5;BANKSIZE = 0xb1;MRSRB6   = 0x20;MRSRB7   = 0x20;
}//测试SDRAM地址
int sdram_test(void)
{volatile unsigned char *p = (volatile unsigned char *)0x30000000;int i;// write sdramfor (i = 0; i < 1000; i++)p[i] = 0x55;// read sdramfor (i = 0; i < 1000; i++)if (p[i] != 0x55)return -1;return 0;
}

main.c:

int main(void)
{uart0_init();sdram_init();if (sdram_test() == 0)led_test();//如果测试成功,LED闪烁return 0;
}

实验结果:
LED按预期闪烁,屏蔽掉sdram_init()后,LED不闪烁。

韦一之内存控制器,2440地址空间,NOR flash和SDRAM(012课)相关推荐

  1. 韦东山ARM第一期作业(三)内存控制器和SDRAM

    文章目录 01 - 作业所在路径 02 - 作业描述 03 - 作业解答 01 - 作业所在路径   ARM裸机1期加强版\源码文档图片\文档图片\第012课_内存控制器与SDRAM 02 - 作业描 ...

  2. s3c2440内存控制器与SDRAM基本测试

    前面我们实验的LED和串口程序,是cpu发送地址给特定的寄存器,在寄存器中写相应的位,达到控制要求. 第一类是GPIO门电路如LED,第二类是协议类如串口,这些都不是cpu直接给地址信息,而是通过寄存 ...

  3. 内存控制器与SDRAM_内存接口概念

    辅线1_硬件知识_内存接口概念 如图是S3C2440是个片上系统,有GPIO控制器(接有GPIO管脚),有串口控制器 (接有TXD RXD引脚). 配置GPIO控制器相应的寄存器,即可让引脚输出高低电 ...

  4. assembly 输出ab中所有数_罗克韦尔(AB)PLC控制器选型(2)-CompactLogix 5370

    前面的文章我们介绍过AB的大型PLC--ControlLogix的选型(参考:罗克韦尔(AB)PLC控制器怎样选型(1)). 今天这篇文章,我们来认识下AB的中型PLC产品--CompactLogix ...

  5. 新1期_012课_内存控制器与SDRAM

    一.基础知识 各种外设有各自的控制器.例如GPIO控制器可控制GPIO输入输出,UART 控制器可以控制不同脉冲的产生 等.而CPU的作用是向各种控制器写入数据,CPU是通过地址线区别不同的外设控制器 ...

  6. 七彩虹 pci内存控制器 感叹号 蓝屏 DPC_WATCHDOG_VIOLATION

    最近自己组装台电脑玩, 出现过几次蓝屏 代码 DPC_WATCHDOG_VIOLATION 打开设备管理器 发现好几个黄色感叹号的 点开显示没有兼容驱动(忘记截图了) 大概有 pci内存控制器, sm ...

  7. Memory Population Guidelines for Intel 3rd Gen Xeon Scalable Processors——内存控制器

    Memory Population Guidelines for Intel 3rd Gen Xeon Scalable Processors 英特尔的第三代至强可扩展处理器采用全新的内存控制器架构. ...

  8. 内存控制器(以位宽为16的NOR FLASH举例)

    CPU 执行的指令: "ldr r0,[某个地址 A]",ldr 是装载 4个字节,这是从这个地址里读取某个数据存到 r0 里去. A 地址的 1 字节数据. A+1 地址的 1 ...

  9. ThinkPad T61 安装XP系统后总是提示“PC内存控制器”的问题

    由于使用XP的习惯问题,以及使用VISTA的资源占用问题,因此我很是忠情于XP.但是在T61的本上每次安装好系统后,总是"PCI内存控制器"在硬件列表中出现感叹号,从网上也找不到驱 ...

最新文章

  1. Spring MVC 到 Spring BOOT 的简化之路
  2. R语言使用lmPerm包应用于线性模型的置换方法(置换检验、permutation tests)、使用lm模型构建简单线性回归模型、使用lmp函数生成置换检验回归分析模型
  3. 采购订单的审批状态异常的处理,审批状态为:预审批或是处理中的单据
  4. python三十:time模块
  5. getChars的用法
  6. JavaScript作用域学习笔记(ife2015spring学习心得)
  7. hssfworkbook 单元格合并后宽度不生效_Excel表格“假”合并,有多牛?
  8. ITCAST-C# 委托
  9. IIS识别Json文件
  10. php oracle 无查询结果,php - Oracle Insert查询不起作用,也不会抛出任何错误 - 堆栈内存溢出...
  11. weakhashmap_Java WeakHashMap keySet()方法与示例
  12. 2021年Q2母婴行业季度洞察报告
  13. 对齐输出(信息学奥赛一本通-T1003)
  14. 查看Linux下端口占用情况的命令
  15. 11-17网页基础--表单
  16. 白话Word2Vec
  17. php 格式化js文件,vscode编辑器在php文件中的html/js格式化解决方案
  18. 【后缀数组】bzoj2217 Secretary
  19. 现代软件工程——第一周博客作业
  20. 后端开发都应该掌握的Redis基础

热门文章

  1. 将一句话里的单词进行倒置,标点符号不倒换P228
  2. 信息论与信道编码之BPSK误码率公式推导
  3. Python大蟒蛇平台是干什么用的?
  4. 管理系统:登录成功后可以选择自己的角色,并查看角色的工作任务(使用多态和抽象类来完成)...
  5. 2017-滴滴出行-安全岗笔试
  6. 软件开发人/月成本估算方法
  7. linux只W25Q256驱动,使用m25p80,支持w25q系列nor flash
  8. 淘宝宝贝详情页模板,自动生成宝贝描述模板,淘宝详情页一键生成,切换
  9. C语言程序的运行与调试过程
  10. centos 6.3下rarlinux 与wireshark的安装