Forum: Compiler & IDEs wie ATMega644- Watchdog ohne Headerdatei betreiben?


von Egon M. (kpc)


Lesenswert?

Hallo,

der Watchdog-Timer des ATMega644 läßt sich nur mittels der Headerdatei 
wdt.h konfigurieren - aber nicht durch Manipulation der zugehörigen 
Register.
Letzeres muß ich aber tun, weil der WD nur einen Interrupt und keinen 
Reset auslösen soll. Mit der Headerdatei wdt.h läßt sich das nicht 
konfigurieren.

Bei meinen allerersten Exercietien mit dem ATMega644 ist mir allerdings 
aufgefallen, daß schon beim Konfigurieren eines normalen Resets 
Seltsames geschieht, wenn man die Register direkt beschreibt.

Ich füge eine kurze Programmsequenz an, wo der Watchdog zunächst ein 
Delay überdauern muß und schließlich in eine Endlosschleife gerät, die 
er abbrechen soll:


#include <avr/io.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>

void wd_start(void)
{
//  wdt_reset();             // aus wdt.h
   MCUSR  &= ~(1<<WDRF);     // sicherheitshalber, für WDE-Manipulation
   WDTCSR |= (1<<WDCE) | (1<<WDE);  // muß zur Manipulation an WDE
                                     //gesetzt sein
   WDTCSR |= (1<<WDE) | (1<<WDP3) | (1<<WDP0); // Watchdog-mode u.
                                               //timeout setzen; hier:
  return;                                      // Totalreset u. 8,0 s
}


int main(void)
{
     wd_start();     // Mit wd_start() (= Registermanipulation) bleibt
                     // das Programm in der Schleife hängen, mit dem
                     // Headerbefehl wdt_enable(7) funktioniert es,
                     // wie sein soll; das Delayglied darf 2000ms sein.

//   wdt_enable(7);
    _delay_ms(10);     // delay bei wd_start nicht über 10ms! (Soll 8,0 
s!)


   MCUSR  &= ~(1<<WDRF);// als wdt-reset zu gebrauchen, Manual (S52) 
unklar
// wdt_reset();         // alternativ aus Headerdatei



   DDRA = 3;
   while (1)        //  ewige Schleife, sollte durch den WDT verlassen
                    //  werden
   {
   PORTA = 3;
   _delay_ms(35);
   PORTA = 0;
   _delay_ms(35);
   }
   return 0;
}

Also, mit wdt_enable(x) läuft es bestens, mit den Registern direkt 
(=wd_start) bleibt es in der Endlosschleife hängen.
Kann jemand beurteilen, ob meine Manual-Interpretation falsch ist und 
wie man den ATMega644 zu einem Watchdog-Interrupt bringen kann, wenn 
nicht mal der Reset richtig zu funktionieren scheint.
Oder muß man einen anderen Prozessor nehmen (welchen)?

Viele Grüße
Egon

von Oliver (Gast)


Lesenswert?

>   MCUSR  &= ~(1<<WDRF);     // sicherheitshalber, für WDE-Manipulation

macht was völlig anderes, als wd_reset().

Warum schaust du dir nicht einfach die Doku der avr-libc und dazu den 
Source-Code in wdt.h an? Das hätte dir sofort gezeigt, was wd_reset() 
tatsächlich macht. Und selbst, wenn da nicht direkt die Unterstützung 
für den Interrupt_mode drin steckt, als Ausgangsbasis für eigenen Code 
ist das allemal besser, als völlig neu von vorne anzufangen.

Oliver

von gast (Gast)


Lesenswert?

steht das so im 644 manual ?

hmm es gab AVRs da klappte das mit der wdt.h der LIB nicht richtig
ich bastel mit einem 2561 .. da muss man auch manuell ausschalten sonst 
crasht er wieder beim start


ich würde dazu das datenblatt nochma durchackern

im datenblatt selber stehen bsp codes für C drin die man nehmen kann

von Egon M. (kpc)


Lesenswert?

Oliver schrieb:
>>   MCUSR  &= ~(1<<WDRF);     // sicherheitshalber, für WDE-Manipulation
>
> macht was völlig anderes, als wd_reset().
>
> Warum schaust du dir nicht einfach die Doku der avr-libc und dazu den
> Source-Code in wdt.h an?

Habe ich gleich zu anfang, bin aber leider nicht so recht schlau daraus 
geworden, deshalb habe ich gem. Manual:
...WDRF The bit is reset by ..... or by writing a logic zero to the 
flag.

Die habe ich als reset interpretiert, deshalb die Manipulation am MCUSR. 
Bin mir aber nicht sicher.

> ...snip..... als Ausgangsbasis für eigenen Code
> ist das allemal besser, als völlig neu von vorne anzufangen.
>
> Oliver

Ist kein eigener Code, ist wortwörtlich aus dem Manual abgeschrieben (S. 
50ff).
Gruß
Egon

von Egon M. (kpc)


Lesenswert?

gast schrieb:
> steht das so im 644 manual ?

>
> ich würde dazu das datenblatt nochma durchackern
>
Kenne ich nun fast auswendig

> im datenblatt selber stehen bsp codes für C drin die man nehmen kann

Leider nicht ausfühlich genug, z.B. steht nichts für Reset, die 
empfehlen selbst den __watchdog_reset() aus irgendeiner spezifischen 
Headerdatei.
Hier bei WinAVR-gcc heißt der Befehl wdt_reset() (funktioniert 
einwandfrei).
Dann noch der Hinweis, daß man WDRF in MCUSR löschen könne.

Ich werde mal allüberall die WDT-Initialisierungsroutine hinschreiben, 
denn  wenn der WD anspricht, dann verstellt er wohl die Zeitkonstante 
(auf den kürzestmöglichen Wert 16ms).

Übrigens gibt es bei Atmel ein App-Notiz (App 132???) - mit schönen 
Diagrammen, aber keinen C-Code, den man anpassen und übernehmen könnte.

Viele Grüße
Egon

von Oliver (Gast)


Lesenswert?

>...WDRF The bit is reset by ..... or by writing a logic zero to the
>flag.

>Die habe ich als reset interpretiert, deshalb die Manipulation am MCUSR.
>Bin mir aber nicht sicher.

WDRF ist das Bit im MCUSR-Register, das anzeigt, daß ein WD-Reset 
stattgefunden hat. Das Bit kann man durch schreiben einer logischen eins 
löschen.

wd_reset() setzt den Zählerstand des watchdog-timers zurück auf 0 (das 
ist ja nichts anderes als ein Timer/Counter). Dazu gibt es den 
(Assembler-)Befehl WDR. Der Sinn liegt wohl darin, zu verhindern, daß 
der watchdog zufällig innerhalb der folgenden Befehle zuschlägt, in 
denen er neu konfiguriert werden soll.

Oliver

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.