AVR Sleep und Button Interrupt

OP #7468415
Lesenswert?
• ▲
▼

Hallo.

Ich hatte einen funktionierenden Code um eine kleine Zusatzfunktion erweitert: Mit einem kleinen Taster sollte geprüft werden können, ob die Akkuspannung unter 3,5 V liegt. Die Änderung war jedoch fehleranfällig und das Aufwachen wurde unzuverlässig.

Nun habe ich den Code so weit wie möglich reduziert und den Fehler gefunden: die Zeile

1
PORTA.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_LEVEL_gc;

muss unmittelbar vor der Anweisung

1
sleep_mode();

stehen.

Aber warum der etwas andere Code nicht funktioniert, verstehe ich immer noch nicht.

Auch habe ich Schwierigkeiten zu erkennen, inwieweit das Prellen den Fehler verursacht, bzw. an welcher Stelle im Code die Entstehung des Fehlers offensichtlich wird.

Außerdem wollte ich fragen, ob hier die Deklaration "volatile" überflüssig ist oder notwendig.

Vielen Dank im Voraus.

(Die Codes im Anhang sind die reduzierten Codes, keine eigenständigen Codes, können daher einen unvernünftigen Eindruck machen.)

Angehängte Dateien:
#7468441
Lesenswert?
• ▲
▼

Schau mal in die "sleep.h": "the sleep_mode() macro might cause race conditions in some situations" Wenn da der Aufwachinterrupt reinhaut, wars das. Nimm besser das sleep_cpu(); wie im Beispiel. Das sleep_disable(); ist Mumptiz und sollte entfallen. Dann reicht auch das sleep_enable(); einmalig im Init-code.

OP #7475165
Lesenswert?
• ▲
▼

Peter D. schrieb:

Schau mal in die "sleep.h": "the sleep_mode() macro might cause race conditions in some situations" Wenn da der Aufwachinterrupt reinhaut, wars das. Nimm besser das sleep_cpu(); wie im Beispiel. Das sleep_disable(); ist Mumptiz und sollte entfallen. Dann reicht auch das sleep_enable(); einmalig im Init-code.

Ich kann auf <avr/sleep.h> komplett verzichten. Aber der Programmfehler wird dadurch nicht behoben. Ich muss den Taster nur noch viel öfter drücken, bis der Fehler auftritt und der Mikrocontroller nicht mehr aufwacht.

#7475186
Lesenswert?
• ▲
▼

Ich muß zugeben, ich seh da nicht durch, wie Du die Taste auswertest.

Ich benutze eine völlig andere Herangehensweise. Der Aufwachinterrupt macht nichts weiter, als nur aufwachen (Empty Interrupt). Das Tasten entprellen erfolgt dann in der üblichen Weise im Timerinterrupt. Das Schlafen gehen wird über ein Flag gesteuert.

Damit auch wirklich kein Aufwachen durch die Lappen geht, wird der Interrupt erst direkt vor dem Sleep enabled und danach sofort wieder disabled. Damit wird garantiert, daß das ein Pin-Change-Interrupt erst nach dem Sleep ausgeführt werden kann bzw. ein erneutes Pin-Change bis zu nächsten Sleep gespeichert bleibt.

Beitrag "Re: AVR Sleep Mode / Knight Rider"

Um welchen AVR geht es eigentlich? Den genauen MC sollte man immer mit angeben.

#7475237
Lesenswert?
• ▲
▼
1
    if(tcb)                                                    // TCB for debouncing without delay
2
    {
3
      if(PORTA.IN & PIN2_bm)                                   // if PA2 button released
4
      {
5
        PORTA.OUTCLR = PIN1_bm;                                // PA1 off
6
        tcb = 0;                                               // clear the flag
7
        indicate = 0;                                          // clear the flag
8
        PORTA.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_LEVEL_gc; // PA2 pull-up, low level sense interrupt
9
* <------------
10
      }
11
    }
12
    if(!indicate)
13
    {
14
* <------------
15
      sleep_mode();
16
    }

Wenn zwischen den markierten Stellen ein Taster-Interrupt auftritt, dann kann der uC nicht mehr aufwachen.

PS: Denn in der ISR wird die Interrupt-Fähigkeit abgeschaltet (im Gegensatz zum 'workable code').

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.