ATiny45 vs. INT0 nach sleep

Gast #3585008
Lesenswert?

Hallo zusammen,

mein von einem ATMega8 portierter Code sorgt aus einem AT45 für 
Probleme, der sleep wird direkt wieder verlassen, insofern ich den INT0 
freigebe (ist hier auskodiert und dann geht er sauber auf 70uA runter). 
Wieso?

  if(mode==5 || off==1) {

    PORTB = 0x00000001;      // Alle Ausgänge aus, unbenötigte Pull-ups 
aus
  off=0;

  MCUCR |= 0b00001000;    // Sleep Mode PWR_DOWN setzen + Enable
  //GIMSK |= 0b01000000;        // Externen Interrupt INT0 freigeben

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_mode();        // Enter Sandman ...zzzZZZ

  GIMSK &= 0b10111111;    // Externen Interrupt INT0 sperren
  PORTB = 0x00010001;      // PortB wieder konfigurieren

  mode=1;

  }

Danke & Gruß, Klaus.
Gast #3585046
Lesenswert?

Ratlosigkeit. Laut Datenblatt ist das doch ein lowlevel INT0 Interrupt, 
der den sleep beendet? Aber selbst wenn ich INT0 auf VCC lege, geht er 
sofort wieder aus dem sleep. Setze ich GIMSK komplett auf 0x00, bleibt 
er brav im sleep (ist dann aber natürlich nicht mehr weckbar).

Nun, vll schlafe ich eine Nacht drüber...

Klaus.
Gast #3585085
Lesenswert?

OK, beim Freigeben des INT0 wird die ISR angesprungen und dann schlafen 
gegangen - wieso bitte springt der in die ISR, wenn man den I freigibt? 
Hab ich da beim AT45 was übersehen?

Aktuell:

  if(mode==5 || off==1) {


  PORTB = 0b00000001;      // Alle Ausgänge aus, unbenötigte Pull-ups 
aus
  off=0;

  _delay_ms(500);

  MCUCR &= 0b11111100;    // Low Level Interrupt
  MCUCR |= 0b00010000;    // Sleep Mode PWR_DOWN
  GIMSK |= 0b01000000;        // Externen Interrupt INT0 freigeben

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_mode();        // Enter Sandman ...zzzZZZ

  GIMSK &= 0b10111111;    // Externen Interrupt INT0 sperren
  PORTB = 0b00010001;      // PortB wieder konfigurieren

  mode=1;

  }

Klaus.
(Firma: matzetronics) #3585135
Lesenswert?

Es ist gute Praxis, wenn du den IRQ nach dem Freigeben nochmal löschst, 
um etwaige anstehende Requests zu eliminieren:
1
GIMSK |= (1 << INT0);   // ext. irq  
2
GIFR |= (1 << INTF0);  // clear pendings
3

4
// and now we are ready to enter the sleep mode.
Es kann übrigens sinnvoll sein, besser einen Pinchange Interrupt zu 
nehmen und auf eine Flanke zu warten statt auf low. Pinchange Interrupts 
brauchen dafür auch im Gegensatz zu INT0 keine laufende I/O Clock.
Gast #3585215
Lesenswert?

Flohzirkus, meine Rettung.

Ich Volldödel hab die ganze Zeit an PCINT0 rumgepegelt, der Taster war 
einfach nur falsch angeschlossen. Nun, bin ich wenigstens doch nicht zu 
doof funktionierenden Code zu schreiben, nein, es geht schon bei viel 
banaleren Dingen los :)

Danke & Gruß, ich hol jetzt mal Brötchen... :)

Klaus.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren