PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Watchdog-Timer Mega88



schamp
22.08.2005, 09:40
Hi!

Versuche grade den Watchdogtimer zum Laufen zu bringen. Klappt aber noch nicht so ganz...
Hab zum Ausprobieren ein ganz einfaches Testprogramm geschrieben.
Watchdog Initialisierung, in der Hauptschleife "Hello World" ans Terminal senden (dort will ich später Delay einbauen, um einen System Reset vom Watchdog zu erzwingen) und dann noch ein Check ob Senderoutine korrekt ausgeführt wurde (wenn dieser OK war, gibts nen Watchdog Reset)
Problem ist, das nie ein "Hello World" am Terminal erscheint... sondern nur:
4
_4
__4
___4
usw. (die _ sollen Leerzeichen darstellen... Forum scheint das nicht zu checken)
Am Software UART kanns aber nicht liegen, da bin ich mir 100% sicher


#include <iom88.h>
#include <ina90.h>
#include <string.h>
#include "sw_uart.h"

void watchdog_init(void);
void sende_routine(void);
void health_check(void);

volatile unsigned char Flag;
#define SENDEROUTINE_M_OK 1

__task void main(void)
{
watchdog_init();

__enable_interrupt();

__watchdog_reset(); // Reset Watchdog Timer und ab in die Hauptschleife

while(1)
{
sende_routine(); // Hallo Welt senden (mit versch. Delays ausprobieren -> System Reset funktioniert?)

health_check(); // Am Ende der Hauptschleife prüfen, ob sende_routine() ordnungsgemäß ausgeführt
}
}


void watchdog_init(void)
{
MCUSR = 0; // Clear all flags previously set.
Flag = 0;

/* Setup Watchdog */
WDTCSR |= (1<<WDCE); // Watchdog Change Enable setzen

WDTCSR |= (1<<WDE); // Watchdog System Reset Mode einstellen

WDTCSR |= (1<<WDP3); // Timeout auf 4.0 Sekunden setzen

sw_uart_init();
}


void sende_routine(void)
{
char bTxt[24] = "\r\nHello, World\r\n";
unsigned char bIx;
unsigned char bLn;

bLn = strlen(bTxt);

for (bIx = 0;bIx < bLn; bIx++)
{
send_one_byte(bTxt[bIx]);

// hier später delay um System Reset zu simulieren....
}

Flag |= (1<<SENDEROUTINE_M_OK); // Routine korrekt ausgeführt
}


void health_check(void)
{
if(Flag & (1<<SENDEROUTINE_M_OK)) // alles ok ?
{
Flag &=~ (1<<SENDEROUTINE_M_OK);

__watchdog_reset(); // dann Reset Watchdog
}
}


Weis nicht woran das liegt.. :-s

Gruß
schamp

PicNick
22.08.2005, 10:26
Hallo, Schampolino !
Ich mißtraue den Griechen, auch wenn sie Geschenke bringen:


void sende_routine(void)
{
char bTxt[24] = "\r\nHello, World\r\n";

bau das mal um auf


static char bTxt[24] = "\r\nHello, World\r\n";
void sende_routine(void)
{
....

Er muß sonst bei jeder Senderoutine den Fixen Text aus dem Flash-Mem in den SRAM verschieben. Und wenn das irgendwie nicht hinhaut, zeigt er ja irgendwelche grauslichen Dinge her (und der strlen ist dann auch hinüber)

schamp
22.08.2005, 12:15
Hab ich jetz gleich ausprobiert.
Mag irgendwie immer noch net. Die Initialisierung vom WD sollte eigentlich stimmen.
Macht der WD vielleicht schon ständig Resets und der Mega88 kommt net dazu den "Hello World"-String zu senden??
Wo kommt dann aber die 4 im Terminal her und eigentlich ist das Timeout ja auf 4 Sekunden gestellt.... :-k

schamp
22.08.2005, 12:27
Hab grad mit PORTD ^= (1<<PORTD5) und Oszi getestet wie weit der uC im Prog kommt...
In die for-Schleife (sende_routine) geht er noch, aber das SENDEROUTINE_M_OK Flag wird dann nimma gesetzt... :-s

edit: die initialisierungsroutine wird auch ständig gestartet.. also gibts ständig nen reset.. :cry:

PicNick
22.08.2005, 12:32
Aus dem Bauch heraus würd ich das auch sagen. Mir kommen 4 sek. seltsam lang vor. Bist du sicher wegen der Zeiteinstellung ? (Ich mag jetzt nicht nachlesen)
Immerhin, scheint ja, als würde er <CR><LF> ja noch rausbringen. Aber schon die blanks sind etwas seltsam. Vielleicht derklatscht ihn der WD mitten im Senden und das blank ist ein Empfangs-Wtlbrnft ?

schamp
22.08.2005, 12:40
Was isn ein Empfangs-Wtlbrnft ? :)

Die 4.0 Sec stimmen schon, ausm Datenblatt:

WDP3 WDP2 WDP1 WDP0
1 0 0 0

Number of WDT Oscillator / Cycles
512K (524288) cycles

Typical Time-out at VCC = 5.0V
4.0 s

hm geht net gscheid zum reinkopiern hier... aber ma verstehts scho oda?

PicNick
22.08.2005, 14:05
Was isn ein ...-Wtlbrnft
Es hat mal einen bayerischen Komiker gegeben, Karl Valentin


"Valentin mit "F" und nicht mit "W", man sagt ja auch nicht Wogel-Wau
Der hat den Ausdruck gebracht, das ist einfach irgendein unleserliches Zeugs

Egal.

Also irgendwie wird das Senden massakriert.
Tu' mal alle Extra-Würste auskommentieren und schau, ob dann auch "Hello" kommt.
Was auch mit dem WD sein mag, das senden muß ja schließlich zumindest richtig anfangen

schamp
22.08.2005, 14:46
Jo Karl Valentin kenn ich natürlich!! Komm aus der Nähe von MUC O:)
Bloß den Ausdruck "Wtlbrnft" kannte ich noch nicht, wieder was dazugelernt... :cheesy:

Hab ma alles Extrazeug rausgeschmissen. Empfangen beim SW UART war scho auskommentiert. Der kloane uC schaffts einfach net bis zum Ende, kommen immer noch die blanks und 4er..

Könnte noch schauen, wie weit er in den Software UART Routinen kommt. Aber is halt echt blöd, 4.0 Sec sind eingestellt und die würd er ja niemals für nen Hello World brauchen.... da müßt ich ja jetzt dann alle paar Befehle nen WD Reset reinhaun

PicNick
22.08.2005, 15:52
Und wenn man sich mal blöd stellt ?
send_one_byte('\r');
send_one_byte('\n');
send_one_byte('H');
send_one_byte('e');
send_one_byte('l');
send_one_byte('l');
.....
Sowas ist doch schon gegangen, grad das senden ?

Taktfrequenz ? (Oszi-einstellungen ?)

schamp
23.08.2005, 07:24
Wenn ichs so ausprobier schafft er genau 2 Zeichen,... dann is Sense 8-[

edit:
SW Uart allein funktioniert einwandfrei (auch oszieinstellungen stimmen), Irgendwas passt bei dem Watchdog nicht...
Hab die Initialisierung jetzt wie im Datenblatt (die Funktion heisst bei denen void WDT_Prescaler_Change(void))
Hilft aber trotzdem nix...


void watchdog_init(void)
{
__disable_interrupt();

MCUSR = 0; // Alle vorher gesetzten Flags clearen
Flag = 0;

sw_uart_init();

WDTCSR |= (1<<WDIF); // Clear WD Interrupt Flag

__watchdog_reset();

/* Setup Watchdog, bzw. Start timed sequence (wie im Datenblatt) */
WDTCSR |= (1<<WDCE) | (1<<WDE); // Watchdog Change Enable setzen


/* Set new prescaler(time-out) value (siehe Datenblatt) */
WDTCSR |= (1<<WDE) | (1<<WDP3); // Timeout auf 4.0 Sekunden setzen

__enable_interrupt();

//PORTD &=~ (1<<PORTD5);
}

Muss man den WD doch irgendwie anders initialisieren ??
Weis echt nich mehr weiter.. :-k

PicNick
23.08.2005, 08:28
Morgen ! Neuer Tag, neues Spiel, neues Glück !
Ich wollt mir der Watchdog genauer anschauen und stelle fest, ich find kein anständiges Datasheet, nur Preliminary.
Beim Mega32 gibts das WDTCSR überhaupt nicht.
Kannst du mir das komplette DS schicken oder posten ?
Mir ist nicht ganz klar, was der WD-Interrupt zu bedeuten hat

schamp
23.08.2005, 09:03
Hab auch nur das hier --> http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf
zum Mega88

Das mit dem Interrupt ist so, man kann den WD noch kurz vorm Reset ne ISR ausführen lassen um z.b. noch wichtige Parameter ins EEPROM zu speichern bevor der eigentliche Reset dann ausgeführt wird... (is dann quasi Interrupt Modus)

Will den WD aber im System Reset Modus betreiben, also nur Reset und sonst nüx...

PicNick
23.08.2005, 09:22
Das DS ist vieles besser ziemlich komplett

Ein Unterschied zu deinem Code:


/* Set new prescaler(time-out) value (siehe Datenblatt) */
WDTCSR |= (1<<WDE) | (1<<WDP3); // Timeout auf 4.0 Sekunden setzen



/* Set new prescaler(time-out) value (siehe Datenblatt) */
WDTCSR = (1<<WDE) | (1<<WDP3); // Timeout auf 4.0 Sekunden setzen


Also KEIN "oder"

nu?

schamp
23.08.2005, 09:45
*DOOHHH* :-b O:)
Ich krieg mich nimma, voll übersehen... sry!!!

WD macht keine Reset mehr!! Wenn jetzt Terminal nicht mehr so n Mist senden würd.... das H schreibt er, die anderen Zeichen passn von der Anzahl her stimmen aber von der Darstellung net.
Wenn ich versuch das hier reinzukopieren isses aufeinmal doch:
Hello, World

Verstehst was ich mein ??

PicNick
23.08.2005, 09:50
Wenn Großbuchstaben gehen, Kleinbuchstaben aber kryptisch werden, ist das Terminalprogramm normalerweise ins Schleudern geraten. (durch bin. Steuerzeichen)
Stoppen, neu Starten.

schamp
23.08.2005, 10:31
Stimmt :-s
Jetzt gehts einwandfrei, nachdem ich Terminalprogramm geschlossen und wieder gestartet hab =D>
Thx für die Hilfe, und wieder was dazugelernt !!!

Probier jetzt ma bischen absichtliche Delays aus mit dem WD

Gruß
schamp

EDIT:
Hier nochmal die fehlerfreie Source, falls es jemanden interessiert :cheesy:


#include <iom88.h>
#include <ina90.h>
#include <string.h>
#include "sw_uart.h"


void watchdog_init(void);
void sende_routine(void);
void health_check(void);

static char bTxt[24] = "\r\nHello, World\r\n";

unsigned char Flag;
#define SENDEROUTINE_M_OK 1

__task void main(void)
{
watchdog_init();

while(1)
{
sende_routine();

health_check(); // Am Ende der Hauptschleife prüfen, ob sende_routine() ordnungsgemäß ausgeführt
}
}


void watchdog_init(void)
{
__disable_interrupt();

MCUSR = 0; // Alle vorher gesetzten Flags clearen
Flag = 0;

sw_uart_init();

WDTCSR |= (1<<WDIF); // Clear WD Interrupt Flag

__watchdog_reset();

/* Setup Watchdog, bzw. Start timed sequence (wie im Datenblatt) */
WDTCSR |= (1<<WDCE) | (1<<WDE); // Watchdog Change Enable setzen


/* Set new prescaler(time-out) value (siehe Datenblatt) */
WDTCSR = (1<<WDE) | (1<<WDP3); // Timeout auf 4.0 Sekunden setzen

__enable_interrupt();
}


void sende_routine(void)
{
unsigned char bIx;
unsigned char bLn;

bLn = strlen(bTxt);

for (bIx = 0;bIx < bLn; bIx++)
{
send_one_byte(bTxt[bIx]);

// hier später delay um System Reset zu simulieren....
}

Flag |= (1<<SENDEROUTINE_M_OK); // Routine korrekt ausgeführt
}



void health_check(void)
{
if(Flag & (1<<SENDEROUTINE_M_OK)) // alles ok ?
{
Flag &=~ (1<<SENDEROUTINE_M_OK);

__watchdog_reset(); // dann Reset Watchdog
}
}

PicNick
23.08.2005, 10:50
Na super !

Also, bis dann

schamp
23.08.2005, 12:42
noch was ganz kurzes.. und zwar:
könnte ich auch
if(Flag & SENDEROUTINE_M_OK)

anstatt

if(Flag & (1<<SENDEROUTINE_M_OK))

??

PicNick
23.08.2005, 13:24
Nein, geht nicht
Da ist das eine Bit-Maske (_M_)
if(Flag & SENDEROUTINE_M_OK)
Da ist das eine Bit-Nummer (_V_)
if(Flag & (1<<SENDEROUTINE_M_OK))

SENDEROUTINE_M_OK is ja = 1
wäre dann
if ( Flag & SENDEROUTINE_M_OK) --> If (Flag & 1)
und
(1<<SENDEROUTINE_M_OK) --> (1 << 1) ---> 2 --> If (Flag & 2)


Edit: Schamperl ! Schaust du mal bei dir aus dem Fenster raus ? Vielleicht bist du längst abgesoffen und hast es nicht bemerkt ?

benites
10.12.2005, 17:35
Hallo schamp,
Ich habe gerade dein Code_Programm gesehen, und finde es klasse. das ist genau was ist brauche.
Aber ich wollte dich bitten, das folgende Datei zu posten:
#include "sw_uart.h"

vielen Dank im Voraus.
Benites

schamp
14.12.2005, 20:25
hm für den watchdog timer brauchste eigentlich net die "sw_uart.h"...
oder gehts dir um den software uart? welches "code programm" meinst du?
in der sw_uart.h sind nurn paar defines für den software uart drin (u.a. preloadwerte für den timer/counter0, sprich baudraten einstellung).
die defines sollten aber in dem sw_uart beispielprogramm, welches picnick und ich hier online gestellt haben, drin sein... hoffe ich zumindest 8-[

benites
15.12.2005, 18:15
hi schamp,
wie gesagt, ich habe deinen Code kompiliert, aber bekomme die folgende Fehlermeldung:

Fatal Error[Pe005]: could not open source file "sw_uart.h"

d.h, sw_uart.h muss man noch einbinden... :-(

Gruß
Benites

schamp
17.12.2005, 20:36
will ja nich blöde rüberkommen jetzt, aber gib mal etwas präzisere angaben was du eigentlich erreichen willst, bzw. welchen code du zum laufen bringen willst.
falls es um den watchdog geht:
da brauchst du den software-uart eigentlich garnicht. den hatte ich nur eingebunden um das "hallo welt" senden zu können. im prinzip kannst du das alles rausnehmen! der rest, watchdog initialisierung etc., sollte trotzdem funktionieren

gruß
schamp

btw: falls dich doch der software uart beschäftigt oder dich dafür interessierst schaust am besten https://www.roboternetz.de/phpBB2/dload.php?action=file&file_id=240