Forum: Mikrocontroller und Digitale Elektronik LPC2478 Interrupt


von ARMer USER (Gast)


Lesenswert?

Hallo zusammen,
ich verwende folgende Hard- und Software:
LPC2478-STK Board von Olimex
Crossworks 2.0

Mein Ziel: Einen angeschlossenen Taster (Port2 Pin19) drücken, dadurch 
einen Interrupt auslösen und eine LED ausschalten, die vorher in der 
Hautschleife eingeschaltet wurde.

Bisher gelesen:
Fast alle Beiträge hier im Forum. Hitex Books Datasheet des µC.

Wie weit bin ich:
Intialisierung:
Für diesen Pin ist wohl der EINT3 zuständig. Ich initialisiere 
VICIntSelect, VICVectAddr17, VICVectPriority17, VICIntEnable. Und lösche 
das I-Bit im CPSR
mit ctl_global_interrupts_enable(); (ging für mich jetzt am 
Schnellsten).


Was funktioniert bisher:
Das beschreiben der Reister.
Die LED geht an. :-)
Wenn ich die Taste drücke, wird das in VICRawIntr und in VICFIQStatus 
angezeigt. Nach dem Loslassen, bleibt das so.
Nun, das war es. Kein Sprung oder sonst etwas.

Ich schätze, dass es am Namen der ISR liegt??? Aber das ist nur so ein 
Gefühl.
Könnte da bitte mal jemand drüber schauen?

Vielen Dank im Voraus!



Mein Code:
[c]
#include <targets/LPC2478.h>
#include <ctl_api.h>


void fiq_handler(void);


//  LED (yellow  pin 66 P1[18]
//
//  button with BUT1 pin 67  P2[19]


#define LED   (1<<18) // Port 1
#define Taste (1<<19) // Port 2
#define GPIOM 0       // Diese Bit schaltet im Register SCS die FIOPORTs 
frei
#define EINT3  (1<<17)


int main (void)
{
  SCS = (1<<GPIOM);
  FIO1DIR= LED;

  IO2IntEnF = Taste;
  VICIntSelect = EINT3;
  VICVectAddr17 = (unsigned long) fiq_handler;
  VICVectPriority17 = 0;
  VICIntEnable = EINT3;
  ctl_global_interrupts_enable();

  for(;;)
  {
      FIO1CLR= LED;
  }
}

void fiq_handler(void)
{
  FIO1SET= LED;
}
[\c]

Mein Startup-Code (Crossworks):

[c]
/*********************************************************************** 
******
 *                           Preprocessor Definitions
 *                           ------------------------
 *
 * VECTORED_IRQ_INTERRUPTS
 *
 *   Enable vectored IRQ interrupts. If defined, the PC register will be 
loaded
 *   with the contents of the VICVectAddr register on an IRQ exception.
 *
 * STARTUP_FROM_RESET
 *
 *   If defined, the program will startup from power-on/reset. If not 
defined
 *   the program will just loop endlessly from power-on/reset.
 *
 *   This definition is not defined by default on this target because 
the
 *   debugger is unable to reset this target and maintain control of it 
over the
 *   JTAG interface. The advantage of doing this is that it allows the 
debugger
 *   to reset the CPU and run programs from a known reset CPU state on 
each run.
 *   It also acts as a safety net if you accidently download a program 
in FLASH
 *   that crashes and prevents the debugger from taking control over 
JTAG
 *   rendering the target unusable over JTAG. The obvious disadvantage 
of doing
 *   this is that your application will not startup without the 
debugger.
 *
 *   We advise that on this target you keep STARTUP_FROM_RESET undefined 
whilst
 *   you are developing and only define STARTUP_FROM_RESET when 
development is
 *   complete.
 *
 * SRAM_EXCEPTIONS
 *
 *   If defined, enable copying and re-mapping of interrupt vectors from 
User
 *   FLASH to SRAM. If undefined, interrupt vectors will be mapped in 
User
 *   FLASH.
 *
 ************************************************************************ 
*****/

#include <targets/LPC2000.h>

  .section .vectors, "ax"
  .code 32
  .align 0
  .global _vectors
  .global reset_handler

/*********************************************************************** 
******
 * Exception Vectors 
*
 ************************************************************************ 
*****/
_vectors:
  ldr pc, [pc, #reset_handler_address - . - 8]  /* reset */
  ldr pc, [pc, #undef_handler_address - . - 8]  /* undefined instruction 
*/
  ldr pc, [pc, #swi_handler_address - . - 8]    /* swi handler */
  ldr pc, [pc, #pabort_handler_address - . - 8] /* abort prefetch */
  ldr pc, [pc, #dabort_handler_address - . - 8] /* abort data */
#ifdef VECTORED_IRQ_INTERRUPTS
  .word 0xB9206E58                              /* boot loader checksum 
*/
  ldr pc, [pc, #-0x120]                         /* irq handler */
#else
  .word 0xB8A06F60                              /* boot loader checksum 
*/
  ldr pc, [pc, #irq_handler_address - . - 8]    /* irq handler */
#endif
  ldr pc, [pc, #fiq_handler_address - . - 8]    /* fiq handler */

reset_handler_address:
#ifdef STARTUP_FROM_RESET
  .word reset_handler
#else
  .word reset_wait
#endif
undef_handler_address:
  .word undef_handler
swi_handler_address:
  .word swi_handler
pabort_handler_address:
  .word pabort_handler
dabort_handler_address:
  .word dabort_handler
#ifndef VECTORED_IRQ_INTERRUPTS
irq_handler_address:
  .word irq_handler
#endif
fiq_handler_address:
  .word fiq_handler

  .section .init, "ax"
  .code 32
  .align 0

/*********************************************************************** 
*******
 * 
*
 * Default exception handlers 
*
 * 
*
 ************************************************************************ 
******/
reset_handler:
#ifdef __FLASH_BUILD
  bl _configure
#endif

#if defined(SRAM_EXCEPTIONS)
  /* Copy exception vectors into SRAM */
  mov r8, #0x40000000
  ldr r9, =_vectors
  ldmia r9!, {r0-r7}
  stmia r8!, {r0-r7}
  ldmia r9!, {r0-r6}
  stmia r8!, {r0-r6}

  /* Re-map interrupt vectors from SRAM */
  ldr r0, =SCB_BASE
  mov r1, #2 /* User RAM Mode. Interrupt vectors are re-mapped from SRAM 
*/
  str r1, [r0, #MEMMAP_OFFSET]
#endif /* SRAM_EXCEPTIONS */

  b _start

#ifndef STARTUP_FROM_RESET
reset_wait:
  b reset_wait
#endif

/*********************************************************************** 
*******
 * 
*
 * Default exception handlers 
*
 * These are declared weak symbols so they can be redefined in user 
code.     *
 * 
*
 ************************************************************************ 
******/
undef_handler:
  b undef_handler

swi_handler:
  b swi_handler

pabort_handler:
  b pabort_handler

dabort_handler:
  b dabort_handler

fiq_handler:
  b fiq_handler

irq_handler:
  b irq_handler

  .weak undef_handler, swi_handler, pabort_handler, dabort_handler, 
fiq_handler, irq_handler
[\c]

von ARMer User (Gast)


Lesenswert?

Hat niemand eine Idee, woran es liegen könnte?

von ARMer USER (Gast)


Lesenswert?

So, nach langem googeln und yahooen, habe ich eine funktionierende 
Lösung gefunden. Ich poste meine Lösung hier, zum einen, dass vielleicht 
doch noch mal einer drüber schaut, der es kann. Zum andern, um einem 
Unwissenden, schneller ans Ziel zu bringen. Den das, so denke ich, ist 
Sinn und Zweck eines Forums.
(Rad erfinden...)
1
#include <targets/LPC2478.h>
2
#include <ctl_api.h>
3
4
5
void irq_Test(void);
6
7
8
//  LED (yellow  pin 66 P1[18]
9
//
10
//  Taste1  pin 67  P2[19]
11
//  Taste2  pin 81  P2[21]
12
13
#define LED   (1<<18) // Port 1
14
#define Taste1 (1<<19) // Port 2
15
#define Taste2 (1<<21) // Port 2
16
#define GPIOM 0       // Diese Bit schaltet im Register SCS die FIOPORTs frei
17
#define EINT3  17
18
19
int main (void)
20
{
21
  SCS = (1<<GPIOM);  // Diese Bit schaltet im Register SCS die FIOPORTs frei
22
  FIO1DIR= LED;     // I/O für die LED als Ausgang schalten
23
 
24
  IO2IntEnF = Taste2 | Taste1;  //  In diesem Register, werden die Pins freigeschaltet, die einen Interrupt an Port2 auslösen können 
25
 
26
   //ctl_set_isr(EINT3, 1, CTL_ISR_TRIGGER_FIXED, irq_Test, 0); // Crosswords Routine. Die folgenden 3 Zeilen, ersetzen diese hier.
27
  VICIntSelect = EINT3; // Hier wird der Interruptkanal für den Pin durchgeschaltet
28
  VICVectAddr17 = (unsigned long) irq_Test; // Hier wird dem Interrupt, die Sprungadresse der ISR bekannt gemacht 
29
  VICVectPriority17 = 1;   // Hier wird die Priorität der Abarbeitung, bei zeitgleichen Interrupts zugewiesen
30
 
31
   //ctl_unmask_isr(EINT3);  //Crosswords Routine. Die folgende Zeile, ersetzt diese hier.
32
  VICIntEnable = 1<<EINT3;  // Hier wird der Interrupt freigeschaltet
33
  
34
  ctl_global_interrupts_enable(); // Hier habe ich nicht ganz verstanden, was passiert, daher "nur" die Crosswords Routine.
35
36
  for(;;)
37
  {
38
     // Warten auf Interrupt
39
  }
40
}
41
42
void irq_Test(void) // Interrupt Routine: Eine Taste schaltet die LED an, die andere aus.
43
{
44
  if(IO2IntStatF &Taste1 )  FIO1SET= LED;  // Hier wird abgefragt, welcher Pin, den Interrupt ausgelöst hat
45
  if(IO2IntStatF &Taste2 )  FIO1CLR= LED;  // Es können ja verschiedene sein, für diese ISR
46
  IO2IntClr = Taste2 | Taste1;            // Zum Abschließen der ISR, die Flags zurücksetzen, sonst wird wieder interruptet
47
}

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.