Hallo Ich möchte mit einer Taste die an PA1 angeschlossen ist bei Zustandsänderung ein Interrupt auslösen. In der Interrupt Routine wird der PA2 getoggelt. Kann mir jemand sagen woran es liegt dass es gar nicht in die Interrupt Routine rein springt. Ich hab natürlich bereits bei Google und im Forum nach Beispielen gesucht aber mir Fällt da nichts auf was ich da fasch mache. #include <avr32/io.h> #include "compiler.h" #include "intc.h" __attribute__((_interrupt_)) static void GPIO_int_handler(void) { AVR32_GPIO.port[0].ovrt |= 0x00000004; } int main (void){ int clock = 66; int clockh = (clock/6) - 1; AVR32_PM.oscctrl0 = (AVR32_PM.oscctrl0 | 0x00000407); AVR32_PM.mcctrl = AVR32_PM_OSC0EN_MASK; while((AVR32_PM.poscsr & AVR32_PM_POSCSR_OSC0RDY_MASK)== 0); AVR32_PM.pll[0] = 0 << AVR32_PM_PLLOSC_OFFSET | 1 << AVR32_PM_PLLDIV_OFFSET | clockh << AVR32_PM_PLLMUL_OFFSET | 5 << AVR32_PM_PLLOPT_OFFSET; AVR32_PM.cksel = 0x00000000; AVR32_PM.pll[0] |= AVR32_PM_PLLEN_MASK; while(!(AVR32_PM.poscsr & AVR32_PM_POSCSR_LOCK0_MASK)); AVR32_FLASHC.fcr |= 1 << AVR32_FLASHC_FWS_OFFSET; AVR32_PM.mcctrl |= 2 << AVR32_PM_MCSEL_OFFSET; AVR32_GPIO.port[0].oders |= 0x00000004; // PA02 als Ausgang Definieren AVR32_GPIO.port[0].iers |= 0x00000002; // Interrupt für PA1 Aktivieren Disable_global_interrupt(); INTC_init_interrupts(); INTC_register_interrupt(&GPIO_int_handler, AVR32_GPIO_IRQ_0 + 1/8, AVR32_INTC_INT1; Enable_global_interrupt(); while(1){} }
Stefan schrieb: > Wie soll ich die Antwort verstehen? Such dir irgendeinen Thread hier aus, in dessen Titel "Tasten" und "Interrupt" vorkommen. Gibt ja genug davon.
Liest Ihr überhaupt den Beitrag durch bevor Ihr antwortet. Hab´s doch oben hingeschrieben dass ich bereits in diversen Foren auch hier und bei Google gesucht habe. Und auch viele Beispiele gefunden habe. Aber geholfen hat es nicht. Es sind nur ein paar Zeilen hier die ich aus Examples übernommen und überarbeitet habe. #include <avr32/io.h> #include "compiler.h" #include "intc.h" // Interrupt Routine __attribute__((_interrupt_)) static void GPIO_int_handler(void) { AVR32_GPIO.port[0].ovrt |= 0b00000100; } int main (void){ AVR32_GPIO.port[0].oders |= 0b00000100; // PA02 als Ausgang Definieren AVR32_GPIO.port[0].iers |= 0b00000010; // Interrupt für PA1 Aktivieren Disable_global_interrupt(); INTC_init_interrupts(); INTC_register_interrupt(&GPIO_int_handler, AVR32_GPIO_IRQ_0 + 1/8, AVR32_INTC_INT1); Enable_global_interrupt(); while(1){} }
>Liest Ihr überhaupt den Beitrag durch bevor Ihr antwortet.
Natuerlich nicht. Soll ich alle Register nachschlagen ? Der erste Fehler
ist eine Taste auf einen Interupt zu legen. Damit stehste mit den Hosen
unten da.
Eine Taste wird immer mit dem Timer interrupt gepollt. Und wenn sie
dann 10ms lang stabil ist, ist immer noch frueh genug was damit zu
machen.
Also lass mal einen Timer als 10ms Tick laufen.
interrupt Timer_x
timerreg=timerreload
timercame=1;
Und dann poll mal die Taste, im main().
if timercame==1 {...}
Hi Oschi Danke für deine Empfehlung werde ich auch als nächstes machen. Der Grund dafür dass ich die Taste auf einen Interrupt gelegt habe, ist dass es nur ein Übungsprogramm ist und dient ausschließlich dazu um ein Interrupt auszulösen. Das hätte auch ein Timer sein könne. Aber die Taste war das erste an was ich gedacht habe. Bin jetzt auch ein Stück weiter gekommen. Nach den folgenden Änderungen springt der Programmzeiger in die Interrupt Routine rein. Danach springt es aber nicht an die Stelle wo es unterbrochen wurde sondern an den Anfang an die erste Speicheradresse. Hat vielleicht noch jemand ein Tipp für mich. :-) #include <asf.h> #include "compiler.h" #include "intc.h" __attribute__((_interrupt_)) static void GPIO_int_handler(void) { AVR32_GPIO.port[0].ovrt |= 0x00000004; AVR32_GPIO.port[0].ifrc |= 0x00000002; // return; } int main (void) { Disable_global_interrupt(); INTC_init_interrupts(); int clock = 66; int clockh = (clock/6) - 1; AVR32_PM.oscctrl0 = (AVR32_PM.oscctrl0 | 0x00000407); AVR32_PM.mcctrl = AVR32_PM_OSC0EN_MASK; while((AVR32_PM.poscsr & AVR32_PM_POSCSR_OSC0RDY_MASK)== 0); AVR32_PM.pll[0] = 0 << AVR32_PM_PLLOSC_OFFSET | 1<< AVR32_PM_PLLDIV_OFFSET | clockh << AVR32_PM_PLLMUL_OFFSET | 5 << AVR32_PM_PLLOPT_OFFSET; AVR32_PM.cksel = 0x00000000; AVR32_PM.pll[0] |= AVR32_PM_PLLEN_MASK; while(!(AVR32_PM.poscsr & AVR32_PM_POSCSR_LOCK0_MASK)); AVR32_FLASHC.fcr |= 1 << AVR32_FLASHC_FWS_OFFSET; AVR32_PM.mcctrl |= 2 << AVR32_PM_MCSEL_OFFSET; AVR32_GPIO.port[0].oders |= 0x00000004; // PA02 als Ausgang Definieren INTC_register_interrupt(&GPIO_int_handler, AVR32_GPIO_IRQ_0 + 1/8, AVR32_INTC_INT3); AVR32_GPIO.port[0].iers |= 0x00000002; // Interrupt für PA1 Aktivieren Enable_global_interrupt(); while(1){} }
Ich schätze mal, AVR32 Benutzer werden hier weit unter 1% sein. Und wenn Du nichtmal die Posting-Regeln liest (Formatierung), wird sich von den wenigen auch keiner den Code ansehen. Generell von Vorteil ist allerdings, immer einen kompletten compilierbaren und simulierbaren minimalen Code als Anhang zu posten, der das Problem enthält. Compilieren zeigt oftmals Warnungen, die auf den Fehler hinweisen. Und simulieren geht oftmals schneller als lesen. Gerade bei 32Bit-Boliden, wo erstmal Unmengen zu konfigurieren sind. Peter
>Bin jetzt auch ein Stück weiter gekommen. Nach den folgenden Änderungen
springt der Programmzeiger in die Interrupt Routine rein. Danach
springt es aber nicht an die Stelle wo es unterbrochen wurde sondern an
den Anfang an die erste Speicheradresse. Hat vielleicht noch jemand ein
Tipp für mich. :-)
Ja. die Ruecksprungadresse sollte auf dem Stack liegen. Wo ist der Stack
? Wo wird der initialisiert?
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.