欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Part9:内存控制器与SDRAM硬件编程

程序员文章站 2022-07-14 09:38:26
...

1 内存接口的概念
以s3c2440为例,看下面该开发板的内存接口图

Part9:内存控制器与SDRAM硬件编程

竟然Nor Flash、网卡、SDRAM(内存)、GPIO、UART这些是统一编址,那有没有“独立编址”的呢?
答:有的,nand flash就是一个典例,它不参与CPU的统一编址,看下图

Part9:内存控制器与SDRAM硬件编程

此外,由第一张图可观察到,这些接口是由CPU发给内存控制器32位addr选择的
那问题来了,对于以上接口,内存控制器怎么根据32位的Addr选择不同的芯片/模块呢?

Part9:内存控制器与SDRAM硬件编程

备注:片选名称、addr范围都是查S3C2440芯片手册和原理图获取的

由上图可观察注意到,一个片选信号选通的地址范围是0x0800,0000,即128M范围。128M=2^(27),即需要27根地址总线
但是S3C2440是32位的,有32根地址线,那为只用到了27根地址线呢?
答:CPU发出32位地址,而实际内存控制器只用27根地址线而已,其余地址线另有他用,
   而这涉及到不同位宽芯片的连接问题,看下面的第2点分析
2 不同位宽芯片的地址连接
查看S3C2440的原理图,可发现像SDRAM/DM9000/Nor Flash它们并不是都有27根地址线,而只是其中一部分。
因此,这涉及到内存控制怎样寻址不同芯片,或者说,不同位宽的芯片/设备地址连接关系是怎样的?看下图

Part9:内存控制器与SDRAM硬件编程

备注:上面8/16/32bit RAM芯片的连法可查看S3C2440芯片手册,里面有举例说明。限于篇幅,在此就不贴出了
但是,当读取4字节时,8bit/16bit的RAM怎么读取呢?
答:对应8bitRAM,需发出4次访问,如访问地址是0x4,第一次访问0x4,接着地址自动+1,访问0x5,依次类推
	同理,对于16bitRAM,需要发出两次地址信号。第二次会在第一次地址基础上+1再访问,最终内存控制器
	会组装好4字节数据给CPU。
	可见,正如教程说的。CPU是大爷,不关心内存控制器怎么操作。大爷动动嘴,就让内存控制器跑断腿 :)

最后一个问题,怎么根据确定芯片访问地址
答:1)根据片选信号确定基址
	2)根据芯片所接地址线确定范围
例如,SDRAM(内存)、DM900(网卡)、Nor Flash的访问地址范围如下表

Part9:内存控制器与SDRAM硬件编程
备注一下:SDRAM的地址访问较复杂,下面第4点SDRAM原理和编程时才介绍

3 内存访问时序图
除了地址总线/数据总线,还有其它数据线。例如怎么确定是CPU向SDRAM读数据还是写数据呢?
答:这涉及内存控制时序的问题,还是看图,如下,以可编程访问周期——读时序图为例

Part9:内存控制器与SDRAM硬件编程

补充:1)从左往右理解值,信号的发出顺序。如上面需要读数据时,先发出A[24:0]地址信号,再发出nGCS片选信号,
        最后才发出nOE读使能信号,并等待Tacc时长数据方可读取,而释放信号顺序反过来理解即可。
  2)s3c2440可接不同性能的芯片,这些时间参数就是为满足不同性能芯片可编程设置。
  
上面时间参数如何选择呢?以s3c2440所接的Nor Flash芯片的读时序为例讲解,如下所示

Part9:内存控制器与SDRAM硬件编程

因此,结合Nor Flash和s3c2440的读时序图,可同时发出片选信号、地址信号和读信号,并等待Tacc=70ns即可满足
  Nor Flash这款芯片的读要求。
基于前面文件HCLK=100mHZ,查询s3c2440手册,只需设置BANKCON0里的tacc(即[10:8])即可,如下所示

Part9:内存控制器与SDRAM硬件编程
因为要>=70ns,且HCLK=100mHZ的周期为10ns,故BANKCON0的[10:8]最少为0b101,即5≤val≤7
Part9:内存控制器与SDRAM硬件编程
Part9:内存控制器与SDRAM硬件编程实验效果:我这边测试时,在[4,7]范围内都是有效的,且流水灯速度越来越慢。至于为啥4时有效,不太清楚,
可能有些误差(我用的是S3C2440的V3版本,Nor Flash型号是MX29LV160DBTI-70G(NOR FLASH))

4 SDRAM原理及硬件编程
对于怎么根据addr访问SDRAM,可看下图的简要解释(注:这里偷个懒,直接截取自韦东山老师的课堂笔记,哈哈)

Part9:内存控制器与SDRAM硬件编程
总的来说,要查看SDRAM芯片手册确定行列地址线数后,再配置s3c2440有关内存控制的寄存器以正确匹配地址拆分,
为此才能正确访问SDRAM,下面根据S3C2440接的EM63A165TS(SDRAM)这款芯片为例,讲解如何配置寄存器

对于EM63A165TS(SDRAM)这款芯片查询可知,列地址需9条列地址线(A0-A8),BANK地址2条(64M,需Bank0~Bank3)、
行地址线13条(A0-A12)

对于nGCS6这条SDRAM的片选信号,需要设置5个相关的内存控制寄存器,如下所示
Part9:内存控制器与SDRAM硬件编程
Part9:内存控制器与SDRAM硬件编程
Part9:内存控制器与SDRAM硬件编程
Part9:内存控制器与SDRAM硬件编程
Part9:内存控制器与SDRAM硬件编程
OK,只需设置上面5个寄存器即可,代码如下
sdram_init函数

void sdram_init(void)
{
	BWSCON = 0x22000000;

	BANKCON6 = 0x18001;
	BANKCON7 = 0x18001; //可不设置
	
	REFRESH  = 0x8404f5;
	
	BANKSIZE = 0xb1;
	
	MRSRB6   = 0x20;
	MRSRB7   = 0x20; //可不设置
}

sdram_test函数

int sdram_test(void)
{
	volatile unsigned char *p = (volatile unsigned char *)0x30000000;
 	int i;

	// write sdram
 	for (i = 0; i < 1000; i++)
  		p[i] = 0x55;
  	// read sdram
 	for (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();
	return 0;
}
备注:我并没有贴出完整代码,一方面官网有(www.100ask.net),没必要这里占据篇幅。
           另一方面,重在理解即可。

实验效果:我这里演示是OK的,即测试成功,有流水灯。

总结:
以上就是这篇文章的所有内容,虽然篇幅有点长,但我尽量以图的方式展示了。
主要讲解了内存接口概念、不同位宽芯片的地址连接、内存访问时序图如何看、SDRAM地址拆分和硬件编程。
这些知识很重要,望重视 : )

说明一下,以上内容是基于韦东山老师新1期的“内存控制器及SDRAM”教程里的笔记。
我这里只是重新整理并加以注释总结。更详细的可查看****  (我不做广告,只是尊重版权: )
相关标签: ARM裸机基础编程