mini2440中断处理实验

中断处理实验主要在片内SRAM中进行了实验。其中中断的过程主要注意一下,都已经在截图的文字中说明了。



下面看下代码,代码都有很清晰的注释了。

首先是Makefile,可以看出运行的地址从0x00000000开始的片内SRAM中,程序很小,只有272字节,因此没有必要动用SDRAM。

int.bin:head.S init.c

                                                                  arm-linux-gcc-O2 -c -o head.o head.S

                                                                  arm-linux-gcc-O2 -c -o init.o init.c

                                                                  arm-linux-ld-Ttext 0x00000000 head.o init.o -o int_elf

                                                                  arm-linux-objcopy-O binary -S int_elf int.bin

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

clean:

                                                                  rm-f head.o init.o int.bin int.dis int_elf

 

 

 

下面是汇编主程序

.text

.global _start

_start:

                                                                           blreset                                                                    @0x00000000 重启

HandleUndef:                                                                                                         @0x00000004 未定义异常

                                                                           bHandleUndef

HandleSWI:                                                                                                                      @0x00000008 软中断异常

                                                                           bHandleSWI

HandlePrefetchAbt:                                                                 @     0x0000000C 预取指令处理异常

                                                                           bHandlePrefetchAbt

HandleDataAbt:                                                                                           @0x00000010 数据访问终止异常

                                                                           bHandleDataAbt

HandleNoUsed:                                                                                                     @0x00000014 未使用异常

                                                                           bHandleNoUsed

                                                                           b      HandleIRQ                                                                @0x00000018 中断异常      

HandleFIQ:                                                                                                                       @0x0000001C 快速中断异常

                                                                           bHandleFIQ

                                                                                   

HandleIRQ:

                                                                           sublr,lr,#4                                                                @将lr-4,指向

                                                                           stmdbsp!,{r0-r12,lr}                          @     将r0-r12保存,并将lr作为下一个返回地址保存

                                                                           blhandle_irq                                                           @     由于handle_irq在片内SRAM中,bl的地址范围足够

                                                                                                                                                                                                    @     如果handle_irq在SDRAM中,需要用寻址范围更大的ldrpc,=***,并保存lr作为返回地址

                                                                           ldmiasp!,{r0-r12,pc}^              @ 将r0-r12恢复,lr恢复到pc中,即相当于跳转到被中断地址了

                                                                                                                                                                                                    @^表示当寄存器列表中有pc的时候,将spsr的内容返回到cpsr中

                                                                                                                                                                                                    @!表示sp为最后的地址,即自动的修改栈顶指针

                                                                          

reset:

                                                                           ldrsp,=4096                                                   @设置刚刚开启CPU的栈指针

                                                                           blclose_watchdog                            @关闭看门狗

@                                                                       blinit_sdram                                                 @初始化SDRAM   并没有使用SDRAM,所以,这句话可以屏蔽掉

                                                                           msrcpsr_c,#0xD2                               @进入中断模式

                                                                           ldrsp,=3074                                                   @设置中断模式下的栈指针

                                                                           msrcpsr_c,#0xD3                               @进入管理模式

                                                                           ldrsp,=4096                                                   @设置系统模式下的栈指针

                                                                           blinit_led_int                                       @初始化中断和LED等

                                                                           msrcpsr_c,#0x53                               @开启IRQ中断

loop:

                                                                           bloop                                                                                 @设置循环

 

 

然后是子函数代码

#define GPBCON(*(volatile unsigned long *)0x56000010)

#define GPBDAT(*(volatile unsigned long *)0x56000014)

#define GPGCON(*(volatile unsigned long *)0x56000060)

#define GPGDAT(*(volatile unsigned long *)0x56000064)

#define SRCPND(*(volatile unsigned long *)0x4A000000)

#define INTMOD(*(volatile unsigned long *)0x4A000004)

#define INTMSK(*(volatile unsigned long *)0x4A000008)

#define PRIORITY(*(volatile unsigned long *)0x4A00000C)

#define INTPND(*(volatile unsigned long *)0x4A000010)

#defineINTOFFSET (*(volatile unsigned long *)0x4A000014)

#defineSUBSRCPND (*(volatile unsigned long *)0X4A000018)

#defineINTSUBMSK (*(volatile unsigned long *)0x4A00001C)

#define EXTINT1(*(volatile unsigned long *)0x5600008c)

#define EINTMASK(*(volatile unsigned long *)0x560000a4)

#define EINTPEND(*(volatile unsigned long *)0x560000a8)

 

voidclose_watchdog()

{

                                                                           #definerWTCON (*(volatile unsigned long *)0x53000000)

                                                                           rWTCON= 0;

}

voidinit_led_int()

{

/*

使用K1,GPG0接口,EINT8外部中断,属于EINT8_23的子中断

LED1作为显示,GPB5

*/

                                                                           //1初始化LED相关内容GPB5

                                                                           GPBCON&= ~(3<<10);

                                                                           GPBCON|= 1<<10;          //设置GPB5为输出

                                                                           GPBDAT&= ~(1<<5);       //LED初始化为亮

                                                                          

                                                                           //2设置中断相关

                                                                           //2.1将IO设置为外部中断模式

                                                                           GPGCON&= ~(3<<0);

                                                                           GPGCON|= 2<<0;                     //将GPG0设置为EINT8

                                                                           //2.1设置相应的寄存器,屏蔽中断

                                                                           //INTMOD默认为0,也就是所有中断均使用IRQ模式

                                                                           //PRIORITY默认 INTSUBMSK和INTSUBMSK因为子中断没有用到而默认

                                                                           INTMSK= ~(1<<5);           //除了EINT8_23中断的其他中断都被屏蔽

                                                                           EINTMASK= ~(1<<8);      //屏蔽除EINT8的其他中断

                                                                           EXTINT1&= ~(0xF);         

                                                                           EXTINT1|= 0xA;                                  //设置下降沿触发,滤波

}

 

voidhandle_irq()

{

                                                                           if(INTOFFSET== 5)

                                                                           {

                                                                                             GPBDAT|= 1<<5;     //关闭LED

                                                                           }

                                                                           SRCPND= 1<<5;

                                                                           EINTPEND= 1<<8;

                                                                           INTPND= 1<<5;       //清中断位

}

 

值得一提的是实验使用==语句并没有出现问题,与上一次遇到的情况不同。也不太确定原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值