Forum: Mikrocontroller und Digitale Elektronik AVR32 Interrupt


von Stefan (Gast)


Lesenswert?

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){}
}

von Purzel H. (hacky)


Lesenswert?

Der Tasten Interrupt ... ja doch ...

von Stefan (Gast)


Lesenswert?

Wie soll ich die Antwort verstehen?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Stefan (Gast)


Lesenswert?

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){}
}

von Purzel H. (hacky)


Lesenswert?

>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 {...}

von Stefan (Gast)


Lesenswert?

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){}
}

von Peter D. (peda)


Lesenswert?

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

von Purzel H. (hacky)


Lesenswert?

>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
Noch kein Account? Hier anmelden.