导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→自学arm遇到中断方面问题,s3c44b0进入中断服务程序后[quqw]

 *第36800篇: 自学arm遇到中断方面问题,s3c44b0进入中断服务程序后无法返回。

  
楼 主:quqw 2009年4月7日22:22
 自学arm遇到中断方面问题,s3c44b0进入中断服务程序后无法返回。
我正在自学arm,中断方面遇到一些问题,rINTCON=0x5;时中断能够服务,但是无法返回。 rINTCON=0x1;中断产生时直接重启。有没有谁能帮我解释一下?谢谢!主要代码如下
void __irq EINT4567Isr(void)
{
 rI_ISPC|=BIT_EINT4567;
 Uart_Printf("%dinterrupt happen\r\nINTPEND=%x\r\nr_ISPR=%x\r\n\r\n",temp++,rINTPND,rI_ISPR);
 Uart_GetString(buf);
 //while(1);
}

void Main(void)
{


#if (PLLON==1)
  ChangePllvalue(PLL_M,PLL_P,PLL_S);
#endif

  
  Port_Init ();  
  Uart_Init (0,115200);
  Uart_Select (0);
  Isr_Init();
while(1)
{

 ;

}

}
void Isr_Init(void)
{

    
    rINTCON=0x5;   // Vectored Int. IRQ enable,FIQ disable  
    rINTMOD =0;  
    rINTMSK |=BIT_GLOBAL;  //disabled int

   //以下针对特定的中断口做初始化   
    rPCONG = rPCONG | 0xff00; //set GPG[7:4] interrupt 
    rPUPG = rPUPG & 0x00;//pull up resistor disable
    setLLInt(4);
    setLLInt(5);
    setLLInt(6);
    setLLInt(7);
    rEXTINT &= 0xffff;
    rINTPND=0;
    rEXTINTPND=0;
    pISR_EINT4567=(unsigned)EINT4567Isr;
    pISR_TIMER1=(unsigned)TIMER1Isr;
    rINTMSK &=~(BIT_GLOBAL|BIT_EINT4567);
}

启动代码如下:
; *******************************************************
; * NAME    : 44BINIT.S     *
; * Version : 10.JAn.2003    *
; * Description:     *
; * C start up codes    *
; * Configure memory, Initialize ISR ,stacks *
; * Initialize C-variables    *
; * Fill zeros into zero-initialized C-variables *
; *******************************************************
 
    GET ..\inc\option.s
    GET ..\inc\memcfg.s

;Interrupt Control
INTPND     EQU 0x01e00004
INTMOD     EQU 0x01e00008
INTMSK     EQU 0x01e0000c
I_ISPR     EQU 0x01e00020
I_CMST     EQU 0x01e0001c

;Watchdog timer
WTCON     EQU 0x01d30000

;Clock Controller
PLLCON     EQU 0x01d80000
CLKCON     EQU 0x01d80004
LOCKTIME    EQU 0x01d8000c
 
;Memory Controller
REFRESH     EQU 0x01c80024

;Pre-defined constants
USERMODE    EQU 0x10
FIQMODE     EQU 0x11
IRQMODE     EQU 0x12
SVCMODE     EQU 0x13
ABORTMODE   EQU 0x17
UNDEFMODE   EQU 0x1b
MODEMASK    EQU 0x1f
NOINT     EQU 0xc0


;check if tasm.exe is used.
    GBLL    THUMBCODE
    [ {CONFIG} = 16 
THUMBCODE SETL {TRUE}
    CODE32
    |   
THUMBCODE SETL {FALSE}
    ]

    [ THUMBCODE
    CODE32   ;for start-up code for Thumb mode
    ]

    MACRO
$HandlerLabel HANDLER $HandleLabel

$HandlerLabel
    sub     sp,sp,#4     ;decrement sp(to store jump address)
    stmfd   sp!,{r0}     ;PUSH the work register to stack(lr does't push because it return to original address)
    ldr     r0,=$HandleLabel;load the address of HandleXXX to r0
    ldr     r0,[r0]     ;load the contents(service routine start address) of HandleXXX
    str     r0,[sp,#4]     ;store the contents(ISR) of HandleXXX to stack
    ldmfd   sp!,{r0,pc}     ;POP the work register and pc(jump to ISR)
    MEND

    IMPORT |Image$$RO$$Limit|  ; End of ROM code (=start of ROM data)
    IMPORT |Image$$RW$$Base|   ; Base of RAM to initialise
    IMPORT |Image$$ZI$$Base|   ; Base and limit of area
    IMPORT |Image$$ZI$$Limit|  ; to zero initialise

    IMPORT  Main    ; The main entry of mon program 
    EXPORT  __ENTRY

    AREA    Init,CODE,READONLY  

__ENTRY 
    b ResetHandler  ;for debug
    b HandlerUndef  ;handlerUndef
    b HandlerSWI    ;SWI interrupt handler
    b HandlerPabort ;handlerPAbort
    b HandlerDabort ;handlerDAbort
    b .      ;handlerReserved
    b HandlerIRQ ;0x18
    b HandlerFIQ
 ;***IMPORTANT NOTE***
 ;If the H/W vectored interrutp mode is enabled, The above two instructions should
 ;be changed like below, to work-around with H/W bug of S3C44B0X interrupt controller. 
 ; b HandlerIRQ  ->    subs pc,lr,#4
 ; b HandlerIRQ  ->    subs pc,lr,#4

VECTOR_BRANCH
    ldr pc,=HandlerEINT0    ;mGA    H/W interrupt vector table
    ldr pc,=HandlerEINT1    ; 
    ldr pc,=HandlerEINT2    ;
    ldr pc,=HandlerEINT3    ;
    ldr pc,=HandlerEINT4567 ;
    ldr pc,=HandlerTICK     ;mGA
    b .
    b .
    ldr pc,=HandlerZDMA0    ;mGB
    ldr pc,=HandlerZDMA1    ;
    ldr pc,=HandlerBDMA0    ;
    ldr pc,=HandlerBDMA1    ;
    ldr pc,=HandlerWDT     ;
    ldr pc,=HandlerUERR01   ;mGB
    b .
    b .
    ldr pc,=HandlerTIMER0   ;mGC
    ldr pc,=HandlerTIMER1   ;
    ldr pc,=HandlerTIMER2   ;
    ldr pc,=HandlerTIMER3   ;
    ldr pc,=HandlerTIMER4   ;
    ldr pc,=HandlerTIMER5   ;mGC
    b .
    b .
    ldr pc,=HandlerURXD0    ;mGD
    ldr pc,=HandlerURXD1    ;
    ldr pc,=HandlerIIC     ;
    ldr pc,=HandlerSIO     ;
    ldr pc,=HandlerUTXD0    ;
    ldr pc,=HandlerUTXD1    ;mGD
    b .
    b .
    ldr pc,=HandlerRTC     ;mGKA
    b .       ;
    b .       ;
    b .       ;
    b .       ;
    b .       ;mGKA
    b .
    b .
    ldr pc,=HandlerADC     ;mGKB
    b .       ;
    b .       ;
    b .       ;
    b .       ;
    b .       ;mGKB
    b .
    b .
;0xe0=EnterPWDN
    ldr pc,=EnterPWDN

    LTORG 

HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort

HandlerADC HANDLER HandleADC
HandlerRTC HANDLER HandleRTC
HandlerUTXD1 HANDLER HandleUTXD1
HandlerUTXD0 HANDLER HandleUTXD0
HandlerSIO HANDLER HandleSIO
HandlerIIC HANDLER HandleIIC
HandlerURXD1 HANDLER HandleURXD1
HandlerURXD0 HANDLER HandleURXD0
HandlerTIMER5 HANDLER HandleTIMER5
HandlerTIMER4 HANDLER HandleTIMER4
HandlerTIMER3 HANDLER HandleTIMER3
HandlerTIMER2 HANDLER HandleTIMER2
HandlerTIMER1 HANDLER HandleTIMER1
HandlerTIMER0 HANDLER HandleTIMER0
HandlerUERR01 HANDLER HandleUERR01
HandlerWDT HANDLER HandleWDT
HandlerBDMA1 HANDLER HandleBDMA1
HandlerBDMA0 HANDLER HandleBDMA0
HandlerZDMA1 HANDLER HandleZDMA1
HandlerZDMA0 HANDLER HandleZDMA0
HandlerTICK HANDLER HandleTICK
HandlerEINT4567 HANDLER HandleEINT4567
HandlerEINT3 HANDLER HandleEINT3
HandlerEINT2 HANDLER HandleEINT2
HandlerEINT1 HANDLER HandleEINT1
HandlerEINT0 HANDLER HandleEINT0


;One of the following two routines can be used for non-vectored interrupt.

IsrIRQ ;using I_ISPR register.
    sub     sp,sp,#4       ;reserved for PC
    stmfd   sp!,{r8-r9}   

 ;IMPORTANT CAUTION
 ;if I_ISPC isn't used properly, I_ISPR can be 0 in this routine.

    ldr     r9,=I_ISPR
    ldr     r9,[r9]
    mov     r8,#0x0
0
    movs    r9,r9,lsr #1
    bcs     %F1
    add     r8,r8,#4
    b     %B0

1
    ldr     r9,=HandleADC
    add     r9,r9,r8
    ldr     r9,[r9]
    str     r9,[sp,#8]
    ldmfd   sp!,{r8-r9,pc}


;****************************************************
;* START         *
;****************************************************
ResetHandler
    ldr     r0,=WTCON     ;watch dog disable 
    ldr     r1,=0x0   
    str     r1,[r0]

    ldr     r0,=INTMSK
    ldr     r1,=0x07ffffff  ;all interrupt disable
    str     r1,[r0]

    ;****************************************************
    ;* Set clock control registers   *
    ;****************************************************
    ldr r0,=LOCKTIME
    ldr r1,=800     ; count = t_lock * Fin (t_lock=200us, Fin=4MHz) = 800
    str r1,[r0]

    [ PLLONSTART
 ldr r0,=PLLCON   ;temporary setting of PLL
 ldr r1,=((M_DIV  <  <12)+(P_DIV  <  <4)+S_DIV) ;Fin=10MHz,Fout=40MHz
 str r1,[r0]
    ]

    ldr     r0,=CLKCON   
    ldr     r1,=0x7ff8     ;All unit block CLK enable 
    str     r1,[r0]

    ;****************************************************
    ;* Set memory control registers   *  
    ;****************************************************
    ldr     r0,=SMRDATA
    ldmia   r0,{r1-r13}
    ldr     r0,=0x01c80000  ;BWSCON Address
    stmia   r0,{r1-r13}

    ;****************************************************
    ;* Initialize stacks    * 
    ;****************************************************
    ldr     sp, =SVCStack ;Why?
    bl     InitStacks

    ;****************************************************
    ;* Setup IRQ handler    *
    ;****************************************************
    ldr     r0,=HandleIRQ  ;This routine is needed
    ldr     r1,=IsrIRQ   ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
    str     r1,[r0]

    ;********************************************************
    ;* Copy and paste RW data/zero initialized data     *
    ;********************************************************
    LDR     r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
    LDR     r1, =|Image$$RW$$Base| ; and RAM copy
    LDR     r3, =|Image$$ZI$$Base| 
 ;Zero init base =>   top of initialised data
   
    CMP     r0, r1     ; Check that they are different
    BEQ     %F1
0  
    CMP     r1, r3     ; Copy init data
    LDRCC   r2, [r0], #4    ;-->   LDRCC r2, [r0] + ADD r0, r0, #4   
    STRCC   r2, [r1], #4    ;-->   STRCC r2, [r1] + ADD r1, r1, #4
    BCC     %B0
1  
    LDR     r1, =|Image$$ZI$$Limit| ; Top of zero init segment
    MOV     r2, #0
2  
    CMP     r3, r1     ; Zero init
    STRCC   r2, [r3], #4
    BCC     %B2

    [ :LNOT:THUMBCODE
 BL Main     ;Don't use main() because ......
 B .      
    ]

    [ THUMBCODE      ;for start-up code for Thumb mode
 orr     lr,pc,#1
 bx      lr
 CODE16
 bl      Main     ;Don't use main() because ......
 b       .
 CODE32
    ]
    
    

;****************************************************
;* The function for initializing stack     *
;****************************************************
InitStacks
 ;Don't use DRAM,such as stmfd,ldmfd......
 ;SVCstack is initialized before
 ;Under toolkit ver 2.50, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'

    mrs     r0,cpsr
    bic     r0,r0,#MODEMASK
    orr     r1,r0,#UNDEFMODE|NOINT
    msr     cpsr_cxsf,r1  ;UndefMode
    ldr     sp,=UndefStack
 
    orr     r1,r0,#ABORTMODE|NOINT
    msr     cpsr_cxsf,r1       ;AbortMode
    ldr     sp,=AbortStack

    orr     r1,r0,#IRQMODE|NOINT
    msr     cpsr_cxsf,r1       ;IRQMode
    ldr     sp,=IRQStack
 
    orr     r1,r0,#FIQMODE|NOINT
    msr     cpsr_cxsf,r1       ;FIQMode
    ldr     sp,=FIQStack

    bic     r0,r0,#MODEMASK|NOINT
    orr     r1,r0,#SVCMODE
    msr     cpsr_cxsf,r1       ;SVCMode
    ldr     sp,=SVCStack

 ;USER mode is not initialized.
    mov     pc,lr ;The LR register may be not valid for the mode changes.

;****************************************************
;* The function for entering power down mode   *
;****************************************************
;void EnterPWDN(int CLKCON);
EnterPWDN
    mov     r2,r0               ;r0=CLKCON
    ldr     r0,=REFRESH  
    ldr     r3,[r0]
    mov     r1, r3
    orr     r1, r1, #0x400000   ;self-refresh enable
    str     r1, [r0]

    nop     ;Wait until self-refresh is issued. May not be needed.
    nop     ;If the other bus master holds the bus, ...
    nop     ; mov r0, r0
    nop
    nop
    nop
    nop

;enter POWERDN mode
    ldr     r0,=CLKCON
    str     r2,[r0]

;wait until enter SL_IDLE,STOP mode and until wake-up
    mov     r0,#0xff
0   subs    r0,r0,#1
    bne     %B0

;exit from DRAM/SDRAM self refresh mode.
    ldr     r0,=REFRESH
    str     r3,[r0]
    
    mov     pc,lr

    LTORG

SMRDATA DATA
;*****************************************************************
;* Memory configuration has to be optimized for best performance *
;* The following parameter is not optimized.                     *
;*****************************************************************

;*** memory access cycle parameter strategy ***
; 1) Even FP-DRAM, EDO setting has more late fetch point by half-clock
; 2) The memory settings,here, are made the safe parameters even at 66Mhz.
; 3) FP-DRAM Parameters:tRCD=3 for tRAC, tcas=2 for pad delay, tcp=2 for bus load.
; 4) DRAM refresh rate is for 40Mhz. 

   
 DCD 0x11110090 ;Bank0=OM[1:0], Bank1~Bank7=16bit, bank2=8bit;
  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)+(Trc  <  <18)+(Tchr  <  <16)+REFCNT) ;REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019
 DCD 0x16    ;SCLK power mode, BANKSIZE 32M/32M
 DCD 0x20   ;MRSR6 CL=2clk
 DCD 0x20   ;MRSR7

 ALIGN


 AREA RamData, DATA, READWRITE

 ^ (_ISR_STARTADDRESS-0x500)
    
UserStack # 256 ;c1(c7)ffa00
SVCStack # 256 ;c1(c7)ffb00
UndefStack # 256 ;c1(c7)ffc00
AbortStack # 256 ;c1(c7)ffd00
IRQStack # 256 ;c1(c7)ffe00
FIQStack # 0 ;c1(c7)fff00


  ^ _ISR_STARTADDRESS
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4

;Don't use the label 'IntVectorTable',
;because armasm.exe cann't recognize this label correctly.
;the value is different with an address you think it may be.
;IntVectorTable
HandleADC # 4
HandleRTC # 4
HandleUTXD1 # 4
HandleUTXD0 # 4
HandleSIO # 4
HandleIIC # 4
HandleURXD1 # 4
HandleURXD0 # 4
HandleTIMER5 # 4
HandleTIMER4 # 4
HandleTIMER3 # 4
HandleTIMER2 # 4
HandleTIMER1 # 4
HandleTIMER0 # 4
HandleUERR01 # 4
HandleWDT # 4
HandleBDMA1 # 4
HandleBDMA0 # 4
HandleZDMA1 # 4
HandleZDMA0 # 4
HandleTICK # 4
HandleEINT4567 # 4
HandleEINT3 # 4
HandleEINT2 # 4
HandleEINT1 # 4
HandleEINT0 # 4   ;0xc1(c7)fff84

  END

  
2楼:quqw 2009年4月11日17:08
 解决了
已经解决。原因是外部中断4567有两个寄存器来控制中断是否发生。extintpnd和intpnd,并且extintpnd会影响intpnd,两个都要清除后才能退出中断。
  
3楼:fushiqi 2009年4月15日10:42
 [建议]三星S3C6410开发板、S3C2450开发板隆重上市!
三星S3C6410开发板、S3C2450开发板隆重上市!
史上做工最精致、性价比最高的6410开发板、支持h264、h263、mpeg4、vc1硬件解码,2D、3D硬件加速
VGA、TV-out、Wifi、Camera、支持SD卡升级。
联系电话:0755-86217140
QQ:519876654,MSN:seeky@hotmail.com
联系人:符先生,深圳友坚恒天科技

>>>>>>对该主题发表你的看法

本主题贴数3,分页: [第1页]


[上一篇主题]:金典课程—亚嵌《DSP6000高级实验班》--免费送3000元课程

[下一篇主题]:关于汇编与C的融合[求助]