Board logo

标题: S3C2440 SDRAM原理到驱动解释完整版(7) [打印本页]

作者: look_w    时间: 2017-10-24 20:54     标题: S3C2440 SDRAM原理到驱动解释完整版(7)

1.1.8  
内存驱动实验设置该工程加载时运行时地址为0x30000000,如图2-55所示:

2-55设置加载时运行时地址
init.s:本程序文件主要实现了,关闭看门狗,初始化内存,拷贝ROM数据到内存中,然后跳往内存中执行xmain函数,从xmain函数返回之后,将全部led点亮,进入死循环。
;
;
内存初始化实验
;
AREA Init, CODE, READONLY
ENTRY
start
; close watchdog
ldr r0, = 0x53000000                     
;
将看门狗控制寄存器地址放入r0
mov r1, #0

str r1, [r0]                                       
;
设置看门狗控制寄存器的值为0

bl initmem                                      
;
跳转到initmem代码段,初始化内存

bl copyall                                       
;
跳转到数据拷贝代码段,将ROM中数据拷贝到内存中

IMPORT xmain                             
;
引入main.c中的xmain函数
ldr sp, =0x34000000                     
;
调用C程序之前先初始化栈指针
ldr lr, =endxmain                           
;
设置xmain函数的返回地址
ldr pc, =xmain                                
;
跳转到C程序中的xmain函数的入口处执行


endxmain

ldr r0, =0x56000010            
        
; LEDGPIO接口配置寄存器
ldr r1, =0x00015400                     
; GPIO配置数据
str r1, [r0]  
                                 
;
设置GPIO
ldr r0, =0x56000014  
               
; LED控制寄存器地址
ldr r1, =0x0  
                              
;
全部LED
str r1,[r0]

loop
   
b loop                                      
;
死循环


copyall

IMPORT |Image

RO


Base|               
;
引入编译器Image

RO


Base符号变量IMPORT |Image

RW



Limit|               
;
引入编译器Image

RW



Limit符号变量ldr r0, = |Image$$RO$Base|                    
;
取得Image$$RO$Base域基址的值
ldr r1, = |Image

RW



Limit|                 
;
取得Image$$RW$Base域结束地址的值ldr r2, =0x0                                             
;
数据拷贝源地址
copyallloop
teq r0,r1                                                   
;
测试是否拷贝完成
beq quitcopyallloop                                 
;
拷贝完成跳往quitcopyallloop退出
ldr r3, [r2], #4                                          
;
四字节加载
str r3, [r0], #4                                          
;
四字节存储
b copyallloop                                          
;
返回继续执行
quitcopyallloop
mov pc, lr                                                
;
调用返回


initmem                                                   
;
内存初始化
ldr r0, =0x48000000                              
;
加载内存相关寄存器首地址r0
ldr r1, =0x48000034                              
;
加载内存相关寄存器尾地址到r1
adr r2, memdata
                           
;
将寄存器配置数据地址段首地址加载到r2
initmemloop
ldr r3, [r2], #4                                          
;
循环设置存寄存器
str r3, [r0], #4
teq r0, r1
bne initmemloop                                      
;
循环到最后一个寄存器时退出函数
mov pc,lr



memdata
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               
;MRSRB7

END

main.c:本程序文件主要实现led灯的初始化,然后四个led灯循环滚动亮5遍,xmain函数返回。
/* C语言函数
*/
/*
端口F寄存器预定义
*/
#define      
GPBCON         
(*(volatile unsigned long *)0x56000010)
#define      
GPBDAT           
(*(volatile unsigned long *)0x56000014)
#define
     
LEDS  
           
(1<<5|1<<6|1<<7|1<<8)
#define
     
DELAYVAL   
(0x1ffff)
extern int delay(int time);
      
/*
声明外部声明汇编函数
*/


int i = 5;
int xmain()
{
        
GPBCON
= 0x00015400;
        
//GPF4--GPF7设置为output
        
while(i > 0) {
         
        
//第一个LED灯亮
      
     
GPBDAT=(GPBDAT&(~LEDS)) | (1<<6|1<<7|1<<8);
     
      
delay(DELAYVAL);            
//调用汇编语言编写的延时程序


         
        
//第二个LED灯亮
      
     
GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<7|1<<8);
      
     
delay(DELAYVAL);            
//调用汇编语言编写的延时程序


         
        
//第三个LED灯亮
      
     
GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<8);
      
     
delay(DELAYVAL);                     
//调用汇编语言编写的延时程序



         
        
//第四个LED灯亮
     

     
GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<7);
      
     
delay(DELAYVAL);                     
//调用汇编语言编写的延时程序
      
     
i--;

   
}
   
return 0;

}



delay.s本程序文件主要通常汇编来实现延时功能。
;汇编指令延时程序

EXPORT delay
AREA
DELAY,CODE,READONLY
      
;该伪指令定义了一个代码段段名为Init属性只读
;下面是延迟子程序
delay
        
sub r0,r0,#1            
;r0=r0-1

         
cmp r0,#0x0            
;r0的值与0相比较
         
bne delay              

;比较的结果不为0r0不为0),继续调用delay,否则执行下一条语句
         
mov pc,lr              

;返回


   
  
END                  
         
;程序结束符




内存的初始化也可以用下面的C程序实现
C语言版本
#define
     
MEM_CTL_BASE              
0x48000000
#define
     
MEM_CTL_END
              
0x48000034
/* SDRAM 13个寄存器的值
*/
unsigned long
const   
mem_cfg_val[]={        
//
声明数组存放内存控制器设置数据
         
0x22000000,               
//BWSCON
         
0x00000700,               
//BANKCON0
         
0x00000700,               
//BANKCON1
         
0x00000700,               
//BANKCON2
         
0x00000700,               
//BANKCON3

         
0x00000700,               
//BANKCON4
         
0x00000700,               
//BANKCON5
         
0x00018005,               
//BANKCON6
         
0x00018005,               
//BANKCON7
         
0x008e07a3,               
//REFRESHHCLK = 12MHz该值为0x008e07a3
                                               
//HCLK = 100MHz 0x008e04f5
         
0x000000b1,               
//BANKSIZE
         
0x00000030,               
//MRSRB6
         
0x00000030,               
//MRSRB7
};
void mem_init(void)
{
        
int
  
i = 0;
        
unsigned long *p = (unsigned long *)MEM_CTL_BASE;
        
for(; i < (MEM_CTL_END - MEM_CTL_BASE)/4; i++)
         
        
p = mem_cfg_val;
}




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0