微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2440中断体系结构

S3C2440中断体系结构

时间:11-13 来源:互联网 点击:

0xd2 @ 进入中断模式,cpsr_c表示cpsr[7:0],0xd2=0b1101 0010

ldr sp, =3072 @ 设置中断模式栈指针

msr cpsr_c, #0xdf @ 进入系统模式

ldr sp, =4096 @ 设置系统模式栈指针,

@ 其实复位之后,CPU就处于系统模式,

@ 前面的“ldr sp, =4096”完成同样的功能,此句可省略

bl init_led @ 初始化LED的GPIO管脚

bl init_irq @ 调用中断初始化函数,在init.c中

msr cpsr_c, #0x5f @ 设置I-bit=0,开IRQ中断

ldr lr, =halt_loop @ 设置返回地址

ldr pc, =main @ 调用main函数

halt_loop:

b halt_loop

HandleIRQ:

sub lr, lr, #4 @ 计算返回地址

stmdb sp!, { r0-r12,lr } @ 保存使用到的寄存器

@ 注意,此时的sp是中断模式的sp

@ 初始值是上面设置的3072

ldr lr, =int_return @ 设置调用ISR即EINT_Handle函数后的返回地址

ldr pc, =EINT_Handle @ 调用中断服务函数,在interrupt.c中

int_return:

ldmia sp!, { r0-r12,pc }^ @ 中断返回, ^表示将spsr的值复制到cpsr

/*

* init.c: 进行一些初始化

*/

#include "s3c24xx.h"

/*

* LED1-4对应GPB5、GPB6、GPB7、GPB8

*/

#define GPB5_out (1<(5*2)) // LED1

#define GPB6_out (1<(6*2)) // LED2

#define GPB7_out (1<(7*2)) // LED3

#define GPB8_out (1<(8*2)) // LED4

/*

* K1-K4对应GPG0,GPG3,GPG5,GPG6

*/

#define GPG0_eint (2<(0*2)) // K1,EINT8

#define GPG3_eint (2<(3*2)) // K2,EINT11

#define GPF5_eint (2<(5*2)) // K3,EINT13

#define GPF6_eint (2<(6*2)) // K4,EINT14

/*

* 关闭WATCHDOG,否则CPU会不断重启

*/

void disable_watch_dog(void)

{

WTCON = 0;// 关闭WATCHDOG很简单,往这个寄存器写0即可

}

void init_led(void)

{

GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out ;

}

/*

* 初始化GPIO引脚为外部中断

* GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD)

*/

void init_irq( )

{

GPGCON = GPG0_eint | GPG3_eint |GPG5_eint |GPG6_eint;

// 对于EINT8、11、13、14,需要在EINTMASK寄存器中使能它们

EINTMASK &= (~(1<8)) & (~(1<11)) & (~(1<13)) & (~(1<14));

/*

* 设定优先级:

* ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ3,即EINT0 > EINT2

* 仲裁器1、6无需设置

* 最终:

* EINT0 > EINT2 > EINT11,EINT19,即K4 > K3 > K1,K2

* EINT11和EINT19的优先级相同

*/

PRIORITY = (PRIORITY & ((~0x01) | (0x3<7))) | (0x0 < 7) ;

//开启EINT8_23

INTMSK &= ~(1<5);

}

interrupt.c

#include "s3c24xx.h"

void EINT_Handle()

{

unsigned long oft = INTOFFSET;

switch( oft )

{

//INTOFFSET为5时,代表INTPND的位[5]为1,则EINT8-23中断发生

case 5:

{

GPBDAT |= (0x0f<5); //LED全灭

if (EINTPEND & (1<8)) //EINT8发生(EINT8对应K1)

GPBDAT &= ~(1<5);

if (EINTPEND & (1<11)) //EINT11发生(EINT8对应K2)

GPBDAT &= ~(1<6);

if (EINTPEND & (1<13)) //EINT13发生(EINT8对应K3)

GPBDAT &= ~(1<7);

if (EINTPEND & (1<14)) //EINT14发生(EINT8对应K4)

GPBDAT &= ~(1<8);

break;

}

default:

break;

}

//清除中断

if(oft == 5)

EINTPEND = (1<8) | (1<11) | (1<13) | (1<14);

SRCPND = 1

INTPND = 1

}

main.c

int main()

{

while(1);

return 0;

}

Makefile

objs := head.o init.o interrupt.o main.o

int.bin: $(objs)

arm-linux-ld -Ttext 0x00000000 -o int_elf $^

arm-linux-objcopy -O binary -S int_elf $@

arm-linux-objdump -D -m arm int_elf > int.dis

%.o:%.c

arm-linux-gcc -Wall -O2 -c -o $@ $

%.o:%.S

arm-linux-gcc -Wall -O2 -c -o $@ $

clean:

rm -f int.bin int_elf int.dis *.o


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top