Forum: Compiler & IDEs Eclipse LPC2119 Interrupts


von Sebastian H. (rs2)


Lesenswert?

Sers,

ich programmiere mit Eclipse und habe ein kleines Problem mit Interrupts 
beim LPC2119.

Ziel:
Wenn an P0.16 ein High-Signal anliegt, soll mittels ISR eine LED zum 
Leuchten gebracht werden.

Klingt erstmal einfach, aber ich krieg es leider nicht zum laufen.
LED funktioniert definitv!

1
#include "lpc21xx_keil.h"
2
3
void IRQ_Routine (void) __attribute__ ((interrupt("IRQ")));
4
5
void IRQ_Routine(void)         // for external interrupt 0
6
{
7
  VICIntEnClr = 0x00004000;    // Disable EINT0 in the VIC
8
9
  IOCLR0 |= (1<<21);           // LED on
10
11
  EXTINT = 0x01;               // Clear the peripheral interrupt flag
12
  VICIntEnable = 0x00004000;   // Enable EINT0 in the VIC
13
  VICVectAddr = 0;             // reset VIC
14
}
15
16
int main (void)
17
{
18
  MAMCR = 0x02;
19
  VPBDIV = 0x01;               // VPB clock = CPU clock
20
21
  IODIR0 |= (1<<21);
22
  IOSET0 |= (1<<21);           // LED off
23
24
  PINSEL1 |= 0x00000001;       // P0.16 as EINT0 interrupt pin
25
  VPBDIV = 0;                  // set peripheral clock to system clock
26
  EXTMODE = 0x00;              // EINT0 is level-sensitive
27
28
  VICVectAddr0 = (unsigned int) &IRQ_Routine;
29
  EXTINT = 0x01;               // Clear the peripheral interrupt flag
30
  VICVectCntl0 = 0x2E;         // Channel0 on Source#14 ... enabled
31
  VICIntEnable = 0x00004000;   // 14th bit is EINT0
32
33
  while (1) {
34
35
  }
36
}

Weiß jemand, wo der Fehler liegt?

Viele Grüße

Sebastian

von Mark .. (mork)


Lesenswert?

1. Es wurden keine Interrupts aktiviert.
2. IO0SET und IO0CLR muss man direkt beschreiben und nicht ver-ODERn, 
also z.b.
1
 IOSET0 = (1<<21);
 statt
1
 IOSET0 |= (1<<21);
 usw.
3. Welchen Start-Up Code benutzt du?

MfG Mark

von Sebastian H. (rs2)


Lesenswert?

Danke für die schnelle Antwort. "verodern" funktioniert auch, daran 
liegt es nicht.

Hier ist der Start-Up-Code


        .global main                    // int main(void)

        .global _etext                  // -> .data initial values in 
ROM
        .global _data                   // -> .data area in RAM
        .global _edata                  // end of .data area
        .global __bss_start             // -> .bss area in RAM
        .global _bss_end_             // end of .bss area
        .global _stack                  // top of stack

// Stack Sizes
        .set  UND_STACK_SIZE, 0x00000004
        .set  ABT_STACK_SIZE, 0x00000004
        .set  FIQ_STACK_SIZE, 0x00000004
        .set  IRQ_STACK_SIZE, 0X00000080
        .set  SVC_STACK_SIZE, 0x00000004

// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
        .set  MODE_USR, 0x10            // User Mode
        .set  MODE_FIQ, 0x11            // FIQ Mode
        .set  MODE_IRQ, 0x12            // IRQ Mode
        .set  MODE_SVC, 0x13            // Supervisor Mode
        .set  MODE_ABT, 0x17            // Abort Mode
        .set  MODE_UND, 0x1B            // Undefined Mode
        .set  MODE_SYS, 0x1F            // System Mode

        .equ  I_BIT, 0x80               // when I bit is set, IRQ is 
disabled
        .equ  F_BIT, 0x40               // when F bit is set, FIQ is 
disabled

        .text
        .code 32
        .align 2

        .global _boot
        .func   _boot
_boot:

// Runtime Interrupt Vectors
// -------------------------
Vectors:
        b     _start                    // reset - _start
        ldr   pc,_undf                  // undefined - _undf
        ldr   pc,_swi                   // SWI - _swi
        ldr   pc,_pabt                  // program abort - _pabt
        ldr   pc,_dabt                  // data abort - _dabt
        nop                             // reserved
        ldr   pc,[pc,#-0xFF0]           // IRQ - read the VIC
        ldr   pc,_fiq                   // FIQ - _fiq

#if 0
// Use this group for production
_undf:  .word _reset                    // undefined - _reset
_swi:   .word _reset                    // SWI - _reset
_pabt:  .word _reset                    // program abort - _reset
_dabt:  .word _reset                    // data abort - _reset
_irq:   .word _reset                    // IRQ - _reset
_fiq:   .word _reset                    // FIQ - _reset

#else
// Use this group for development
_undf:  .word __undf                    // undefined
_swi:   .word __swi                     // SWI
_pabt:  .word __pabt                    // program abort
_dabt:  .word __dabt                    // data abort
_irq:   .word __irq                     // IRQ
_fiq:   .word __fiq                     // FIQ

__undf: b     .                         // undefined
__swi:  b     .                         // SWI
__pabt: b     .                         // program abort
__dabt: b     .                         // data abort
__irq:  b     .                         // IRQ
__fiq:  b     .                         // FIQ
#endif
        .size _boot, . - _boot
        .endfunc


// Setup the operating mode & stack.
// ---------------------------------
        .global _start, start, _mainCRTStartup
        .func   _start

_start:
start:
_mainCRTStartup:

// Initialize Interrupt System
// - Set stack location for each mode
// - Leave in System Mode with Interrupts Disabled
// -----------------------------------------------
        ldr   r0,=_stack
        msr   CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
        mov   sp,r0
        sub   r0,r0,#UND_STACK_SIZE
        msr   CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
        mov   sp,r0
        sub   r0,r0,#ABT_STACK_SIZE
        msr   CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
        mov   sp,r0
        sub   r0,r0,#FIQ_STACK_SIZE
        msr   CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
        mov   sp,r0
        sub   r0,r0,#IRQ_STACK_SIZE
        msr   CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
        mov   sp,r0
        sub   r0,r0,#SVC_STACK_SIZE
        msr   CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
        mov   sp,r0

// Copy initialized data to its execution address in RAM
// -----------------------------------------------------
#ifdef ROM_RUN
        ldr   r1,=_etext                // -> ROM data start
        ldr   r2,=_data                 // -> data start
        ldr   r3,=_edata                // -> end of data
1:      cmp   r2,r3                     // check if data to move
        ldrlo r0,[r1],#4                // copy it
        strlo r0,[r2],#4
        blo   1b                        // loop until done
#endif
// Clear .bss
// ----------
        mov   r0,#0                     // get a zero
        ldr   r1,=__bss_start           // -> bss start
        ldr   r2,=__bss_end__           // -> bss end
2:      cmp   r1,r2                     // check if data to clear
        strlo r0,[r1],#4                // clear 4 bytes
        blo   2b                        // loop until done

/*
   Call C++ constructors (for objects in "global scope")
   ctor loop added by Martin Thomas 4/2005
   based on a Anglia Design example-application for ST ARM
*/

    LDR   r0, =__ctors_start__
    LDR   r1, =__ctors_end__
ctor_loop:
    CMP   r0, r1
    BEQ   ctor_end
    LDR   r2, [r0], #4
    STMFD   sp!, {r0-r1}
    MOV   lr, pc
    MOV   pc, r2
    LDMFD   sp!, {r0-r1}
    B     ctor_loop
ctor_end:

// Call main program: main(0)
// --------------------------
        mov   r0,#0                     // no arguments (argc = 0)
        mov   r1,r0
        mov   r2,r0
        mov   fp,r0                     // null frame pointer
        mov   r7,r0                     // null frame pointer for thumb
        ldr   r10,=main
        mov   lr,pc
        bx    r10                       // enter main()

/* "global object"-dtors are never called and it should not be
   needed since there is no OS to exit to. */

        .size   _start, . - _start
        .endfunc

        .global _reset, reset, exit, abort
        .func   _reset
_reset:
reset:
exit:
abort:
#if 0
// Disable interrupts, then force a hardware reset by driving P23 low
// -------------------------------------------------------------------
        mrs   r0,cpsr                   // get PSR
        orr   r0,r0,#I_BIT|F_BIT        // disable IRQ and FIQ
        msr   cpsr,r0                   // set up status register

        ldr   r1,=(PS_BASE)             // PS Base Address
        ldr   r0,=(PS_PIO)              // PIO Module
        str   r0,[r1,#PS_PCER_OFF]      // enable its clock
        ldr   r1,=(PIO_BASE)            // PIO Base Address
        ldr   r0,=(1<<23)               // P23
        str   r0,[r1,#PIO_PER_OFF]      // make sure pin is contolled by 
PIO
        str   r0,[r1,#PIO_CODR_OFF]     // set the pin low
        str   r0,[r1,#PIO_OER_OFF]      // make it an output
#endif
        b     .                         // loop until reset

        .size _reset, . - _reset
        .endfunc

        .end

von Mark .. (mork)


Lesenswert?

Der StartUp-Code sollte passen. Was passiert, wenn Du Interrupts 
aktivierst?

>verodern" funktioniert auch [...]

Ist aber trotzdem falsch, siehe Datenblatt.

MfG Mark

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

C-Code nicht durchgeschaut. Aber betr. Interrups: Wie schon von Mark 
geschrieben: aktivieren. Es steht doch im Kommentar, dass sie 
deaktiviert sind. Testweise:
1
// vorher:
2
// ...
3
// - Leave in System Mode with Interrupts Disabled
4
//...
5
        msr   CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
6
//...
7
8
// nachher:
9
// ...
10
// - Leave in System Mode with Interrupts Enabled
11
//...
12
        msr   CPSR_c,#MODE_SYS // System Mode
13
//...

von Sebastian H. (rs2)


Lesenswert?

@Mark: Ja, Du hast recht "verodern" ist an der Stelle nicht korrekt, 
verwende jetzt nur noch "=".

@Thomas: Thx, funktioniert!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.