;@*************************************************************************
;@ File:head.S
;@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
;@*************************************************************************
IMPORT main
IMPORT disable_watch_dog
IMPORT memsetup
IMPORT copy_steppingstone_to_sdram
AREA Init,CODE,READONLY ;程序入口的地方
ENTRY
START
ldr sp, =4096 ; @设置堆栈
bl disable_watch_dog ; @关WATCH DOG
bl memsetup ; @初始化SDRAM
bl copy_steppingstone_to_sdram
ldr lr, =halt_loop ; @设置返回地址
ldr pc, =main ; @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转
halt_loop
b halt_loop
END
这是一些初始化函数,只要调用了下面函数,注意两个文件不要放在一起:
#define WTCON (*(volatile unsigned long *)0x53000000)//关门狗寄存器的地址
#define MEM_CTL_BASE 0x48000000 //寄存器的起始地址
void disable_watch_dog();
void memsetup();
void copy_steppingstone_to_sdram(void);
void disable_watch_dog()
{
WTCON = 0;//写0就可以了
}
void memsetup()
{
int i = 0;
unsigned long *p = (unsigned long *)MEM_CTL_BASE;
unsigned long const mem_cfg_val[]={ 0x22011110, //BWSCON
0x00000700, //BANKCON0
0x00000700, //BANKCON1
0x00000700, //BANKCON2
0x00000700, //BANKCON3
0x00000700, //BANKCON4
0x00000700, //BANKCON5
0x00018005, //BANKCON6
0x00018005, //BANKCON7
0x008C07A3, //REFRESH
0x000000B1, //BANKSIZE
0x00000030, //MRSRB6
0x00000030, //MRSRB7
};
for(; i < 13; i++)
p[i] = mem_cfg_val[i];//把相应的值写到寄存器地址中就可以完成设置
}
void copy_steppingstone_to_sdram(void)
{
unsigned int *pdwSrc = (unsigned int *)0;
unsigned int *pdwDest = (unsigned int *)0x30000000;//SDRAM的地址
while (pdwSrc < (unsigned int *)4096)
{
*pdwDest = *pdwSrc;
pdwDest++;
pdwSrc++;
}
}
最后是main()函数:
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
void wait(unsigned long dly)
{
for(; dly > 0; dly--);
}
int main(void)
{
unsigned long i = 0;
GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出
while(1){
wait(30000);
GPBDAT = (~(i<<5)); // 根据i的值,点亮LED1-4
if(++i == 16)
i = 0;
}
return 0;
}