当前位置 博文首页 > cumtchw:S3C2440裸机------SDRAM

    cumtchw:S3C2440裸机------SDRAM

    作者:[db:作者] 时间:2021-07-12 18:45

    目录

    1.配置内存控制器的寄存器

    1.1BWSCON寄存器设置

    1.2BANKCON6寄存器设置

    1.3REFRESH寄存器配置

    1.4 BANKSIZE寄存器配置

    1.5MRSRB6寄存器配置

    2.代码

    2.1init.h

    2.2init.c

    2.3main.c


    1.配置内存控制器的寄存器

    我们的S3C2440在访问SDRAM的时候,首先发出地址,然后内存控制器首先根据地址范围发出片选信号nGCS6,然后根据片选信号的类型得知是SDRAM,然后拆分地址为 bank地址,行地址和列地址,具体应该怎么把地址拆分成bank地址,行地址,列地址则由我们配置的SDRAM寄存器决定,然后开始读数据。

    1.1BWSCON寄存器设置

    由于我们的SDRAM只连接到了片选6上面,所以我们只看该寄存器的与6相关的几项,由于我们使用了两篇SDRAM组成32位的,所以DW6我们设置成10,WS6表示是否使用wait信号,wait信号是指如果内存芯片的速度很慢,当cpu发出读写命令之后,内存控制器开始驱动相关引脚,在这些时间之内内存芯片还是没有把数据准备好,那么内存芯片可以向内存控制器发出一个wati信号,请求再宽限一点时间,在我们的原理图里面我们根本没用到这个wait信号,这里设置成0,ST6表示SRAM是否使用UB/LB引脚,我们是SDRAM不是SRAM,这个也用不到。

    1.2BANKCON6寄存器设置

    其中MT表示外部接的是ROM SRAM还是SDRAM,这里我们设置成11. SCAN用来设置列地址占据多少位,这个要看内存芯片的芯片手册得到列地址占据多少位,这里我们通过看芯片手册得到列地址占据9位。然后我们的内存控制器是先发出行地址,再发出列地址,然后行地址和列地址之间会有一个时间间隔,这个时间间隔也许要看内存芯片的芯片手册,这里通过看芯片手册得到是20ns,所以我们这里设置成是两个时钟周期。

    1.3REFRESH寄存器配置

    动态内存是在使用过程中需要不断的刷新, 否则里面的数据会丢失, 首先REFEN位肯定要enable,TREFMD我们使用自动刷新模式,然后Refresh Counter里面的Refresh period这个值可以看SDRAM芯片手册, 然后发现64ms刷新8192次,那么刷新周期是64/8192=7.8ms. 然后我们的HCLK正好是100M,所以正好与寄存器配置表的里面例子重合,那么就是1269等于16进制的0x4F5.然后看一下Trp,这个是行地址信号的充电时间,我们直接在内存芯片手册里面搜索这个Trp发现是20ns,也就是两个时钟周期,然后看一下Tsrc,我们再内存芯片手册里面根本搜不到这个名字,但是我们在寄存器的注释里面发现一个公式,Trc = Tsrc + Trp,所以我们去内存芯片手册找一下Trc,发现是70ns,那么可以得到Tsrc是50ns。

    1.4 BANKSIZE寄存器配置

    先看BK76MAP,我们bank6接了两个SDRAM组成了64M的内存,然后BURST-EN是指突发访问,也就是可以一次访问多个字节。 然后SCKE_EN休眠模式使能,然后SCLK_EN使用推荐值。

    1.5MRSRB6寄存器配置

    我们看一下CL,内存控制器读的时候,发出bank地址,行地址,列地址,然后要等待一会才有数据,具体等待时间要看一下我们的SDRAM的芯片手册,SDRAM里面有个MR模式寄存器,里面有一项CL,我们的内存控制器设置了MRSR寄存器之后,它就会向SDRAM发出指定的信号来设置MR使得里面的CL等于某个值。

    2.代码

    我们在之前uart代码的基础上增加两个文件,init.h和init.c。

    2.1init.h

    #ifndef _INIT_H
    #define _INIT_H
    
    void sdram_init(void);
    int sdram_test(void);
    
    #endif

    2.2init.c

    
    #include "s3c2440_soc.h"
    
    void sdram_init(void)
    {
    	BWSCON = 0x22000000;
    
    	BANKCON6 = 0x18001;
    	BANKCON7 = 0x18001;
    
    	REFRESH  = 0x8404f5;
    
    	BANKSIZE = 0xb1;
    
    	MRSRB6   = 0x20;
    	MRSRB7   = 0x20;
    }
    
    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;
    }
    
    

    2.3main.c

    
    #include "s3c2440_soc.h"
    #include "uart.h"
    #include "init.h"
    
    int main(void)
    {
    	uart0_init();
    
    	sdram_init();
    
    	if (sdram_test() == 0)
    		led_test();
    	
    	return 0;
    }
    
    
    
    

    ?

    cs
    下一篇:没有了