s2c2440中IRQ返回。

johnners   2010-3-8 21:13 楼主
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);

}

回复评论 (6)

顶一下吧,让更多人看到我的问题,来帮我解决问题。谢谢。
点赞  2010-3-9 03:58
你要不然把__irq去掉 用BL call
要不然留着__irq 用B jump过去
ARM得返回PC/LR不用mode有不同偏移 4 or 8 bytes 请留意
点赞  2010-3-9 04:44
请问,你的程序进入中断程序了么?
如果可以的话,把你所有代码都贴出来看看
点赞  2010-3-10 15:58
确定是中断函数无返回吗?确定已经进入中断函数吗?
查看一下反汇编代码,看看函数结束那段有没有什么问题
点赞  2010-3-10 16:03
可以使用交叉模式,挺会显示源码和汇编码,有利于问题的分析。
点赞  2010-3-10 17:13
我确定他进入中断了,因为中断是按钮与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 ;
        }


}                 
   

  
     
点赞  2010-3-10 18:28
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复