实验三——SDRAM

发布时间:2023-06-13  

一。运行环境


  开发板:jz2440


  系统:  ubuntu12.04


  编译器:arm-linux-gcc


二、特殊寄存器


     sdram的操作无需按照时序图来设置,只要设置好相关的13个寄存器,arm处理器里面的存储管理器会自动输出控制信号


 1     .long   0x22011110      @ BWSCON

 2     .long   0x00000700      @ BANKCON0

 3     .long   0x00000700      @ BANKCON1

 4     .long   0x00000700      @ BANKCON2

 5     .long   0x00000700      @ BANKCON3  

 6     .long   0x00000700      @ BANKCON4

 7     .long   0x00000700      @ BANKCON5

 8     .long   0x00018005      @ BANKCON6

 9     .long   0x00018005      @ BANKCON7

10     .long   0x008C07A3      @ REFRESH

11     .long   0x000000B1      @ BANKSIZE

12     .long   0x00000030      @ MRSRB6

13     .long   0x00000030      @ MRSRB7

先看BWSCON:

每四位控制一个BKNK

对于SDRAM,ST7设置为0,SRAN则设置为1

WSx通常设置为0 

DBx设置为01b,这个一般按照实际情况来设置,还要参照具体开发板上面存储资源。

 

 

对于这六个寄存器,主要设置时序的,默认值就欧克

MT[16:15]设置SRAM   OR  SDRAM   ,这里设置0B11

如果是sdram,那么Trcd 设为推荐值0b10

SCAN 设置为9-bit

 

对于刷新寄存器,注意低11位会根据CLK不同而不同,也就是说使用PLL与否,会有不同的值

由此可算出

Refreh_count =2^12+1-12*64/8092=1955

REFRESF=0x008c0000+1955


  先看代码:这里主要有三个head.S  ,led.c ,Makefile,其中led的代码同流水灯一样,直接拷贝过来。

  此外外,代码参考韦东山先生的源码,经过烧写可验证没问题。


三。直接贴代码

先看Makefile:

1 sdram.bin:head.S led.c

2     arm-linux-gcc -Wall -O2 -c -g -o head.o head.S

3     arm-linux-gcc -Wall -O2 -c -g -o led.o led.c

4     arm-linux-ld -Ttext 0x30000000 head.o led.o -o sdram_elf

5     arm-linux-objcopy -O binary -S sdram_elf sdram.bin

6     arm-linux-objdump -D -m arm sdram_elf>sdram.dis

8 clean:

9     rm -f sdram.bin sdram_elf*.o sdram.dis


再看head.h


 1 .equ MEM_BASE,0x48000000

 2 .equ SDRAM_BASE,0x30000000

 3 

 4 .text

 5 .global _start

 6 _start:

 7 

 8     bl close_watchdog       @关闭看门狗

 9     bl mem_set              @设置存储寄存器组

10     bl steppingstone_sdram  @复制代码到sdram

11 

12     ldr pc,=on_sdram

13 on_sdram:

14     ldr sp,=0x34000000

15     bl main

16 halt_loop:

17     b halt_loop

18 

19 

20 

21 close_watchdog:

22     mov r1,#0x53000000

23     mov r2,#0x0

24     str r2,[r1]

25 

26     mov pc,lr   @返回

27 

28 steppingstone_sdram:    @起始地址0x00000000,目标地址0x30000000

29     mov r1,#0

30     ldr r2,=SDRAM_BASE

31     mov r3,#1024*4

32 

33 

34 copy_loop:

35     ldr r4,[r1],#4

36     str r4,[r2],#4

37 

38     cmp r1,r3

39     bne copy_loop

40     mov pc,lr        @返回

41 

42 mem_set:

43     mov r1,#MEM_BASE

44 

45     adrl r2,JCQ

46     add r3,r1,#52      @4*13

47 

48 set_loop:

49     ldr r4,[r2],#4

50     str r4,[r1],#4

51     cmp r1,r3

52     bne set_loop

53 

54     mov pc,lr

55 

56 

57 .align 4

58 JCQ:

59     .long 0x22011110 @BWSCON

60     .long 0x00000700 @bankcon0

61     .long 0x00000700 @bankcon1

62     .long 0x00000700 @bankcon2

63     .long 0x00000700 @bankcon3

64     .long 0x00000700 @bankcon4

65     .long 0x00000700 @bankcon5

66     .long 0x00018005 @bankcon6

67     .long 0x00018005 @bankcon7

68     .long 0x008c07a3 @refresh

69     .long 0x000000b1 @banksize

70     .long 0x00000030 @mrsrb6

71     .long 0x00000030 @mrsrb7


其实没什么改动,换些名字而已,但是自己敲的话,当然会有一些细节上面会出错,不注意的地方。


以上启动文件是以汇编编写的,下面贴出c语言版的。


 head.S:


 1 .extern main

 2 .text

 3 .global _start

 4 _start:

 5     b reset

 6 

 7 reset:

 8     ldr sp,=4096         @

 9 

10     bl close_watchdog       @关闭看门狗

11     bl mem_set              @设置存储寄存器组

12     bl steppingstone_sdram  @复制代码到sdram

13 

14 

15     

16     ldr pc,=on_sdram

17 on_sdram:

18     ldr sp,=0x34000000

19     ldr pc,=0x30000000

20 halt_loop:

21     b halt_loop


init.c:


 1 /*************************************************************************

 2     > File Name: init.c

 3     > Author: hulig

 4     > Mail:  

 5     > Created Time: 2014年11月08日 星期六 15时52分55秒

 6     >function:init disable watchdog ,init mem .goto main and on

 7     >result:ok

 8  ************************************************************************/

 9 

10 #define WTCON    (*(volatile unsigned long *)0x53000000)

11 #define MEM_BASE (*(volatile unsigned long *)0x48000000)

12 

13 void close_watchdog()

14 {

15     WTCON =0;     //往看门狗寄存器里写0 就可以啦

16 }

17 

18 void mem_set()   //与sdram设置有关的13个寄存器写入对应的值就ok

19 {

20     unsigned long const mem_jcq[]={

21             0x22011110,

22             0x00000700,

23             0x00000700,

24             0x00000700,

25             0x00000700,

26             0x00000700,

27             0x00000700,

28             0x00018005,

29             0x00018005,

30             0x008c07a3,

31             0x000000b1,

32             0x00000030,

33             0x00000030,

34     };

35 

36     int i=0;

37     volatile unsigned long *p=(volatile unsigned long *)MEM_BASE;

38     for(;i<13;i++)

39         p[i]=mem_jcq[i];

40 }

41 

42 void steppingstone_sdram(void)

43 {

44     unsigned int *pSrc=(unsigned int *)0;        // 将steppingstone  0地址复制到sdram起始地址

45     unsigned int *pDes =(unsigned int *)0x30000000;//sdram起始地址

46 

47     while(pSrc48     {

49     *pDes=*pSrc;

50     pDes++;

51     pSrc++;

52     }    

53 

54 

55 }


上面c代码并不能达到预期的效果,其主要问题点是sdram的初始化,也就是给13个寄存器赋值的时候:


 1 《一》。

 2 #define BWSCON (*(volatile unsigned long * )0x48000000)

 3 #define BANKCON0 (*(volatile unsigned long * )0x48000004)

 4 #define BANKCON1 (*(volatile unsigned long * )0x48000008)

 5 #define BANKCON2 (*(volatile unsigned long * )0x4800000c)

 6 #define BANKCON3  (*(volatile unsigned long * )0x48000010)

 7 #define BANKCON4 (*(volatile unsigned long * )0x48000014)

 8 #define BANKCON5 (*(volatile unsigned long * )0x48000018)

 9 #define BANKCON6 (*(volatile unsigned long * )0x4800001c)

10 #define BANKCON7 (*(volatile unsigned long * )0x48000020)

11 #define REFRESH (*(volatile unsigned long * )0x48000024)

12 #define BANKSIZE (*(volatile unsigned long * )0x48000028)

13 #define MRSRB6 (*(volatile unsigned long * )0x4800002c)

14 #define MRSRB7 (*(volatile unsigned long * )0x48000030)

15 

16 

17 void mem_set() 

18 {

19     BWSCON=    0x22011110;

20     BANKCON0=0x00000700;

21     BANKCON1=0x00000700;

22     BANKCON2=0x00000700;

23     BANKCON3=0x00000700;

24     BANKCON4=0x00000700;

25     BANKCON5=0x00000700;

26     BANKCON6=0x00018005;

27     BANKCON7=0x00018005;

28     REFRESH=0x008c07a3;

29     BANKSIZE=0x000000b1;

30     MRSRB6 =0x00000030;

31     MRSRB7=    0x00000030;

32 }

33 

34 

35 《二》。

36 void mem_set()   //与sdram设置有关的13个寄存器写入对应的值就ok

37 {

38     int i=0;

39     unsigned long *p=(unsigned long *)MEM_BASE;

40     unsigned long const mem_jcq[]={

41             0x22011110,

42             0x00000700,

43             0x00000700,

44             0x00000700,

45             0x00000700,

46             0x00000700,

47             0x00000700,

48             0x00018005,

49             0x00018005,

50             0x008c07a3,

51             0x000000b1,

52             0x00000030,

53             0x00000030,

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>