WD und INT Tiny4313

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • WD und INT Tiny4313

      Hallo,

      ich versuche beides zusammenzubringen.

      AVR im Sleepmodus, wird durch WD alle 8 sec aufgeweckt um irgendwas zu tun.

      Jetzt soll zusätzlich noch ein externes Ereignis gezählt werden (wohl INT0 oder 1).

      Bei einer Flanke am Eingang soll der AVR aufwachen, einen Zähler hochzählen und dann wieder schlafen.
      Mir ist noch nicht klar wie das Befehlsmässig geht und was passiert wenn der AVR schon wach ist weil er vom WD bereits wachgerüttelt wurde.

      Gibts hier ein Beispiel an das ich mich anhängen kann, oder nach welchen Kriterien sollte ich suchen?
      Welche Fallstricke sind da ev. ausgelegt?


      Kurt
    • Deinen Watchdog kannst du als Interrupt konfigurieren, dein INT0 ebenso.
      Beide sind, je nach Powerdown Modus, als Aufwachquelle geeignet.
      Im Datenblatt steht das genauer, da gibt es eine Tabelle zum Thema.
      Der externe Interrupt muss zum Aufwachen als Low Level eingestellt sein.

      On Int0 Ereignislabel
      Enable Int0
      Config Int0 = LOW LEVEL
      Enable Interrupts
    • Gefunden im Netz zu: Config Int0 = LOW LEVEL



      Michael wrote:

      Deinen Watchdog kannst du als Interrupt konfigurieren, dein INT0 ebenso.
      Beide sind, je nach Powerdown Modus, als Aufwachquelle geeignet.
      Im Datenblatt steht das genauer, da gibt es eine Tabelle zum Thema.
      Der externe Interrupt muss zum Aufwachen als Low Level eingestellt sein.
      Damit habe ich ein Problem.

      Gefunden:
      ------------
      Es gibt für diesen Interrupt drei Einstellmöglichkeiten auf die er reagieren kann:

      Low Level: reagiert solange der Pin auf Masse gesetzt wird
      ----------------

      Was bedeutet das genau?
      Muss der Pin solange auf Masse bleiben bis der AVR mit dem IR fertig ist oder führt er den IR solange aus bis der Pin wieder auf 1 ist?
      Oder ist es ganz anders?


      Kurt


      Ich habs ev. gefunden.

      Wenn der Low-Pegel am Interrupt-Pin entfernt wird, bevor das Gerät aufgewacht ist, programmieren SieDie Ausführung wird nicht zur Interrupt-Service-Routine umgeleitet, sondern ab der folgenden Anweisung fortgesetztden SLEEP-Befehl.

      The post was edited 1 time, last by Kurt ().

    • Ich hab mal die genannte Tabelle rauskopiert.
      Da steht auch in der Fußnote, dass Int0 Low-Level sein muss.
      Das heißt, der Pin braucht GND, um einen Interrupt auszulösen, und das muss eine Weile anliegen, während der Oszillator anläuft.
      Wenn der Chip dann wach ist, ist er im Interrupt, dort schaltest du den Int0 ab, um gleich den nächsten zu verhindern, wenn der Pin noch Low ist.
      Vor dem Sleep schaltest du ihn wieder scharf (und wenn der Pin High ist)

      Gruß, Michael


      Sleep_4313.png
    • Michael wrote:

      Deinen Watchdog kannst du als Interrupt konfigurieren, dein INT0 ebenso.
      Beide sind, je nach Powerdown Modus, als Aufwachquelle geeignet.
      Im Datenblatt steht das genauer, da gibt es eine Tabelle zum Thema.
      Der externe Interrupt muss zum Aufwachen als Low Level eingestellt sein.

      On Int0 Ereignislabel
      Enable Int0
      Config Int0 = LOW LEVEL
      Enable Interrupts
      So schauts momentan aus:

      Source Code

      1. ' ------- int config----
      2. Config Int0 = Low Level
      3. On Int0 Zaehlen
      4. Enable Int0
      5. Enable Interrupts

      Und so der WD mit Arbeitsroutine

      Source Code

      1. ' --- Aufwachzyklus festlegen -------------
      2. Config Watchdog = 8192
      3. Start Watchdog
      4. ...
      5. Powerdown

      Hier die ISR

      Der Auslösepuls dauert 500 ms an, darum die Wartezeit von 600 ms

      Source Code

      1. ' ------ Interruptrutine ----------------
      2. Zaehlen:
      3. Incr M3_zaehler ' Zähler erhöhen
      4. Disable Int0
      5. Waitms 600
      6. Enable Int0
      7. If Aktiv = 0 Then
      8. sleep
      9. End If
      10. Return
      Display All
      Die Var "Aktiv" wird in der Hauptroutine gesetzt und verhindert das Schlafenlegen während diese aktiv ist.
      Die Verzögerung von 600 ms durch die ISR spielt im Hauptprogramm eigentlich keine entscheidende Rolle.

      Ob hier ein "sleep" oder "powerdown" zum Abschalten hingehört ist mir noch nicht ganz klar.

      Kurt
    • Es wäre sicher besser, du postest ein zusammenhängendes Programm.
      Damit erreichst du auch die weniger interessierten Helfer.
      Ich selbst antworte oft gar nicht, wenn solche Sachen fehlen.

      Deinen Watchdog hast du als Resetquelle konfiguriert?
      Auch hier kann ein Interrupt ausgelöst werden.
      On Wdt Watdoglabel

      Idle owerdown unterscheiden sich im der Tiefe des Schlafes.
      In der Tabelle in Beitrag #5 siehst du, welche Taktquellen noch aktiv sind.
    • Kurt wrote:

      Ob hier ein "sleep" oder "powerdown" zum Abschalten hingehört ist mir noch nicht ganz klar
      Ein sleep kennt er nicht das ist der Überbegriff wie z.B ko das kann erschöpft,halbschlaf oder tiefschlaf sein.
      600ms sind ne Ewigkeit, wäre da das Usi Start Condition nicht besser geeignet? Es würde in bei jeder Flanke wecken aber dafür nicht wachhalten. Batteriebetrieb?
      Wenn er gerade wach ist wird die Isr auch ausgeführt.
    • New

      Michael wrote:



      Deinen Watchdog hast du als Resetquelle konfiguriert?
      Auch hier kann ein Interrupt ausgelöst werden.
      On Wdt Watdoglabel

      Idle owerdown unterscheiden sich im der Tiefe des Schlafes.
      In der Tabelle in Beitrag #5 siehst du, welche Taktquellen noch aktiv sind.

      On Wdt Ziel hat nicht funktioniert, ev. ist meine SW schon zu alt.
      Ging auch so, fing halt bei "Reset" an.

      Nachdem ich geschnallt hatte das der SLEEP ja nur das vorher eingestellte aktiviert war auch der Stromverbrauch, ca. 25µA während des Schlafmodus, wieder OK.
      Ansonsten läufts, danke an alle für die Hilfe!

      Kurt
    • New

      Kurt wrote:

      On Wdt Ziel hat nicht funktioniert
      Er ist da ein Sonderfall: Vier Möglichkeiten 1 - garnicht
      sonst immer Config Watchdog = xxxx ms
      2- als Watchdog: Start Watchdog und oft genug Reset Watchdog
      3- als Int-Timer: On Wdt wd_isr : Enable wdt : ' Kein Start Watchdog und Reset Watchdog nur wenn zusätzliche Verzögerung gewünscht ist
      4- oder beides : wie oben aber auch Start Watchdog. Dann aber in seiner Isr (Oder bald danach) Reset Watchdog : Enable Wdt
      Ohne das Enable Wdt würde er nur einmal die Isr aufrufen und dann einen Reset
    • New

      Kalle_BMW wrote:

      dann poste doch bitte dein Programm wie du dies gelöst hast damit ich dies auch verstehen kann :D
      Alles geht nicht, also nur das relevanteste.

      Source Code

      1. $regfile = "Attiny4313.dat"
      2. $crystal = 4096000
      3. $baud = 9600
      4. $noramclear
      5. Config Serialin = Buffered , Size = 25
      6. ' hier kommt dann die Variablendeclaration und die Pinconfiguration
      7. ' weiter mit demda:
      8. ' ------- int config----
      9. Config Int0 = Low Level
      10. On Int0 Zaehlen
      11. Enable Int0
      12. Enable Interrupts
      13. ' --- Aufwachzyklus festlegen -------------
      14. Config Watchdog = 8192
      15. Start Watchdog
      16. ' ----- Arbeiten -------------
      17. ' ... das Programm arbeit den ganzen Block nun ab.
      18. ' am Ende wird wieder geschlafen bis der WD einen Reset erwirkt
      19. Powerdown ' schlafen legen
      20. sleep
      21. ' ------ Interruptrutine ----------------
      22. Zaehlen:
      23. Disable Int0
      24. Incr M3_zaehler ' Zähler erhöhen
      25. Waitms 600
      26. Enable Int0
      27. Return
      Display All

      Angedacht ist es so:
      Der WD weckt auf, die Arbeitsroutine wird (bei Bedarf) abgearbeitet, danach wird wieder geschlafen.

      Der zu zählende Impuls ist 500 ms lang und kommt nicht oft.
      Er weckt den AVR durch einen IR auf und dieser zählt einfach weiter.
      In der IR_Rutine werden weitere IR gesperrt (Prellen usw.) und erst nach der Max-Länge des Impulses wieder freigegeben.

      Dem Hauptprogramm tut das normalerweise keinen Abbruch, und wenns mal nicht klappt ist das auch nicht tragisch.
      Eins musste ich ändern, wenn ein Dauerpuls anliegt dann hauts nicht mehr hin, das Hauptprogramm geht dann nicht mehr bzw zu selten.
      Darum habe ich einen Kondensator in Reihe zum Pulsgeber geschaltet der diese Situation dann abfängt.

      Kommt der IR während das Hauptprogramm läuft dann wird trotzdem gezählt weil der AVR ja schon wach ist.

      Ein Problem sehe ich gerade:
      Liest das Hauptprogramm die Long-VAR aus während sie incrementiert wird dann gibts Datensalat.
      Das muss also noch verhindert werden.

      Kurt
    • New

      Hallo Kurt,
      du hast nicht genau genug gelesen, was Michael geschrieben hat:

      Michael wrote:

      Wenn der Chip dann wach ist, ist er im Interrupt, dort schaltest du den Int0 ab, um gleich den nächsten zu verhindern, wenn der Pin noch Low ist.
      Vor dem Sleep schaltest du ihn wieder scharf (und wenn der Pin High ist)

      In der ISR aus-und wieder einschalten hat keinen Wert, weil dort die Interrupts eh global abgeschaltet sind und erst mit dem Verlassen wieder aktiviert werden.
      Wenn du befürchtest, dass Impulse auftreten, während das Hauptprogramm läuft, dann könntest du evtl. den Int umkonfigurieren, sodass er auf eine fallende Flanke reagiert. Und direkt vor dem Powerdown wieder auf Low_level.
      Warum hast du eigentlich nach dem Powerdown ein Sleep im Programm? Wenn er vom Powerdown aufwacht und die ISR abgearbeitet hat, geht er sofort in den Sleep. Irgendwie komisch.
      Und wie gesagt, ich würde den neuen Befehl Config Powermode verwenden, so wie MCS das empfiehlt und nicht die alten Versionen.
      Wenn du mit Datensalat M3_zaehler meinst, dann solltest du vor der Benutzung im Hauptprogramm die Interrupts ausschalten.