- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 13

Thema: Watchdog Interrupt?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Ich glaube eher der Timer wird von 0 bis 255 laufen, ist aber eigentlich auch ziehmlich egal.
    Beim PWM Mode kann man noch zwischen fast PWM und Phasenrichtigem PWM Wählen. Beim Phasensirchtigen PWM läuft der Timer abwechselnd hoch und runter - der Überlauf kommt dann nur alle 512 Takte.


    Beim zugriff auch die Regster des WDT gibt es schon eine Schwierigkeit mit der Zeit: es müssen innerhalb der 4 Zyken 2 mal Werte geschrieben werden. Das ist in ASM kein Problem, weil man da beide Werte aus 2 CPU Registern schreiben kann. Beim Compiler ist es da nicht sicher das da nicht noch etwas dazwischen kommt, und sei es nur den 2 ten Wert ins CPU Register zu laden.

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    05.01.2010
    Beiträge
    35
    Moin, ich mal wieder.

    Jetzt stehe ich bei einem neuen Projekt wieder vor dem gleichen Problem, dass ich nicht weiß, wie ich unter Bascom den Interrupt des WDT nutzen soll.
    Diesmal komme ich aber nicht drum herum, da ich im Energiespar-Modus die Zeit mitzählen muss und das höchstens über Timer2 gehen würde, der den uC aber zu oft aufwecken würde, dass die Batterie zu schnell leer geht.

    Bascom Version ist 2.0.4.0 und ich nutze einen Atmega48V.

    Also die Idee war, dass ich den WDT im "Hybrid-Modus" nutze, dass der also alle 8 Sekunden den uC aus dem Powerdown-Modus aufweckt und in der Interruptroutine die Byte-Variable "Zeit" um 1 erhöht, aber trotzdem noch den uC resettet, wenn sich dieser aufhängt. Wird leider alles nicht direkt von Bascom unterstützt, aber das Datenblatt meint dazu:

    Bit 6 - WDIE: Watchdog Interrupt Enable
    When this bit is written to one and the I-bit in the Status Register is set, the Watchdog Interrupt is
    enabled. If WDE is cleared in combination with this setting, the Watchdog Timer is in Interrupt
    Mode, and the corresponding interrupt is executed if time-out in the Watchdog Timer occurs.

    If WDE is set, the Watchdog Timer is in Interrupt and System Reset Mode. The first time-out in
    the Watchdog Timer will set WDIF. Executing the corresponding interrupt vector will clear WDIE
    and WDIF automatically by hardware (the Watchdog goes to System Reset Mode). This is useful
    for keeping the Watchdog Timer security while using the interrupt. To stay in Interrupt and
    System Reset Mode, WDIE must be set after each interrupt. This should however not be done
    within the interrupt service routine itself, as this might compromise the safety-function of the
    Watchdog System Reset mode. If the interrupt is not executed before the next time-out, a System
    Reset will be applied.
    Bit 4 - WDCE: Watchdog Change Enable
    This bit is used in timed sequences for changing WDE and prescaler bits. To clear the WDE bit,
    and/or change the prescaler bits, WDCE must be set.
    Once written to one, hardware will clear WDCE after four clock cycles.
    Das WDCE bit, wo man 4 Takte schnell sein muss, scheint ja nur für die 4 Prescalerbits und WDE gebraucht zu werden, was den WDT in den Resetmodus setzt.
    Das sollte dann ja nicht das Problem sein, wenn man mit "Config Watchdog = 8192" den WDT einstellt, da der dann ja den richtigen Prescaler hat und im Reset-Modus arbeitet.

    Aber was muss ich jetzt genau in Bascom machen, damit der WDT auch parallel als Interrupt arbeitet?
    Direkt nach dem "Config Watchdog" nur noch per "Wdtcsr.6 = 1" WDIE auf 1 setzen und auch immer, wenn der WDT-Interrupt ausgelöst wird?

    Und dann weiß ich immer noch nicht, was ich in Bascom machen muss, damit der WDT eine Interruptroutine auslöst, die dann meine Zeit-Variable hochzählt eine Flag-Variable setzt, damit im Hauptprogramm dann wieder WDIE auf 1 gesetzt wird.

    Kann mir da jemand helfen?

    Edit:
    Falls jemand an der Lösung interessiert ist, so ging es:
    Code:
    $regfile = "m48def.dat"                                     'ATmega48V-10AU TQFP
    $crystal = 1000000                                          '1 MHZ
    
    Dim Zeit As Byte                                            'Wird alle 8 Sekunden um 1 erhöht
    Dim Wdtflag As Byte                                         'Wird alle 8 Sek auf 1 gesetzt, zum anzeigen, dass die Watchdogtimer-ISR ausgelöst wurde und das WDIE Bit im WDTCSR Register wieder auf 1 gesetzt werden muss
    
    Enable Interrupts
    Config Watchdog = 8192                                      'Watchdog auf Resetmodus mit 8sek Zeit einstellen
    Wdtcsr.wdie = 1                                             'WDIE Bit auf 1 setzen, damit beim WDT-Timeout ein Interrupt ausgeführt wird und kein Reset
    Start Watchdog
    On Wdt Isr_wdt
    
    Wdtflag = 0
    Zeit = 0
    
    Do
       If Wdtflag = 1 Then
          Reset Watchdog
          Wdtcsr.wdie = 1
          Wdtflag = 0
       End If
    Loop
    
    'Diese Interruptroutine wird beim Timeout vom Watchdogtimer ausgelöst und dient
    '  der Zeitmessung und dem Resetten des WDTs
    Isr_wdt:
       Wdtflag = 1
       Incr Zeit
    Return
    Geändert von Dunuin (27.03.2011 um 15:04 Uhr) Grund: Lösung hinzugefügt

  3. #3
    Das ist genau das, was ich gesucht habe!
    Leider bekomme ich es nicht zum Laufen. Mit einem xmega128a1 bekomme ich beim kompillieren immer diese Fehler:

    Code:
    Config Watchdog = 8000                                      'Watchdog auf Resetmodus mit 8sek Zeit einstellen
    Wdtcsr.wdie = 1                                             'WDIE Bit auf 1 setzen, damit beim WDT-Timeout ein Interrupt ausgeführt wird und kein Reset
    Start Watchdog
    'On Wdt Isr_wdt
    Fehler:
    Getclass error [0]
    Variable not dimensioned [0 -> 0]
    Invalid Date typ [[0011]0[WDIE]]
    Variable not dimensioned [0 -> 0]
    Invalid Date typ [[0011]0[WDTCSR]]

    Was mache ich denn da falsch?
    Danke!

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.694
    Sorry - verwechselt.
    Ciao sagt der JoeamBerg

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.715
    Blog-Einträge
    133
    Zitat Zitat von lendl Beitrag anzeigen
    Code:
    Config Watchdog = 8000                                      'Watchdog auf Resetmodus mit 8sek Zeit einstellen
    Wdtcsr.wdie = 1                                             'WDIE Bit auf 1 setzen, damit beim WDT-Timeout ein Interrupt ausgeführt
    Fehler: ...
    Was mache ich denn da falsch?
    Der Watchdog im XMEGA wird anders als im ATmega48 konfiguriert. Ein Watchdog-Interrupt kann dort nicht aktiviert werden.

    Deine Compiler Fehler kommen daher, daß die entsprechenden Register und Bitnamen im XMEGA nicht existieren.

    Auf der Microchip Seite gibt es die Application Note AN2654 zum XMEGA Watchdog.

    https://www.microchip.com//wwwAppNot...pnote=en591662

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.236
    Ich würde eine Zeitmessung eigentlich immer über einen Timer(Interrupt) machen.
    Der Watchdog wäre für mich immer nur eine Notbremse, falls sich das Prog irgendwo aufhängt ( Stack Overflow, Warten auf ein Ereignis ).

    Die Timer der AVR sind äusserst flexibel.
    Wenn der Prescaler für die Anwendung passt kann so ein Timer auch durchaus bis zu 3 Aufgaben auf einmal bewältigen ( Zeit messen ( Input Capture ), PWM generieren, Timer Interrupts generieren ).

    Zudem kann man einen Timer mit relativ hoher Taktfrequenz laufen lassen und im Overflow Interrupt Variablen runterzählen lassen ( frisst zwar viel Rechenzeit geht aber ).
    Somit sind dann auch Messungen für unterschiedliche Zeitintervalle möglich.

  7. #7
    Als sehr einfach zu realisierende "Pi-mal-Daumen"-Zeitbasis, an die keine hohe Präzisionsforderung gestellt wird,
    ist der WD-Timer sehr gut geeignet. Die anderen Timer bleiben dann anderweitig nutzbar.

    Für die Attinys u.A. geht das auch ganz simpel:

    Config watchdog = 8000 'nach meiner Erfahrung läuft der wd-Timer damit schon los, auch ohne "start"-Befehl
    Set Wdtcr.wdie 'wd in Interrupt-Modus versetzen, statt reset-Modus


    If Wdtcr.wdif = 1 Then 'zeitintervall abgelaufen
    set Wdtcr.wdif ' das wdif-flag sofort wieder löschen, indem man es setzt
    Incr wd_tick
    end if


    Damit wird die Zählvariable "wd_tick" jedesmal wenn das wdif-flag gesetzt wird incrementiert,
    und das wdif_flag bis nach Ablauf des nächsten Zeit-Intervalls zurückgesetzt,
    ohne dass man eine WD-Interruptroutine aufrufen bzw. ausführen muss. (= Polling)

    Zu beachten ist, dass das vom Timer gesetzte wdif-flag dadurch gelöscht wird, dass man es setzt(!),
    also mit einer 1 beschreibt, obwohl es schon gesetzt ist.

    Man braucht hierbei auch keine 4-Takte-Sequenz einhalten, wie oft irrtümlich geschrieben wird.

    Dieses einfache Polling des Interrupt-Flags geht auch bei anderen Timern oder anderen Interruptquellen, wenn man die zeitraubenden Pushs und Pops der Interruptroutinen vermeiden will.
    Geändert von stemmy (20.02.2022 um 13:39 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress