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: |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum