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]
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.