IRQ的中断程序无法返回。代码如下,不知道那里出了问题。
HandlerIRQ
BL IRQ_Fun
mov pc ,lr
///////////////////////////////////////////////////////////////////
void Port_Init()
{
rINTMSK = 0xffffffe0;
rEINTMASK = 0xffffe0;
rGPFCON = 0xaaaa;
rGPFUP = 0xf;
}
__irq void IRQ_Fun()
{
switch (rINTPND)
{
case BIT_EINT1 :
rGPBDAT = 0x1c0;
break;
case BIT_EINT2 :
rGPBDAT = 0x160;
break;
case BIT_EINT0 :
rGPBDAT = 0x0e0;
break;
case BIT_EINT4_7:
rGPBDAT = 0x000;
break;
}
rSRCPND &= ~(0x1f);
rINTPND &= ~(0x1f);
rEINTPEND &=~(0x1f);
}
我确定他进入中断了,因为中断是按钮与led灯,当我按下按钮时,led有反映然后就卡住了。正常的话应该是返回到之前的状态。
程序在没中断的时候是在一个c函数里无限循环,同时流水led。有中断时按钮1对应led1,按钮2对应led2等等。可是当按下后led就卡住了。
因此断定是没有从irq中返回。
;Start up code for TQ2440
;2010-03-03 Zhan Yan
GET 2440addr.inc
GET Memcfg.inc
;4 bit of regiser CPSR
USERMODE EQU 0X10
FIQMODE EQU 0X11
IRQMODE EQU 0X12
SVCMODE EQU 0X13
ABORTMODE EQU 0X17
UNDEFMODE EQU 0X1b
;for same opretion
MODEMASK EQU 0X1f
NOINT EQU 0Xc0
;stack address
_STACK_BASEADDRESS EQU 0X33ff8000
UserStack EQU (_STACK_BASEADDRESS-0X3800)
SVCStack EQU (_STACK_BASEADDRESS-0X2800)
UndefStack EQU (_STACK_BASEADDRESS-0X2400)
AbortStack EQU (_STACK_BASEADDRESS-0X2000)
IRQStack EQU (_STACK_BASEADDRESS-0X1000)
FIQStack EQU (_STACK_BASEADDRESS-0X0)
U_MDIV EQU 52
U_PDIV EQU 2
U_SDIV EQU 2
M_MDIV EQU 92
M_PDIV EQU 1
M_SDIV EQU 1
IMPORT Main
IMPORT IRQ_Fun
;IMPORT RdNF2SDRAM
GBLA Y
Y SETA 0X10
GBLA X
PRESERVE8 ;The stack in this section is 8 duiqi
;Point of entry
AREA Init , CODE , READONLY
ENTRY
ResetEntry
B ResetHandler
B HandlerUndef
B HandlerSWI
B HandlerPabort
B HandlerDabort
B .
B HandlerIRQ
B HandlerFIQ
HandlerUndef
B HandlerUndef
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HandlerSWI
cmp r0 ,#4
ldrlo pc ,[pc,r0,lsl #2]
movs pc, lr
SwiFunction
DCD IRQEnable
DCD IRQDisable
IRQEnable
mrs r0 , cpsr
and r0 , r0 , #0x3f
movs pc ,lr
IRQDisable
bl LED
mov pc , lr
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HandlerPabort
B HandlerPabort
HandlerDabort
B HandlerDabort
HandlerIRQ
stmfd sp! ,{r0-r9,lr}
BL IRQ_Fun
ldmfd sp! ,{r0-r9,lr}
subs pc , lr ,#4
HandlerFIQ
B HandlerFIQ
ResetHandler
; B ResetHandler
ldr r0 , =WTCON
ldr r1 , =0x0
str r1 , [r0]
ldr r0 , =INTMSK
ldr r1 , =0xffffffff
str r1 , [r0]
ldr r0 , =INTSUBMSK
ldr r1 , =0x7fff
str r1 , [r0]
ldr r0 , =LOCKTIME
ldr r1 , =0xffffff
str r1 , [r0]
ldr r0 , =CLKDIVN
ldr r1 , =5
STR r1 , [r0]
mrc p15 ,0,r0,c1,c0,0
orr r0 , r0 ,#0xc0000000
mcr p15 ,0,r0,c1,c0,0
ldr r0 , =UPLLCON
ldr r1 , =((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)
str r1 , [r0]
nop
nop
nop
nop
nop
nop
nop
ldr r0 , =MPLLCON
ldr r1 , =((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)
str r1 , [r0]
adrl r0 , SMRDATA
ldr r1 , =BWSCON
add r2 , r0 ,#52
0
ldr r3 ,[r0] , #4
str r3 ,[r1] , #4
cmp r2 , r0
bne %B0
;Delay
mov r0 , #&1000
1
subs r0 , r0 ,#1
bne %B1
bl InitStacks
; bl RdNF2SDRAM
bl Main
InitStacks
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_c,r1 ;UndefMode
ldr sp,=UndefStack ; UndefStack=0x33FF_5C00
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_c,r1 ;AbortMode
ldr sp,=AbortStack ; AbortStack=0x33FF_6000
orr r1,r0,#IRQMODE|NOINT
msr cpsr_c,r1 ;IRQMode
ldr sp,=IRQStack ; IRQStack=0x33FF_7000
orr r1,r0,#FIQMODE|NOINT
msr cpsr_c,r1 ;FIQMode
ldr sp,=FIQStack ; FIQStack=0x33FF_8000
bic r0,r0,#MODEMASK|NOINT
orr r1,r0,#SVCMODE
msr cpsr_c,r1 ;SVCMode
ldr sp,=SVCStack ; SVCStack=0x33FF_5800
;USER mode has not be initialized.
mov pc,lr
;The LR register will not be valid if the current mode is not SVC mode.
SMRDATA DATA
DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0
DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1
DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2
DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3
DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4
DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5
DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6
DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7
DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Tsrc<<18)+(Tchr<<16)+REFCNT)
DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M
DCD 0x30 ;MRSR6 CL=3clk
DCD 0x30 ;MRSR7 CL=3clk
ALIGN
;the test of program :LED
LED
LDR R1 ,=0x56000010 ;Initial port B
LDR R0 ,=0x155555
STR R0 ,[R1]
LDR R0 ,=0x56000014
MOV R1 ,#0x1c0
MOV R2 ,#0x1a0
MOV R3 ,#0x160
MOV R4 ,#0x0e0
MOV R5 , #0
LOOP
STR R3 ,[R0]
BL DELAY
STR R4 ,[R0]
BL DELAY
STR R1 ,[R0]
BL DELAY
STR R2 ,[R0]
BL DELAY
CMP R5 , #0
BEQ LOOP
DELAY
LDR R6 , =1000000
P
SUB R6 ,R6 ,#1
CMP R6 ,#0
BNE P
MOV PC , LR
END
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
#include "2440addr.h"
//#include "stdarg.h"
void delay (int);
void Port_Init();
__swi(0x00)void SWIHandle1(int Handle);
#define EnableIRQ() SWIHandle1(0)
#define DisableIRQ() SWIHandle1(1)
int Main(void)
{
EnableIRQ();
//DisableIRQ();
// Port_Init();
rGPBCON = 0x15400;
//rGPBDAT = 0x1e0;//全灭
rINTMSK = 0xffffffe0;
rGPFCON = 0xaaaa;
rGPFUP = 0xf;
// rSRCPND = 0x0 ;
// rINTPND = 0x0;
//rEINTMASK = 0x0e;
while(1);
// rEINTPEND = 0x0; //clear eint 4
// rEINTMASK =0x0;
while(1)//Uart_GetKey() != ESC_KEY
{
rGPBDAT = 0x1e0;//全灭
delay(5);
rGPBDAT = 0x000;//全亮
delay(5);
rGPBDAT = 0x1c0;//LED1
delay(5);
rGPBDAT = 0x1a0;//LED2
delay(5);
rGPBDAT = 0x160;//LED3
delay(5);
rGPBDAT = 0x0e0;//LED4
delay(5);
}
}
void delay(int NUM)
{
int i,j,k;
for(i=0;i
for(j=0;j<1000;j++)
for(k=0;k<1000;k++)
;
}
void Port_Init()
{
rINTMSK = 0xffffffe0 ;
rGPFCON = 0xaaaa;
rGPFUP = 0xf;
rEXTINT0 =0x22222; //set eint0,1,2,4 falling edge int
rEINTPEND = 0x0; //clear eint 4
rEINTMASK =0x0;
rSRCPND = 0x0 ;
rINTPND = 0x0; //enable eint 4
}
void __irq IRQ_Fun()
{
if(rINTPND==BIT_EINT1)
{
rGPBDAT = 0x1c0;
return ;
}
if(rINTPND==BIT_EINT2)
{
rGPBDAT = 0x160;
return ;
}
if(rINTPND==BIT_EINT4_7)
{
rGPBDAT = 0x1a0;
return ;
}
if(rINTPND==BIT_EINT0)
{
rGPBDAT = 0x0e0;
return ;
}
}