Lesen Sie den AVR-Watchdog-Timer

AVR-Watchdog-Timer. Gibt es eine Möglichkeit, den Watchdog-Timer aus dem Code heraus zu lesen?

Beabsichtigter Anwendungsfall: Um eine ungefähre Vorstellung (sehr grob, +/- 1 Sek.) davon zu bekommen, wie lange es her ist, seit der Watchdog-Timer das letzte Mal zurückgesetzt wurde. Dies würde es meinem Code ermöglichen, zu erraten, wie lange er geschlafen hat, ohne eine externe RTC oder ähnliches.

Ich habe versucht, im attiny85-Datenblatt nachzusehen, und es nicht gefunden. Irgendwelche Ideen Leute?

Sie möchten wahrscheinlich dieses hier: jeelabs.net/pub/docs/jeelib/classSleepy.html

Antworten (4)

Stellen Sie den Watchdog auf 1 Sekunde und dann in den Interrupt-Modus, wenn der Interrupt auftritt, setzt sich der Watchdog wieder in den Reset-Modus und dann muss Ihr Code ihn manuell in den Interrupt-Modus versetzen, auf diese Weise können Sie den Watchdog-Timer als 1 verwenden zweiten Timer und der hat den Watchdog immer noch funktionsfähig, denn wenn nach der Interrupt-Ausführung ein Zeitfenster von einer Sekunde vorhanden ist, um den Watchdog in den Interrupt-Modus zu versetzen, bevor der Timer abläuft, und das Mikro zurückzusetzen. Ich habe den Watchdog auf diese Weise in einem attiny10 verwendet

Dies ist die einfachste Lösung. Da die längste Zeit, die Sie mit dem Watchdog bei einem einzigen Schlaf messen können, ohnehin 8 Sekunden beträgt, bedeutet dies, dass Sie höchstens 8-mal häufiger aufwachen. Sie können den Code, der bei jedem Aufwecken ausgeführt wird, sehr, sehr schnell machen, indem Sie einfach einen Sekundenzähler in einem Register erhöhen, WDIE einstellen, schlafen. Sie können diesen Code wahrscheinlich sogar direkt in die Vektortabelle einfügen, um einen Sprung zu sparen (vorausgesetzt, Sie benötigen die USI-Vektoren nicht).
Dies ist die beste Antwort hier, denke ich. Der Vektortisch-Trick wäre auch ein cleveres Showboat :)

Soweit ich das Datenblatt verstehe, ist der WDT-Reset ein UND-verknüpftes Signal von einem Satz geteilter 128-kHz-Takte, die durch den WDT-Prescaler laufen, und wird als solches nicht in einem Register gespeichert, das Sie lesen können.

Wenn ich das wäre, würde ich meinen eigenen Timer verwenden, der jedes Mal zurückgesetzt wird, wenn der WDT war. Ich könnte dies dann abfragen, um die seit dem letzten Zurücksetzen verstrichene Zeit abzuschätzen. Dies ist hardwareunabhängiger und damit portabler.

Würde der Schlafmodus nicht auch die Timer schlafen legen? Oder sind die Timer nicht an die CPU-Uhr gebunden?
Wenn Sie im Leerlaufmodus schlafen, läuft Timer1 weiter und kann verwendet werden, um den AVR bei Bedarf aufzuwecken, oder abgefragt werden, wenn ein anderer Interrupt den AVR aufweckt. Siehe Abschnitt 7.1.1 des Datenblatts.
Selbst bei der niedrigstmöglichen Leistungskonfiguration, die mit einem 128-kHz-RC-Takt betrieben wird, verbraucht der Leerlaufmodus in der Größenordnung von 50-100uA. Der Abschaltmodus mit aktiviertem Watchdog verwendet nur in der Größenordnung von 3-9 uA, sodass der Watchdog mit Abschaltung viel energieeffizienter ist als ein normaler Timer im Leerlauf.
@bigjosh das mag der Fall sein, aber es ist nicht die gestellte Frage - Sie können immer noch nicht wissen, wie lange Sie geschlafen haben, wenn Sie von einer anderen Interrupt-Quelle geweckt wurden

Beachten Sie, dass ich diese Lösung nicht befürworte, sondern nur zeige, dass ich sie für möglich halte. Ich denke, dass die Antwort von Kvegaoro praktischer ist und wahrscheinlich sogar weniger Strom für fast alle Anwendungsfälle im wirklichen Leben verbraucht.

Ich denke, du könntest so etwas tun ...

  1. Richten Sie den Watchdog-Interrupt-Only-Modus ein.
  2. Stellen Sie den Prescaller auf die maximale Verzögerung von 8 Sekunden ein.
  3. Starten Sie den Watchdog.
  4. Schlafen.
  5. Aufwachen aufgrund eines externen INT außer dem Watchdog.
  6. Stoppen Sie den Watchdog sofort nach dem Aufwachen.
  7. Gehen Sie in einer Schleife durch die Prescaller-Werte vom höchsten zum niedrigsten.

    D. Löschen Sie das Watchdog-Interrupt-Flag

    A. Stellen Sie den Prescaler auf den Schleifenwert ein.

    B. Prüfen Sie, ob das Watchdog-Interrupt-Flag gesetzt wurde.

    C. Schieben Sie das Bit aus dem vorherigen Test in ein Schieberegister.

Am Ende von all dem sollte das Schieberegister nun die oberen Bits des Wertes innerhalb des Prescaller-Zählers haben.

Beachten Sie, dass ich nicht getestet habe, ob das Ändern des Werts des Vorteilers den Wert von WDIF asynchron aktualisiert, selbst wenn der Watchdog nicht läuft, aber basierend darauf vermute ich , dass dies der Fall ist. Auch wenn dies nicht der Fall ist, kann diese Methode dennoch funktionieren. Sie müssen lediglich einen Watchdog-Interrupt-Handler erstellen, der irgendwo ein Flag setzt, das anzeigt, dass er aufgerufen wurde. Überprüfen Sie dann einfach dieses Flag nach jedem Prescaler-Update, um zu sehen, ob der Interrupt ausgelöst wurde.

Wenn Sie mich davon überzeugen können, dass Sie einen der unwahrscheinlichen Anwendungsfälle haben, in denen dies tatsächlich Sinn macht, dann werde ich etwas Code spinnen, um die Details herauszuarbeiten!

Dies würde mein Problem lösen. Es ist eine schreckliche Idee, und ich sehe keinen Vorteil gegenüber Kvegaoros Lösung. Aber es beantwortet wirklich meine Frage und ist eine großartige Lösung. Ich denke auch, dass es urkomisch wäre, dies umgesetzt zu sehen. Kann es aber in keinster Weise begründen!

Der Watchdog-Timer wird verwendet, um den Mikrocontroller zurückzusetzen, wenn er in eine Endlosschleife eintritt. Sie können WDT nur mit bevorzugter Zeit aktivieren oder deaktivieren. Sie können den Wert des Watchdog-Timers nicht lesen .

Sie können den normalen Timer verwenden, um Ihren AVR aus dem Schlafmodus zu wecken, wenn er überläuft.