Forum: Mikrocontroller und Digitale Elektronik ATtiny13A Pin Change Interrupt


von Daniel (Gast)


Lesenswert?

Hi,

ich versuche vergeblich im AtmelStudio 6.1 Simulator einen Pinchange 
Interrupt auszulösen. Mein code:
#include <avr/io.h>

void powerDown(void){
  GIFR |= (1<<PCIF); // Clear eventually occurred previous interrupts
  GIMSK |= (1<<PCIE); // Activate Pin change interrupts
  PINB |= (1<<PB4);
  PINB |= (1<<PB4);
  PINB |= (1<<PB4);
  GIMSK &= (0<<PCIE); // Deactivate Pin change interrupts
}

ISR(PCINT0_vect) {
  PINB |= (1<<PB4);
  PINB |= (1<<PB4);
}

int main(void)
{
  //SREG &= 0B01111111; //Disables Interrupts globally during setup
  PORTB |= (1<<PB0)|(1<<PB1)|(1<<PB2); //Setting outputs to zero, 
activating pullups on inputs
  DDRB |= (1<<PB3)|(1<<PB4)|(1<<PB5); //0, 1, 2 are inputs, 3, 4, 5 are 
outputs

  //GIMSK = (1<<PCIE); // Activate Pin change interrupts
  PCMSK |= (1<<PCINT0)|(1<<PCINT1)|(1<<PCINT2); // Sets the Pin change 
interrupt mask, only PB0,1,2 will trigger the PCINT once it it enabled 
before sleep
    //MCUCR = (1<<ISC00)|(0<<ISC01);

  SREG |= (1<<SREG_I); //Enables Interrupts globally after setup
  while(1)
    {
        //TODO:: Please write your application code
    PINB |= (1<<PB4);
    powerDown();
    }
}


Mit PINB |= (1<<PB4); toggle ich einen Pin, um einfach irgendwas zu 
machen ;) powerDown soll später mal Sleep aktivieren und dann soll der 
Mikro per Pinchange Interrupt wieder aus dem Schlaf zurück geholt 
werden. Sorry für die Wahrscheinlich total einfache Frage, aber ich 
fange gerade erst an mit Mikrocontrollern und kenne mich noch nicht gut 
aus.

Während der drei
PINB |= (1<<PB4);
PINB |= (1<<PB4);
PINB |= (1<<PB4);
ändere ich manuell den State eines der drei Inputs im single Step Modus, 
aber es passiert garnichts und der Code wird weiter normal ausgeführt, 
ohne in die ISR zu springen.

von Daniel (Gast)


Lesenswert?

Also es lag daran, dass ich die avr/interrupt.h nicht included hatte;) 
Jetzt funktioniert es. Eine Sache ist mir jedoch aufgefallen, wenn 
innerhalb von

void powerDown(void){
  GIFR |= (1<<PCIF); // Clear eventually occurred previous interrupts
  GIMSK |= (1<<PCIE); // Activate Pin change interrupts
  PINB |= (1<<PB4);
  PINB |= (1<<PB4);
  PINB |= (1<<PB4);
  GIMSK &= (0<<PCIE); // Deactivate Pin change interrupts
}

bzw während der drei PINB |= (1<<PB4); ein Pin geändert wird, springt 
der Mikro erst beim/nach dem Aufruf von GIMSK &= (0<<PCIE); in die ISR!? 
Ist das normal oder mache ich etwas falsch? Ich dachte Interrupts würden 
wirklich sofort interrupten.

von troll (Gast)


Lesenswert?

>GIMSK &= (0<<PCIE);
Das setzt das gesamte Register auf 0, ist das gewollt? Oder wolltest du 
GIMSK &= ~(1<<PCIE); schreiben?

von Daniel (Gast)


Lesenswert?

Ja, habe ich in der Zwischenzeit auch geändert. Das Verhalten ist aber 
das selbe, da der Rest des Registers eh 0 war. Hatte also nichts mit dem 
komischen Interruptverhalten zu tun.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Daniel schrieb:
> Ist das normal oder mache ich etwas falsch? Ich dachte Interrupts würden
> wirklich sofort interrupten.

Versuch es nach der Initialisierung mal mit einem
sei():

Bin aber noch nicht ganz wach, hoffe, es lag daran... :-)

von Daniel (Gast)


Lesenswert?

Guten Morgen,

SREG |= (1<<SREG_I); //Enables Interrupts globally after setup

sollte das selbe sein, was ein sei macht wenn ich das richtig verstanden 
habe

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Daniel schrieb:
> sollte das selbe sein, was ein sei macht wenn ich das richtig verstanden
> habe

OK, wie ich schon schrieb, ich war noch nicht wach, sorry. :-)

Warum steht das powerDown() eigentlich innerhalb der Hauptschleife?

von Daniel (Gast)


Lesenswert?

Ich will den Code nur testen, deshalb wollte ich eine Möglichkeit die 
PowerDown Funktion manuell aufzurufen ohne auf Timer etc. zu warten.

Also, kann jemand helfen?

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.