标题:
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
; LED
的
GPIO
接口配置寄存器
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
R
O
Base|
;
引入编译器
Image
R
O
Base
符号变量
IMPORT |Image
R
W
Limit|
;
引入编译器
Image
R
W
Limit
符号变量
ldr r0, = |Image$$RO$Base|
;
取得
Image$$RO$Base
域基址的值
ldr r1, = |Image
R
W
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
;
比较的结果不为
0
(
r0
不为
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,
//REFRESH
(
HCLK = 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