-         

Ergebnis 1 bis 8 von 8

Thema: Watchdog Interrupt?

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    05.01.2010
    Beiträge
    35

    Watchdog Interrupt?

    Anzeige

    Moin,

    Ich bastle gerade mit der Bascom-Demo an einem Projekt, wo ein ATtiny2313 vier LEDs per PWM dimmen soll. Das klappt auch soweit mit der PWM, aber leider sind jetzt dadurch Timer0 und Timer1 blockiert.
    Ich muss jetzt noch irgendwie die Zeit messen, was ich über Timer2 mit einem Timeroverflow machen wollte, der der immer ein Flag auf 1 setzt und eine Variable hochzählt.
    Mir ist leider jetzt erst aufgefallen, dass der Tiny ja gar keinen Timer2 besitzt.

    Dann habe ich im Datenblatt nach einer Alternative gesucht und habe gelesen, dass der Watchdogtimer alternativ zum Reset auch einen Interrupt auslösen kann.

    Über Bascom kann ich aber wohl nur den Watchdog starten, zurücksetzen und den Prescaler definieren. Eine Einstellung als Interrupt geht wohl nicht und ein Interruptvektor für den Overflow konnte ich auch nicht finden.

    Ich glaube ich muss folgendes machen, um das Register des Watchdogs auf Interrupt umzustellen:

    Code:
    Wdtcsr = &B01010000
    Wenn ich das richtig verstanden habe, dann sollte der WDTimer damit alle 16ms einen Interrupt auslösen und nicht resetten.

    Aber wie mache ich das jetzt mit dem Interrupt?

    Der Vektor dafür hat die Nummer 19, ist an Programmadresse "0x0012" und Source ist "WDT OVERFLOW", laut Datenblatt.

    Normalerweise würde ich das ja mit...
    Code:
    Enable Interrupts
    Enable Vektorname
    On Vektorname Isr_wdovf
    Isr_wdovf:
       Incr Zeit1
       Zeitflag = 1
    Return
    ...machen, aber den Vektor kennt Bascom ja nicht.

    Hat da schon wer Erfahrungen gemacht?
    Kann mir da wer helfen?

    MfG

    Dunuin

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hallo Dunuin,
    ich hätte jetzt sowas gemacht:
    On WDT Wdt_isr

    Allerdings musst du bei Änderung des WDTCSR Registers bedenken, dass du das Change bit setzen musst und dann innerhalb von 4 Takten deine Änderungen, also unmittelbar danach:
    WDTCSR.WDCE = 1
    WDTCSR = &B01000000

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.04.2010
    Beiträge
    1.249
    Wieso nicht mit einem Timer 2 Dinge zählen?!

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Vermutlich ist es besser einen der PWM timer mit zu nutzen. Außer der vielleicht etwas hohen Frequenz spricht nichts dagegen auch bei Timer 1 noch den Overflow Interrupt zu nutzen.

    Das ändern der Watchdog timer Einstellungen über die Register geht so direkt nicht von BASIC aus - das schaft der Compiler nicht in den geforderten 4 Zyklen. Da müsste man schon inline ASM bemühen.

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Zitat Zitat von Besserwessi
    Das ändern der Watchdog timer Einstellungen über die Register geht so direkt nicht von BASIC aus - das schaft der Compiler nicht in den geforderten 4 Zyklen. Da müsste man schon inline ASM bemühen.
    Der Compiler braucht das auch nicht zu schaffen, das kann der µC sehr gut selber. Register setzen dauert exakt 2 Takte, also wo ist das Problem. Und das ist nichts anderes, als inline ASM.

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    05.01.2010
    Beiträge
    35
    Aha, dann werde ich das mal mit dem Timer1-Overflow versuchen. Wusste nicht, dass das auch noch geht, wenn ich den als PWM nutze.

    Der Timer1 ist ja ein 10-Bit Timer, den ich als 8-Bit PWM eingestellt habe, da die 256 Abstufungen eigentlich reichen und Timer0 ja auch nur als 8-Bit PWM funktioniert.
    Sehe ich das richtig, dass der dann immer nach 255 Schritten überläuft? Also immer von 65280 bis 65535 hochzählt?

  7. #7
    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.

  8. #8
    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 16:04 Uhr) Grund: Lösung hinzugefügt

Berechtigungen

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