Forum: Compiler & IDEs Externer Interrupt beim ATmega48


von Hugo H. (planetenbepinkler)


Lesenswert?

Hallo zusammen,

ich experimentiere gerade, um diesen Baustein zu verstehen, mit Lampe an 
- Lampe aus. INT0/1 funktionieren. Nun habe ich den Code um den PCINT17 
erweitert -> Resultat ist nieder schmetternd. Ich glaube, ich habe es 
nicht so richtig verstanden.
Hier der Code:

/*
 * Ext_Int.c
 *
 * Created: 01.05.2013 11:14:40
 *  Author: Ich
 */


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <avr/sleep.h>

int Lampe = 0;

ISR(INT0_vect)
{
  PORTB |= (1<<PB0);  // Lampe an
}

ISR(INT1_vect)
{
  PORTB &= ~(1<<PB0);  // Lampe aus
}

ISR(PCIE2)
{
  if Lampe == 0
  (PORTB |= (1<<PB1); Lampe = 1;)  // Lampe an
  if Lampe == 1
  (PORTB &= ~(1<<PB1); Lampe = 0;  // Lampe aus
}

int main(void)
{
  DDRB |= (1<<PB0) | (1<<PB1);  // Pin C0/1 ist Ausgang
  PORTD |= (11<<PD1) | (1<<PD2) | (1<<PD3); // Pull Up Widerstände 
gesetzt

  EICRA |= (1<<ISC11) | (1<<ISC01);  // IT0/1 konfigurieren; fallende 
Flanke
  EIMSK |= (1<<INT0) | (1<<INT1);    // INT0 und INT1 aktivieren
  PCICR |= (1<<PCIE2);        // INT 16-23 erlaubt
  PCMSK2 |= (1<<PCINT17);        // PCINT17 aktivieren
  sei();  // Globaler Interrupt erlauben

    while(1)
    {
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // Einschlafen lassen ;-)
    }
}

Was habe ich falsch gemacht?!

Danke für eure Hinweise.

von J.-u. G. (juwe)


Lesenswert?

Hugo Hugoson schrieb:
> ISR(PCIE2)

Gemäß Datenblatt heißt der Interruptvektor für den Pin-Change-Interrupt2 
"PCINT2".

Beim AVR-GCC muß bei der Definition der ISR an den Namen noch das Suffix 
"_vect" angehängt werden:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts
Also:
1
ISR(PCINT2_vect)
2
{
3
...
4
}

Wurde Deine Version denn überhaupt ohne Fehler- bzw. Warnmeldungen 
kompiliert?

von Stefan E. (sternst)


Lesenswert?

J.-u. G. schrieb:
> Wurde Deine Version denn überhaupt ohne Fehler- bzw. Warnmeldungen
> kompiliert?

1
  if Lampe == 0
2
  (PORTB |= (1<<PB1); Lampe = 1;)  // Lampe an
3
  if Lampe == 1
4
  (PORTB &= ~(1<<PB1); Lampe = 0;  // Lampe aus

Ganz sicher nicht.

von Hugo H. (planetenbepinkler)


Lesenswert?

Danke, jetzt geht's :-)
Mit dem 'if' ist klar ->

ISR(PCINT2_vect)
{
  if (Lampe == 0)
  {
    PORTB |= (1<<PB1);
    Lampe = 1;  // Lampe an
  }
  else
  {
    Lampe = 0;
    PORTB &= ~(1<<PB1);  // Lampe aus
  }
}

Nur noch eine Frage: Wie kann ich die Interrupts in Priroritäten 
staffeln?

von Justus S. (jussa)


Lesenswert?

gar nicht

von Bernd S. (bernds1)


Lesenswert?

Hugo Hugoson schrieb:
> Nur noch eine Frage: Wie kann ich die Interrupts in Priroritäten
> staffeln?

Im Datenblatt ist eine Tabelle, die alle vorhandenen Interrupts 
auflistet. Da kannst du nachschauen. Die sind nach Priorität angeordnet.
Ändern kannst du aber an der Reihenfolge nichts. Die ist durch den 
Prozessor vorgegeben.

von Oliver (Gast)


Lesenswert?

Bernd S. schrieb:
> Da kannst du nachschauen. Die sind nach Priorität angeordnet.

Wobei grundsätzlich erst einmal gilt: First come, first serve.

Wenn du die Interrupts in einer ISR wieder freigibst (was du nur tun 
solltest, wenn du genau weißt, was du tust), unterbricht die jeder 
andere Interrupt, sobald er auftritt.

Die Prioritäten kommen nur zum tragen, wenn mehrere Interrupts 
gleichzeitig anstehen. Dann entscheidet die Priorität, welcher als 
nächstes ausgeführ wird.

Oliver

von Hugo H. (planetenbepinkler)


Lesenswert?

Vielen Dank an alle.
Ihr habt mir sehr geholfen!

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.