Forum: Mikrocontroller und Digitale Elektronik Interrupt im Idle-Modus und wom Watchdog augeweckt werden


von fred (Gast)


Lesenswert?

Guten Tag,

in einem Projekt von mir mag ich den ATmega88PA in den Idle-Modus 
schicken, leider hab ich noch ein paar Verständnisprobleme.
Erstmal zu ein paar Grundlege Verwendungen vom AVR:

Timer0 schaltet Ports, inkremitiert, vergleicht Variable und endprellt 
tasten -.- (bitte noch nichts sagen). Hier zu habe ich nacher die Frage
Timer1 erzeugt ein PWM-Signal, das er ja auch weiterhin in dem Idle 
macht.
Timer2 läuft asynchron mit 32kHz und setzt nur ein Flag

Die main() besteht im weschentlichen nur aus eine Switch-case-Anweisung. 
In den einzelnen Zuständen werden die Taster abgefragt, um in einen 
anderen Zustand zu wechseln, und sehr selten auch vereinzelt Funktionen 
aufgerufen.
Dieses ständige „sinnlose“ durlaufen der Switch-case wollte ich jetzt 
einen Ende machen!!

Meine Plan: Den Atmega88 in den Idle- Modus zuschicken und ihn alle 3ms 
von Watchdog aufzuwecken.

Meine Frage: Kann der AVR den Timer0-Interrupt so abarbeiten, obwohl die 
CPU und der Flash schläft? Wachen die für den Interrupt wieder auf? Ist 
dieses vorgehen überhaupt sinnvoll?

Timer0-interrupt: jede ms
1
 ISR(TIMER0_COMPA_vect)
2
{  
3
  PORT_ZEILE = 0; // wegen dem glimmen, test
4
  
5
  PORT_SPALTE = (~(1<<(spalte+1))|adc_transitor|spi_cs);  //~(1<<(spalte)<<1)
6
  PORT_ZEILE = daten[spalte];
7
  if(++spalte > 5)
8
    spalte = 0;
9
    
10
  // wacke_up_flag = 1;
11
}

Beispielhafte und unvollständige main:
1
int main(void)
2
{
3
  //Variablen definition
4
  // Port, ADC, Timer, .. Initialisierung
5
  sei();
6
7
while()
8
{
9
    // ADEN-BIT für ADC-enable löschen,
10
    // sonst wird eine neue Messung gestartet
11
    ADCSRA &= ~(1<<ADEN);
12
13
     set_sleep_mode(SLEEP_MODE_IDLE);
14
     sleep_mode();                   // in den Schlafmodus wechseln
15
     
16
     // Aufwachpunkt
17
     if (wacke_up_flag==1)
18
     { 
19
      wacke_up_flag=0;
20
      // ADEN-BIT für ADC-Enable setzten
21
      ADCSRA |= (1<<ADEN);
22
23
     }
24
    
25
    // hier kommt jetzt die Tastenentprellung hin
26
    // und weite kleine Aufgabe die vorher in der ISR waren
27
28
    switch(state)
29
    {
30
      ..
31
    }
32
  } // ende While(1)
33
} // ende main

Würdet ihr die Hauptschleife jede ms mit der ISR von Timer0 aufrufen?
Wie löse ich das Aufwecken vom uC mit dem Watchdog am besten?

Vielen Dank und Grüße
fred

von Carsten R. (kaffeetante)


Lesenswert?

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Power_Management
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Watchdog

Die Idee einen Timer zu verwenden ist genau richtig. Der Watchdog ist 
ein besonderer Timer, der aber für genau das was du vorhast NICHT 
gemacht ist. Der Watchdog arbeitet genau umgekehrt, wie ein Eieruhr. Man 
zieht ihn immer wieder auf, bevor er abläuft, damit er eben nicht 
auslöst. Man hindert ihn also daran etwas zu machen, da alles was er 
kann, ein Reset ist. Wenn der Prozessor hängt, kann man den Watchdog 
nicht zurücksetzen und er läuft ab und startet somit die CPU neu.

fred schrieb:
> Wie löse ich das Aufwecken vom uC mit dem Watchdog am besten?

Die Antwort lautet also: gar nicht. Man nimmt einen der anderen Timer 
dafür.

fred schrieb:
> Würdet ihr die Hauptschleife jede ms mit der ISR von Timer0 aufrufen?


Das hängt ganz davon ab wie schnell die Reaktion erfolgen soll. Im 
Allgemeinen ist das von Dir genannte Intervall eine praktikable 
Auflösung. Größere Intervalle verlangsamen das Programm aber bringen 
kaum zusätzliche Erparnis. Eventuell könnte man die Intervalle noch 
verkürzen.

Zur Realisierung:

Für den Einstieg würde ich einen freien Timer nehmen und in dessen 
Interruptroutine nur ein Return schreiben. Das reicht um aus dem 
IDLE-Sleep zurück zu kehren. Ein Main-Aufruf ist nicht erforderlich. Die 
CPU kehrt aus der ISR zurück und macht direkt mit der nächsten Anweisung 
nach dem Sleep weiter. Der Timer 2 ist allerdings manchmal etwas tricky 
mit einer externen Quelle, wie z.B. einem Uhrenquarz. Es gibt da im 
Datenblatt genaue Anweisungen was zu beachten ist, damit der Timer die 
CPU aus dem Sleep zurückholen kann. Das hängt mit der Implementierung 
des asynchronen Zählwerkes zusammen. Hier ist also Vorsicht und 
besonders genaues Arbeiten angesagt, sonst spielt die CPU Dornröschen 
und nur noch ein Reset hilft.

: Bearbeitet durch User
von fred (Gast)


Lesenswert?

Danke für die schnelle Antwort.

Leider habe ich keinen freien Timer mehr -.-
Aus diesem Grund bin ich auf den Watchdog gekommen um ihn als „Eieruhr“ 
zu missbrauchen. Dabei hätte ich den Watchdog Time-out Interrupt (Vector 
no.6) genommen und die Resetfunktion abgestellt. Ein aufhängen vom 
Programm würde eine externe Hardware erkennen und den AVR über den 
Restpin neu starten.  So würde er alle 16ms meine Main aufrufen.

Leider hab ich noch keine Erfahrung mit dem Sleepmode.
Deshalb die Frage ob eine ISR auch z.B. arithmetische Rechnung während 
des Idle-Mode ausführen kann. Einfach ausprobieren kann ich es noch 
nicht, da die Hardware noch nicht komplett aufgebaut ist.

von Falk B. (falk)


Lesenswert?

@ fred (Gast)

>Leider habe ich keinen freien Timer mehr -.-

Man kann einen Timer für mehrere Dinge nutzen.

Siehe Sleep Mode.

von Carsten R. (kaffeetante)


Lesenswert?

Im verlinkten Artikel findest du alle Interrupts die den den AVR aus dem 
jeweiligen Sleepmodus holen können. Der Timer muß nicht frei sein. Es 
muß nur ein Interrupt sein der regelmäßig genug aufgerufen wird. Ich 
habe nur den freien Timer erwähnt, weil man sich dann aussuchen kann wie 
schnell der Timer läuft, da nicht andere Prozesse mit davon abhängen. 
Hat man keinen freien Timer-Interrupt- so muß man mehrere Funktionen mit 
in der ISR miteineander verheiraten, was aber auch geht. Was die Routine 
macht ist geneu genoen egal. Die CPU kehrt nach dem return zurück und 
setzt das Programm unmittelbat mit dem nächsten Befehl nach dem Sleep 
fort.

Während des Sleep steht die CPU. Berechnungen sind somit nicht möglich. 
Aber man kan die Berechnung vorher starten und am Ende ein Sleep 
einfügen, so daß dann gearbeitet wird bis alles erledigt ist und dann 
wird gschlafen.

von Erwin (Gast)


Lesenswert?

Den Watchdog kann man als Eieruhr nehmen!
=========================================

Allerdings ist das nur möglich, wenn man den Watchdog
nicht auf RESET, sondern auf Watchdog-Interrupt konfiguriert.
In dieser Watchdog-Interrupt-Routine muss das jedesmal
explizit neu mit Setzen von WDIE gemacht werden!

Dies bietet sich an, wenn man z.B. eine Messwerterfassung,
-verarbeitung und -übermittlung nur alle paar Sekunden bis
Minuten machen will.

Klassisches Beispiel dafür sind externe Temperaturerfassungs-
Module, die jede Minute messen und senden. Den Rest der Zeit
hält man sie im Sleep-Modus, was dann über Monate und Jahre
mit 2 AAA-Zellen funktioniert!

Ob das für deine Zwecke mit PWM etc. nutzbar ist?
Lies mal genauer im Datenblatt nach!

von Carsten R. (kaffeetante)


Lesenswert?

Erwin schrieb:
> Allerdings ist das nur möglich, wenn man den Watchdog
> nicht auf RESET, sondern auf Watchdog-Interrupt konfiguriert.

Asche af mein Haupt, das hatte ich bei diesem Modell übersehen. Nicht 
alle AVRs können das. Ich bin vom Atmega8 ausgegangen, aber hier wird 
ein Atmega88 verwendet. Letzterer kann das, der Atmega8 jedoch nicht. 
Mein Fehler. -.-

Erwin schrieb:
> Den Rest der Zeit
> hält man sie im Sleep-Modus, was dann über Monate und Jahre
> mit 2 AAA-Zellen funktioniert!


Dadurch kann man ihn wie beschrieben nutzen. Allerding wird gerade bei 
Batterieanwendungen empfohlen den Watchdog abzuschalten um Strom zu 
sparen. Die Einsparungen in Relationen zum Sleep-Mode werden im 
Datenblatt als signifikant eingestuft. Für solche Dinge ist eher der 
asynchrone Timer2 mit Uhrenquarz gedacht.

: Bearbeitet durch User
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.