本文主要是介绍s3c2440和sdram,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
经过了一段时间考试,今天终于把SDRAM这块给学习了。
1、许多单片机像STM32一直是使用片上FLASH和RAM,MDK也是定义好了下载算法,进行简单地配置就可以了,而s3c2440确需要外扩FLASH和SDRAM(小于4K的程序可以不用配置SDRAM),使用前需要对其进行初始化。
S3C2440 有 27 根地址线 ADDR[26:0],2^27= 128Mbyte ,是一个bank的最大容量,有8个bank,bank0-5 for Rom、Sram,bank6-7 for Rom、sram、Sdram,bank6和bank7可配置大小。通过memory controler来配置SDRAM
SDRAM 内部是一个存储阵列。可以把它想象成一个表格。和表格的检索原理一样,先指定行,再指定列,就可以准确找到所需要的存储单元。这个表格称为逻辑BANK。目前的 SDRAM 基本都是 4 个 L-BANK。寻址的流程就是先指定L- BANK 地址,再指定行地址,最后指定列地址。
HY57V561620F这个SDRAM有
13根行地址线 RA0-RA12
9 根列地址线 CA0-CA8
2 根BANK 选择线 BA0-BA1
SDRAM的地址引脚是复用的,在读写SDRAM存储单元时,操作过程是将读写的地址分两次输入到芯片中,每一次都由同一组地址线输入。两次送到芯片上去的地址分别称为行地址和列地址。它们被锁存到芯片内部的行地址锁存器和列地址锁存器。/RAS 是行地址锁存信号,该信号将行地址锁存在芯片内部的行地址锁存器中;/CAS 是列地址锁存信号,该信号将列地址锁存在芯片内部的列地址锁存器中,这样就更容易理解这里只有15个地址总线了。
SDRAM 的A0接S3C2440 的ADDR2。SDRAM 的A0接S3C2440 的哪一根地址线是根据整个SDRAM 的数据位宽来决定的。(因为CPU的寻址空间是以Byte为单位的)。BA0~BA1 代表了SDRAM 的最高2地址位,因此接ADDR24与ADDR25。也可以这样推理:13根行地址线+9根列地址线 = 22根。另外 HY57V561620F 一个存储单元是2 个字节,相当于有了23根地址线。BA0,BA1 是最高地址位,所以应该接在ADDR24,ADDR25上。也就是说SDRAM 的BA0,BA1接S3C2440 的哪几根地址线是根据整个SDRAM 的容量来决定的。
2、下面是使用SDRAM的程序(汇编+C语言)
a、
AREA Init,CODE,READONLY
ENTRY
start
/* close watchdog */
ldr r0,=0x53000000
mov r1,#0
str r1,[r0] bl initmem bl copyall IMPORT xmain
ldr sp,=0x34000000
ldr lr,=endxmain
ldr pc,=xmain endxmainldr r0, =0x56000010
ldr r1, =0x00015400
str r1, [r0]
ldr r0, =0x56000014
ldr r1, =0x0
str r1,[r0]
loopb loop /* copy the text */
copyall
IMPORT |Image$$RO$$Base|
IMPORT |Image$$RW$$Limit|
ldr r0, =|Image$$RO$Base|
ldr r1, =|Image$$RW$$Limit|
ldr r2, =0x0
copyallloop
teq r0,r1
beq quitcopyallloop
ldr r3, [r2], #4
str r3, [r0], #4
b copyallloop
quitcopyallloop
mov pc, lr /* init mem */
initmem
ldr r0, =0x48000000
ldr r1, =0x48000034
adr r2, memdata
initmemloop
ldr r3, [r2], #4
str r3, [r0], #4
teq r0, r1
bne initmemloop
mov pc,lr memdata<span style="white-space:pre"> </span>//
DCD 0x22000000 //BWSCON
DCD 0x00000700 //BANKCON0
DCD 0x00000700 //BANKCON1
DCD 0x00000700 //BANKCON2
DCD 0x00000700 //BANKCON3
DCD 0x00000700 //BANKCON4
DCD 0x00000700 //BANKCON5
DCD 0x00018005 //BANKCON6
DCD 0x00018005 //BANKCON7
DCD 0x008e07a3 //REFRESH
DCD 0x000000b1 //BANKSIZE
DCD 0x00000030 //MRSRB6
DCD 0x00000030 //MRSRB7END
编译时出了一些问题,bad instruction,如下图:
试了几次,还是不行,又把程序改成了下面的样子
b、下面的程序编译成功,并且下载到板子上成功
Init.s
.equ MEM_CTL_BASE, 0x48000000
.equ SDRAM_BASE, 0x30000000.text
.global _start
_start:bl disable_watchdog
bl memsetup
bl copy_steppingstone_to_sdram
ldr pc,=on_sdramon_sdram:/* IMPORT xmain */ldr sp,=0x34000000bl xmain
halt_loop:b halt_loop/* close watchdog */
disable_watchdog:ldr r0,=0x53000000 mov r1,#0 str r1,[r0]mov pc,lr
/* copy the text */
copy_steppingstone_to_sdram:mov r1,#0ldr r2,=SDRAM_BASEmov r3,#4*1024<span style="white-space:pre"> </span>//4K空间
1:<span style="white-space:pre"> </span>//局部标签ldr r4,[r1],#4 str r4,[r2],#4cmp r1,r3bne 1bmov pc,lr/* init mem */
memsetup:mov r1,#MEM_CTL_BASE<span style="white-space:pre"> </span>//<span style="font-family: Arial, Helvetica, sans-serif;">13个相关寄存器的起始地址</span>adrl r2,memdataadd r3,r1,#52 @13*4<span style="white-space:pre"> </span>//<span style="font-family: Arial, Helvetica, sans-serif;">13个相关寄存器</span><span style="white-space:pre">
</span>
1:ldr r4,[r2],#4str r4,[r1],#4cmp r1,r3bne 1bmov pc,lr.align 4
memdata:<span style="white-space:pre"> </span>//<span style="font-family: Arial, Helvetica, sans-serif;">13个相关寄存器</span>.long 0x22000000 @BWSCON.long 0x00000700 @BANKCON0 .long 0x00000700 @BANKCON1 .long 0x00000700 @BANKCON2 .long 0x00000700 @BANKCON3 .long 0x00000700 @BANKCON4 .long 0x00000700 @BANKCON5 .long 0x00018005 @BANKCON6 .long 0x00018005 @BANKCON7 .long 0x008e07a3 @REFRESH .long 0x000000b1 @BANKSIZE .long 0x00000030 @MRSRB6 .long 0x00000030 @MRSRB7
delay.s
@AREA delay,CODE,READONLY
@entry
@code32
@extern delay
@EXPORT delay
.text
.global delay
delay:sub r0,r0,#1 /* parameter transmission */ cmp r0,#0x0 bne delay mov pc,lr
main.c (跑马灯)
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define LEDS (1<<5|1<<6|1<<7|1<<8)
#define DELAYVAL (0x0ffff)
extern int delay(int time); //int i = 5;
int xmain()
{GPBCON = 0x00015400; // while(i > 0) while(1){GPBDAT=(GPBDAT&(~LEDS)) | (1<<6|1<<7|1<<8);delay(DELAYVAL); GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<7|1<<8);delay(DELAYVAL); GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<8);delay(DELAYVAL); GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<7);delay(DELAYVAL); // i--; }return 0;}
Makefile
sdram.bin:Init.o delay.o main.oarm-linux-ld -Ttext 0x30000000 -o sdram_led.elf $^arm-linux-objcopy -O binary -S sdram_led.elf sdram.binarm-linux-objdump -D sdram_led.elf > sdram.dis
%.o:%.s<span style="white-space:pre"> </span>//通配符arm-linux-gcc -o $@ $< -c
%.o:%.carm-linux-gcc -o $@ $< -c
clean:rm *.o sdram_led.elf sdram.bin sdram.dis
新学到的汇编知识:equ,dcd,align,.word,.long,局部标签1和1b以及arm的一些伪指令,写Makefile时的通配符的运用
还是不知道那些出错的bad instruction是为什么
要搞懂从steppingstone跳转到SDRAM的指令,ldr pc,=on_sdram,看反汇编的代码可以理解
这篇关于s3c2440和sdram的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!