程序烧写在norflash上面
Makefile
mem_controler.bin : start.s function.c
arm-linux-gcc -g -c -o start.o start.s
arm-linux-gcc -g -c -o function.o function.c
arm-linux-ld -Ttext 0x30000000 -g start.o function.o -o interrupt.elf
arm-linux-objcopy -O binary -S interrupt.elf interrupt.bin
arm-linux-objdump -D -m arm interrupt.elf > interrupt.dis
clean :
rm -f *.o *.bin *.dis
start.s
.text
.global _start
_start:
b reset
b .
b .
b .
b .
b .
b handle_irq
b .
reset:
@shut down the watchdog
ldr r0, =0x53000000
ldr r1, =0x00000000
str r1, [r0]
@init the stack address
ldr r1, =4096
ldr r0, =0x40000000
add sp, r1, r0
bl init_led
bl init_sdram
@reset the stack pointer
ldr sp, =0x34000000 @change stack to the end of sdram
msr cpsr_c, #0xd2
ldr sp, =0x33F00000 @change the stack pointer of irq mode
msr cpsr_c, #0xd3 @change cpu back to svc mode
bl copy_code2sdram @copy 8KB data from norflash to sdram
ldr pc, =on_sdram
on_sdram:
bl init_interrupt
msr cpsr_c, #0x53 @clear the irq disable bit in cpsr
bl main
halt_loop:
b halt_loop
handle_irq:
sub lr, lr, #4 @set the address(int main function) to return when handle_irq ends
stmdb sp!, {r0-r12, lr} @save the universal registers and lr_irq to the stack of irq mode
bl handle_irq_func @branch to the irq handleing function achieved in function.c
ldmia sp!, {r0-r12, pc}^ @resume the universal registers and save lr to pc while copying spsr to cpsr
function.c
//gpb registers
#define GPBCON (*((volatile unsigned long *)0x56000010))
#define GPBDAT (*((volatile unsigned long *)0x56000014))
//mem controler registers
#define BWSCON (*((volatile unsigned long *)0x48000000))
#define BANKCON0 (*((volatile unsigned long *)0x48000004))
#define BANKCON1 (*((volatile unsigned long *)0x48000008))
#define BANKCON2 (*((volatile unsigned long *)0x4800000C))
#define BANKCON3 (*((volatile unsigned long *)0x48000010))
#define BANKCON4 (*((volatile unsigned long *)0x48000014))
#define BANKCON5 (*((volatile unsigned long *)0x48000018))
#define BANKCON6 (*((volatile unsigned long *)0x4800001C))
#define BANKCON7 (*((volatile unsigned long *)0x48000020))
#define REFRESH (*((volatile unsigned long *)0x48000024))
#define BANKSIZE (*((volatile unsigned long *)0x48000028))
#define MRSRB6 (*((volatile unsigned long *)0x4800002C))
#define MRSRB7 (*((volatile unsigned long *)0x48000030))
//gpg registers
#define GPGCON (*((volatile unsigned long *)0x56000060))
//interrupt related registers
#define EINTMASK (*((volatile unsigned long *)0x560000A4))
#define INTMSK (*((volatile unsigned long *)0x4A000008))
#define INTMOD (*((volatile unsigned long *)0x4A000004))
#define INTOFFSET (*((volatile unsigned long *)0x4A000014))
#define SRCPND (*((volatile unsigned long *)0x4A000000))
#define INTPND (*((volatile unsigned long *)0x4A000010))
#define EINTPEND (*((volatile unsigned long *)0x560000A8))
#define EXTINT1 (*((volatile unsigned long*)(0x5600008c)))
#define EXTINT2 (*((volatile unsigned long*)(0x56000090)))
void init_sdram(){
BWSCON = 0x22011110;
BANKCON0 = 0x00000700;
BANKCON1 = 0x00000700;
BANKCON2 = 0x00000700;
BANKCON3 = 0x00000700;
BANKCON4 = 0x00000700;
BANKCON5 = 0x00000700;
BANKCON6 = 0x00018005;
BANKCON7 = 0x00018005;
REFRESH = 0x008C07A3;
BANKSIZE = 0x000000B1;
MRSRB6 = 0x00000030;
MRSRB7 = 0x00000030;
}
void init_interrupt(){
//set the gpio pins of the six keys to interrupt mode
GPGCON = (1<<(0*2+1) | 1<<(3*2+1) | 1<<(5*2+1) | 1<<(6*2+1) | 1<<(7*2+1) | 1<<(11*2+1));
//set EINTMASK register to enable external interrupt
EINTMASK &= (~(1<<8 | 1<<11 | 1<<13 | 1<<14 | 1<<15 | 1<<19));
//set INTMSK register to inable eint8_23
INTMSK &= (~(1<<5));
//set INTMOD register to set int8_23 to irq mode
INTMOD &= (~(1<<5));
}
void blink(void);
void handle_key(){
int eint_v;
eint_v = EINTPEND;
if(eint_v & (1<<8)){
display_led(1);
EINTPEND = 1<<8;
return;
}
if(eint_v & (1<<11)){
display_led(2);
EINTPEND = 1<<11;
return;
}
if(eint_v & (1<<13)){
display_led(3);
EINTPEND = 1<<13;
return;
}
if(eint_v & (1<<14)){
display_led(4);
EINTPEND = 1<<14;
return;
}
if(eint_v & (1<<15)){
display_led(5);
EINTPEND = 1<<15;
return;
}
if(eint_v & (1<<19)){
display_led(6);
EINTPEND = 1<<19;
return;
}
}
void handle_irq_func(){
int offset_v;
offset_v = INTOFFSET;
switch(offset_v){
case 5:
handle_key();
break;
default:
break;
}
//clear the interrupt
SRCPND = 1< void delay(int n){ int i, j; for(i=0; i } } void blink(){ GPBDAT = 0xffffffff; GPBDAT = 0x00000000; delay(10); GPBDAT = 0xffffffff; delay(10); } void display_led1(){ GPBDAT = ~(1<<5); delay(1); } void display_led2(){ GPBDAT = ~(3<<5); delay(1); } void display_led3(){ GPBDAT = ~(7<<5); delay(1); } void display_led4(){ GPBDAT = ~(15<<5); delay(1); } void display_led(int n){ GPBDAT = ~(n<<5); } void copy_code2sdram(){ int size, i; unsigned char *src, *des; size = 8*1024; des = (unsigned char*)(0x30000000); src = (unsigned char *)(0x00000000); for(i=0; i } } void init_led(){ GPBCON = 0x00015400; GPBDAT &= ~(0x0f<<5); } /* int main(void){ int i; GPBCON = 0x00015400; i = 0; while(1){ GPBDAT = ~(1<<(i+5)); delay(1); i = (i+1)%4; } return 0; } */ int main(void){ while(1){ //wait for external interrupt } return 0; }
上一篇:mini2440 简单的dma工作原理实验
下一篇:mini2440串口轮询实验
推荐阅读最新更新时间:2024-11-11 15:02
设计资源 培训 开发板 精华推荐
- 【CW32】无刷电机驱动器
- LTC1624 的典型应用 - 高效率 SO-8 N 沟道开关稳压控制器
- AD9234-1000EBZ、9680CE04B AD9234-1000高速ADC评估板针对全模拟输入频率范围进行了优化
- RT9068 60V、30A IQ、低压差可调高达25V输出电压线性稳压器的典型应用
- MPC5777MEVB: MPC5777M EVB和适配器(MPC57XXXMB / MPC5777M-416DS / MPC5777M-512DS)
- L7805A 远程关断稳压器的典型应用
- TCR4S25DWBG、200mA、2.5V输出电压CMOS低压降稳压器的典型应用
- PAM8408 2X3W立体声差分输入D类音频放大器的典型应用
- RSO-2405S 5V、200mA输出DC/DC转换器典型应用电路
- 智能窗帘-WQM