Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum

Re: Für alle die den eingebauten Watchdog nutzen möchten. Kategorie: Programmierung Assembler (von Ernst H. - 2.01.2011 16:59)
Als Antwort auf Re: Für alle die den eingebauten Watchdog nutzen möchten. von Joerg - 1.01.2011 19:38



   ' Fertiges Program   -  einfach kopieren und Starten:
   ' Watchdog in Basic verwenden:
   ' die $Asm.... am Anfang definieren
   ' dann im Programm ....WatchDog_Reset( )... einfügen
   ' im unteren Programm wird 3x bis 2,2sec angezeigt, dann erfolgt Reset
   ' schon nach 800ms Anzeige-(USB Kabel abstecken sonst kein Neustart)
   ' Anregung von Jörg eingebunden: Reset-Gründe werden zuerst
   ' als Zahlenwert angezeigt, dann im internen EEprom Aufaddiert
   ' es ist dadurch nachvollziehbar ob der Watchdog im Einsatz war, oder
   ' alle Neustarts durch PowerOn erfolgten.
   ' Zur Frage ob Watchdog anstelle Reset wo anderst hinspringen kann
   ' - ja/nein: Die Variablen werden auf 0 gesetzt, die sind verloren
   ' man kann lediglich eine andere Startroutine für einen Watchdogreset
   ' schreiben, so könne man eventuell Initialisierungen auslassen.
   ' auf der anderen Seite solle so Programmiert werden, das nur ein
   ' Absturz infolge eines Störimpulses o.ä. den Watchdog zum Einsatz
   ' bringt und da ist eine Neuinitialisierung zB des LCD ohnehin ratsam.

'//  Valid values for WatchDog_On
$Asm("tag_WDT_on") WatchDog_On(prescalar As Byte)

'// Needs to be called before time which is defined
'by WatchDog_On( prescalar) has run off.
'void WatchDog_Reset
$Asm("tag_WDT_reset")WatchDog_Reset()

'// Turn Watch Dog off
'void WatchDog_Off
$Asm("tag_WDT_off")WatchDog_Off()

Dim Laufvari As Integer
Dim Text(20) As Char
Dim ResetZahlPower As Byte 'EEProm 30-31
Dim ResetZahlExt As Byte 'EEProm 32-33
Dim ResetZahlWatchdog As Byte 'EEProm 34-35
Dim ResetZahlUndef As Byte 'EEProm 36-37
Dim val As Byte
Sub main()
LCD_Init()
LCD_Locate(1,1 )
'EEProm intern: für Erstprogrammierung auf Pos=0 eine Abfrage:
If EEPROM_Read(0)<>0b01101011 Then 'beliebiges Muster das nicht zufällig drin
   ' Wenn stelle 0 noch nie beschrieben wurde dann erste Werte

   EEPROM_WriteWord(30,0 )   'Dim ResetZahlPower As Byte 'EEProm 30-31
   EEPROM_WriteWord(32,0 )   'Dim ResetZahlExt As Byte 'EEProm 32-33
   EEPROM_WriteWord(34,0 )   'Dim ResetZahlWatchdog As Byte 'EEProm 34-35
   EEPROM_WriteWord(36,0 )   'Dim ResetZahlUndef As Byte 'EEProm 36-37
   EEPROM_Write(0,0b01101011)'Erstbeschreibung erledigt
End If                                              'Reseteinstellungen 'main
'Address    Name    Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
' $34 ($54) MCUCSR  JTD     â??   â??     JTRF  WDRF  BORF  EXTRF PORF    56, 257

  val = DirAcc_Read(0x54)'    ;    // Read MCUCSR
  DirAcc_Write(0x54,0x00)'    ;    // Clear MCUCSR
LCD_WriteText("rCode")
LCD_WriteWord(val,3 )
AbsDelay(2000)
  If (val And 0x08) = 0x08 Then    'Klammer bei And notwendig!!
    EEPROM_WriteWord(34,EEPROM_ReadWord(34)+1) 'ResetZahlWatchdog EEProm 34-35
  ElseIf (val And 0x01 = 0x01) Then
    EEPROM_WriteWord(30,EEPROM_ReadWord(30)+1) 'ResetZahlPower  EEProm 30-31
  ElseIf (val And 0x02) = 0x02 Then
    EEPROM_WriteWord(32,EEPROM_ReadWord(32)+1) 'ResetZahlExt EEProm 32-33
  Else
    EEPROM_WriteWord(36,EEPROM_ReadWord(36)+1) 'ResetZahlUndef  EEProm 36-37
  End If



LCD_Locate(1,1 )
LCD_WriteText("rW")
LCD_WriteWord(EEPROM_ReadWord(34),2)    'ResetZahlWatchdog EEProm 34-35
LCD_WriteText("rP")
LCD_WriteWord(EEPROM_ReadWord(30),2)    'ResetZahlPower  EEProm 30-31
LCD_Locate(2,1 )
LCD_WriteText("rE")
LCD_WriteWord(EEPROM_ReadWord(32),2)    'ResetZahlExt EEProm 32-33
LCD_WriteText("rU")
LCD_WriteWord(EEPROM_ReadWord(36),2)    'esetZahlUndef  EEProm 36-37


AbsDelay(3000)

WatchDog_On(6)                            'Aktivieren ...
'Prescalar     Typical Timeout Value
'                 0    15 ms
'                 1    30 ms
'                 2    60 ms
'                 3   120 ms
'                 4   240 ms
'                 5   0.5 sec
'                 6   1.0 sec
'                 7   2.0 sec
WatchDog_Reset( )
Do While (1)                    'EndlosSchleife Start
    For Laufvari = 1 To 9
        LCD_Locate(2,1 )
        LCD_WriteText("Schleif")
        LCD_WriteWord(Laufvari,1)
        If Laufvari < 3 Then
            WatchDog_Off()     'ab Schleife 4  Watchdog wirksam
        Else
           WatchDog_On(6)  'Die Aktivierung des Watchdog ist eigentlich
                           'nur einmal am Begin erforderlich
                           'hier nur damit das Ausschalten demonstriert
                           'werden kann
                           'eine Schleife 5 wird nie erreicht - durch den
        End If             'Watchdogreset

        WatchDog_Reset( )
        AbsDelay(400)
        LCD_Locate(1,1 )
        LCD_WriteText("Vz 400ms   ")


        WatchDog_Reset( )
        AbsDelay(800)
        LCD_Locate(1,1 )
        LCD_WriteText("Vz 800ms   ")


        WatchDog_Reset( )
        AbsDelay(1800)
        LCD_Locate(1,1 )
        LCD_WriteText("Vz 1,8s    " )

        WatchDog_Reset( )
        AbsDelay(2200)
        LCD_Locate(1,1 )
        LCD_WriteText("Vz 2,2s    " )
    Next
End While   'Rücksprung zur Hauptprogrammschleife
End Sub

/*        unteres File als Watchdog.asm speichern und im Projekt hinzufügen
'  Achtung wegen Forum-Editor   die Hochkomma bei "<<" entfernen (6x)
;***************************************************************************
;* File: Watchdog.asm
;* Author  : M. Benninger
;* Ident   : Rev 1 30-DEC-2008
;* Function: Watchdog Timer Functions
;*         This module implements three functions:
;*         WDT_on (prescalar), WDT_off () and WDT_reset ()
;*         The parameter prescalar determine the Watchdog Timer prescaling
;*         when the Watchdog Timer is enabled. The different prescaling values
;*         and their corresponding Timeout Periods are shown below:
;*              Prescalar        Typical Timeout Value
;*                  0                   15 ms
;*                  1                   30 ms
;*                  2                   60 ms
;*                  3                  120 ms
;*                  4                  240 ms
;*                  5                  0.5 sec
;*                  6                  1.0 sec
;*                  7                  2.0 sec
;*
;* Library:  none
;*
;* History : Rev 1 30-DEC-2008 M. Benninger
;*                 - first implementation
;*         Rev.1.1 29.12.2010 Joachim Kühnapfel (Jo)
;*              - WTD_off: rettrn und wiederherstellen von R16 und R17 wie im
;*                 wie im Forum diskutiert / beschrieben
;*              - .ifdef tag_xxx / .endif hinzugefügt gemäÃ? Vorgaben aus
;*                   Beispiel der C-Control Hilfe
;*              - rename
;*                     WDT_on       -> WatchDog_On
;*                     WDT_off      -> WatchDog_Off
;*                     WDT_reset    -> WatchDog_Reset
;*          Rev.1.2 1-1-2011  Ernst H.  bei ldi ... ein Ã?bertragungsfehler?
;*
;************************************************************************

;**** Watchdog Timer Definitions ****

.equ WDTCR = $21               ; Watchdog Timer Control Register
.equ WDCE  = 4                 ; WDT Change Enable bit
.equ WDE   = 3                 ; WDT Enable bit
.equ WDPM  = 7                 ; WDT Prescalar mask

.ifdef tag_WDT_reset
WatchDog_Reset:                          ; Reset Watchdog Timer
    wdr
    ret
.endif


.ifdef tag_WDT_on
WatchDog_On:                        ; Enable Watchdog Timer
    movw    r26, r6                 ; r7:r6 points to ret_addr
    adiw    r26, 4                  ; X now points to prescalar parameter
    ld      r16, x                  ; get prescalar parameter
    andi    r16, WDPM               ; and mask lower 3 bits
    ori     r16, (1"<<"WDE)           ; turn on WDE bit
    ldi     r17, (1"<<"WDCE)|(1"<<"WDE) ; Write logical one to WDCE and WDE
    out     WDTCR, r17              ; enable write to WDT control register
    out     WDTCR, r16              ; write WDT control register
    ret
.endif


.ifdef tag_WDT_off
WatchDog_Off:
    push    R16
    push    R17
                                    ; Disable Watchdog Timer
    in      r16, WDTCR              ; get WDT control register
    ori     r16, (1"<<"WDCE)|(1"<<"WDE); enable write to WDT control register
    out WDTCR, r16                  ; write WDT control register
    ldi     r16, (0"<<"WDE)           ; turn off WDE bit
    out WDTCR, r16                  ; write WDT control register
    pop     R17
    pop     R16
    ret
.endif

;* End of Watchdog.asm -- Watchdog Timer Functions für ATmega128
;**************************************************************************
*/  'Ende Basic


    Antwort schreiben


Antworten: