Forum: Mikrocontroller und Digitale Elektronik ATiny45 vs. INT0 nach sleep


von Klaus2 (Gast)


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.

von Klaus2 (Gast)


Lesenswert?

Oups, der Bedientaster, der die modes wechselt hängt an INT0...das 
dürfte das Problem sein, er ist quasi in dem Moment noch gedrückt?!

Klaus.

von Klaus2 (Gast)


Lesenswert?

Ne, das wars auch nicht...eine Verzögerung von 500ms nach Eintritt in 
"mode 5" führt zum gleichen Ergebnis. Hmmm...

Klaus.

von Kaj (Gast)


Lesenswert?

Klaus2 schrieb:
> PORTB = 0x00000001;
Du versuchst einen 32bit Wert in ein 8bit register zu schreiben...
Ich nehme einfach mal an das sollte "0b..." heißen und nicht "0x..."

von Klaus2 (Gast)


Lesenswert?

Das lief aufm AT8 auch so :) Nichts desto trotz habe ich auch bereits 
gesehen und pro forma geändert, bringt aber nichts.

Klaus.

von Klaus2 (Gast)


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.

von Klaus2 (Gast)


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.

von Flohzirkus (Gast)


Lesenswert?

Klaus2 schrieb:
>
>   PORTB = 0b00000001;      // Alle Ausgänge aus, unbenötigte Pull-ups aus

Dein Taster hat einen externen Pullup? (INT0 liegt auf PB2)

Schönes Wochenende

von Matthias S. (Firma: matzetronics) (mschoeldgen)


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.

: Bearbeitet durch User
von Klaus2 (Gast)


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.

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.