Forum: Mikrocontroller und Digitale Elektronik XMEGA externer Interrupt


von Alex B. (Gast)


Lesenswert?

Hallo,

ich möchte bei meinem XMEGA128A1 (AVR Studio 4, GNU C, STK600) einen 
externen Interrupt über PORTB Pin0 auslösen.
Hier mein Code

uint8_t temp;
int main(void)
{

  // internen Oszillator auf 32MHZ einstellen
  OSC.CTRL = 3;
  while(OSC.STATUS != 3)
  {
  }
  CCP = 0xD8;
  CLK.CTRL = 1;

  temp = 255;

  // Interrupts aktivieren und alle Level freigeben
  sei();
  PMIC.CTRL=0x07;

  //LEDS initialisieren
  PORTA.DIR = 0xFF;
  PORTA.OUT = 0xFF;

  //TASTER initialisieren
  PORTB.DIR = 0x00;
  //Interrupt Level an PORTB festlegen
  PORTB.INTCTRL = 0x03;
  //Interrupt an PORTB PIN0 freigeben
  PORTB.INT0MASK = 0x01;

  while(1)
  {
  }

}

ISR (PORTB_INTFLAGS_INT0IF)
{
  if (temp > 0)
  {
    temp--;
    PORTA.OUT = temp;
  }
  else
  {
    temp = 255;
  }
}

Das Interrupt Flag INT0IF wird auch gesetzt, aber die ISR wird nicht 
gestartet.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Interruptvektor?

von Alex B. (Gast)


Lesenswert?

Jo, ist mir auch gerade aufgefallen und hab ich geändert

ISR (PORTB_INT0_vect)
{
  if (temp > 0)
  {
    temp--;
    PORTA.OUT = temp;
  }
  else
  {
    temp = 255;
  }
}

Läuft aber leider trotzdem noch nicht

von Alex B. (Gast)


Lesenswert?

Ich gehe mal davon aus, dass die Initialisierung des Port-Interrupts 
noch nicht ganz stimmt. Für Tips wäre ich sehr dankbar.

von Alex B. (Gast)


Lesenswert?

Muss ich PORTB als Eingang konfigurieren, damit ich an ihm einen 
externen Interrupt empfangen kann?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Du hast noch vergessen, bei welcher Flanke der Interrupt triggern soll.

Register: PORTB_PIN0CTRL

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

>Muss ich PORTB als Eingang konfigurieren, damit ich an ihm einen
>externen Interrupt empfangen kann?

Ja. Sonst kannst Du nur Interrupts detektieren, die die Firmware selbst 
auf den Pin schreibt.

von Alex B. (Gast)


Lesenswert?

OK, jetzt sieht die Initialisierung folgendermaßen aus:

//TASTER initialisieren
PORTB.DIR = 0x00;
//Interrupt Level an PORTB festlegen
PORTB.INTCTRL = 0x03;
//Interrupt an PORTB PIN0 freigeben
PORTB.INT0MASK = 0x01;
//Interrupt auf fallende Flanke einstellen
PORTB.PIN0CTRL = 0x02;

Aber leider gehts immer noch nicht und ich glaub auch nicht, dass das 
der Grund gewesen sein könnte, da das Register ja standardmäßig auf 0x00 
steht und damit sowohl auf fallende als auch auf steigende Flanke 
reagiert werden sollte.

von Re T. (toobatch)


Lesenswert?

hatte gerade  ähnliches Problem ...

hatte nur die
1
#include<avr\interrupt.h>

vergessen ... der compiler hat weiter nicht gemeckert ... aber die 
Sprungadresse hat nicht gepasst.

also mal überprüfen ob du die zeile drinne hast

von Alex B. (Gast)


Lesenswert?

Jo, die hab ich drinne und natürlich auch avr\io.h ;-)

von Alex B. (Gast)


Lesenswert?

Müssen die Initialisierungen vielleicht in einer bestimmten Reihenfolge 
vorgenommen werden?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Der Interruptcontroller muß vor dem 'SEI' initialisiert sein.

von Alex B. (Gast)


Angehängte Dateien:

Lesenswert?

Ok, danke, das ist gut zu wissen. Da kommt dann wohl auch mal wieder 
durch, dass ich blutiger Anfänger bin.

Jetzt hab ich aber noch in meinem Programm nen Timer am laufen. Und 
eigenartigerweise funktioniert der externe Interrupt nur, wenn ich den 
Timer rauslasse. Sobald ich den Timer initialisiere funktioniert der 
externe Interrupt nicht mehr.

von Alex B. (Gast)


Lesenswert?

Aber auch die ISR die durch den Timer-Interrupt aktiviert werden soll 
läuft nicht. Scheinbar scheinen sich die beiden Interrupts irgendwie 
gegenseitig zu stören.

von Re T. (toobatch)


Lesenswert?

guck doch mal im  avr simulator (disassembler) deines Programms nach wo 
die sprünge von der IRQ-Tabelle aus hingehen ...  ob das ungefähr was er 
an der sprungadresse tut - mit deinem dort auszuführenden aufgaben in 
der ISR zusammenhängen kann ... oder ob er sonstwo hinspringt.

von Alex B. (Gast)


Lesenswert?

Fehler gefunden: Ich hatte in der ISR des Timers das _vect bei ISR 
(TCC0_OVF_vect) vergessen. Daher konnte natürlich die Timer ISR nicht 
laufen. Warum dadurch aber auch die ISR des externen Interrupts nicht 
lief ist mir trotzdem ein Rätsel. Aber jetzt läufts.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Bis auf die wenigen dokumentierten Errata macht der Controller alles 
richtig ;-). Zum Glück helfen Datenblatt und Manual. Man muß aber recht 
viel hin- und herblättern.

von Alex B. (Gast)


Lesenswert?

Das viele hin- und herblättern ist auch das, was einem Anfänger wie mir 
zu schaffen macht. Es ist halt gar nicht so einfach, zu selektieren 
welche Infos gerade wichtig sind und welche nicht. Und an was man alles 
gerade denken muss.

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.