Watchdog Reset Fehler

Gast #3427466
Lesenswert?

Hey,

Ich habe ein Problem mit dem Watchdog Reset des ATmega644. Ich möchte an 
einer beliebigen Programmstelle einen Reset des AVRs bewirken und nutze 
dafür den WDT. Das sieht recht simpel aus:

wdt_enable(WDTO_15MS);
while(1); //Reset sollte nach 15ms erfolgen

Das tut er dann auch. Neu starten tut er dann allerdings nicht mehr, 
selbst wenn ich ganz am Beginn der main()

wdt_disable();

einfüge. Vielleicht sollte ich diesen Fehler etwas erklären: Es scheint 
schon ein Start durchgeführt zu werden, das Backlight vom LCD welches in 
ansteuere fängt wie wild an zu flackern (sollte eigentlich einfach nur 
eingeschaltet werden) und das wars dann auch schon. Dieser Zustand 
bleibt erhalten, von einem normalen Programmstart nicht zu reden. Selbst 
bei manuelem Reset wird nach auftreten dieses Fehlers das Programm nicht 
mehr richtig gestartet. Erst nachdem VCC einige Sekunden weg ist und 
dann wieder angelegt wird startet das Programm ordnungsgemäß.

Hat jemand eine Idee?
Gast #3427479
Lesenswert?

Das ist weder witzig noch bringt es irgendjemanden weiter. Ich kann den 
Code hier gerne posten aber aus viel mehr als den 3 Zeilen und der LCD 
Initialisierung, die einwandfrei funktioniert, besteht der nunmal nicht.
Gast #3427499
Lesenswert?

Ich habe den Code nun wie folgt reduziert:

int main()
{
    wdt_disable();
    DDRD|=(1<<PD7);

    PORTD&= ~(1<<PD7);
    _delay_ms(1000);
    PORTD |= (1<<PD7);
    _delay_ms(1000);
    wdt_enable(WDTO_15MS);
    while(1);
}

Hiernach sollte die am PD7 angeschlossene LED mit ca. 1Hz blinken, das 
tut sie allerdings nicht. main() wird nur einmal korrekt ausgeführt, 
danach bleibt die LED aus.
Gast #3427504
Lesenswert?

Jabu schrieb:
> Ich habe den Code nun wie folgt reduziert:
>
> int main()
> {
>     wdt_disable();
>     DDRD|=(1<<PD7);
>
>     PORTD&= ~(1<<PD7);
>     _delay_ms(1000);
>     PORTD |= (1<<PD7);
>     _delay_ms(1000);
>     wdt_enable(WDTO_15MS);
>     while(1);
> }
>
> Hiernach sollte die am PD7 angeschlossene LED mit ca. 1Hz blinken, das
> tut sie allerdings nicht. main() wird nur einmal korrekt ausgeführt,
> danach bleibt die LED aus.

Aus dem Tutorial:

Bei neueren AVR-Typen bleibt der Watchdog auch nach einem Reset durch 
den Watchdog aktiviert. Wenn ein Programm nach dem Neustart bis zur 
erstmaligen Rückstellung des Watchdogs länger braucht, als die im 
Watchdog eingestellte Zeit, sollte man den Watchdog explizit möglichst 
früh deaktivieren. Ansonsten resetet der Watchdog den Controller 
immerfort von Neuem. Die frühe Deaktivierung sollte durch eine Funktion 
erfolgen, die noch vor allen anderen Operationen (insbesondere vor dem 
mglw. länger andauernden internen Initialisierungen vor dem Sprung zu 
main()) ausgeführt wird. Näheres zur Implementierung mit 
avr-gcc/avr-libc findet sich in der Dokumentation der avr-libc 
(Suchbegriffe: attribut, section, init).

Versuch mal die Zeit hoch zu stellen.
Gast #3427512
Lesenswert?

Bei mir kompiliert dieser Code wunderbar, ich habe alle anderen 
Programmteile bis auf dieses main rausgenommen. Auch habe ich nun die 
WDT Zeit auf 500ms hochgesetzt, ohne Unterschied. Auch MCUSR = 0; folgt 
jetzt gleich auf wdt_disable, ohne Änderung.
Gast #3427520
Lesenswert?

Vollständigkeitshalber hier nochmal der an den bisherigen Kommentaren 
verbesserte, nicht funktionierende Code:

#include <avr/io.h>
#include <avr/wdt.h>

int main()
{
    wdt_disable();
    MCUSR = 0;        //Nachgebessert (Interrupt Flag Reset)
    DDRD|=(1<<PD7);

    PORTD&= ~(1<<PD7);
    _delay_ms(1000);
    PORTD |= (1<<PD7);
    _delay_ms(1000);
    wdt_enable(WDTO_500MS);  //Nachgebessert auf 500ms
    while(1);
}
Gast #3427524
Lesenswert?

Versuch mal ohne den wdh.h auf manuellen weg.
1
//einschalten
2
MCUSR = (1<<WDRF);
3
WDTCSR = (1<<WDE); // keine Prescale 16ms
4

5
//ausschalten
6
MCUSR = 0;
7
WDTCSR = 0;

Datenblatt s.53 es gibt keine 15ms.
Dann die Fuse WDTON keinen Haken setzen.
Gast #3427537
Lesenswert?

int main()
{
    //wdt_disable();
  //ausschalten
  MCUSR = 0;
  WDTCSR = 0;

    DDRD|=(1<<PD7);

    PORTD&= ~(1<<PD7);
    _delay_ms(1000);
    PORTD |= (1<<PD7);
    _delay_ms(1000);
    //wdt_enable(WDTO_500MS);
  //einschalten
  MCUSR = (1<<WDRF);
  WDTCSR = (1<<WDE); // keine Prescale 16ms
    while(1);
}

Keine Besserung. WDTON Fuse wird vom AVR Studio 5 Programmer als 0 
gelesen.
Gast #3427540
Lesenswert?

Oliver schrub:
> Wahrscheinlich das hier am Anfang der Datei:

Es ist uninteressant was es ∗wahrscheinlich∗ ∗ungefähr∗ ist - der TO 
soll mit seinem ∗echten∗ Code rausrücken, sonst ist das nur Fischen im 
Nebel.

Zum echten Code zählt alles, nicht nur etwas das ungefähr ein bisschen 
fast so ähnlich aussieht.
Gast #3427560
Lesenswert?

Um sämtliche fehlerhaften Einflüsse auszuschließen habe ich ein neues 
Projekt angelegt in dem nichts weiter als folgendes steht:

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

#define F_CPU = 8000000

int main()
{
    wdt_disable();
    MCUSR = 0;        //Nachgebessert (Interrupt Flag Reset)
    DDRD|=(1<<PD7);

    PORTD&= ~(1<<PD7);
    _delay_ms(1000);
    PORTD |= (1<<PD7);
    _delay_ms(1000);
    wdt_enable(WDTO_500MS);  //Nachgebessert auf 500ms
    while(1);
}

WDTON Fuse habe ich testweise auf 1 gesetzt, die LED bleibt dan 
dauerhaft aus. Wenn diese auf 0 ist geht sie wie vorher bereits nur 
einmal an.
Gast #3427564
Lesenswert?

A. K. schrieb:
> Steffen schrieb:
>> naja muss man testen.
>
> Ist eindeutig. Um WDE zurückzusetzen muss WDCE gesetzt sein. Hat ja auch
> einen Sinn, das soll nicht aus versehen geschehen dürfen.
>
> Er soll mal ruhig beim wdt_reset() bleiben.

Naja sollte ja ein Test sein ob es vielleicht an der wdt.h liegt. So 
weit wie ich das gelesen habe macht er keinen wdt_reset irgendwie... tut 
ja auch sonst wie Geheimsnissvoll um den Quelltext. Nuja jetzt sind wir 
bei der Minimalanforderung und beim Lernen wie der WDT funktioniert 
angekommen :-D
Gast #3427573
Lesenswert?

Fuse habe ich als 0 und auch als 1 getestet. Als 0 leuchtet die LED 
einmal auf, als 1 bleibt alles dunkel.

@ Steffen:
Ich möchte auch keinen wdt_reset() machen, ich möchte den AVR 
softwareseitig zum reset zwingen und das funktioniert nach meinem Wissen 
nur über den WDT Reset. Wen du eine bessere Methode kennst bitte teile 
sie mir mit.
Gast #3427592
Lesenswert?

Jabu schrieb:
> Fuse habe ich als 0 und auch als 1 getestet. Als 0 leuchtet die LED
> einmal auf, als 1 bleibt alles dunkel.
>
> @ Steffen:
> Ich möchte auch keinen wdt_reset() machen, ich möchte den AVR
> softwareseitig zum reset zwingen und das funktioniert nach meinem Wissen
> nur über den WDT Reset. Wen du eine bessere Methode kennst bitte teile
> sie mir mit.

Aach ja....
Die LED kann ja nicht an gehn, nach 16ms kommt der Reset die macht das 
so schnell das man das nicht sieht. Stell mal den WDT auf 1s
Gast #3427604
Lesenswert?

Letzter Stand des Programms:

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

#define F_CPU 8000000

int main()
{
    MCUSR = 0;
    wdt_disable();
    DDRD|=(1<<PD7);

    PORTD&= ~(1<<PD7);
    _delay_ms(1000);
    PORTD |= (1<<PD7);
    _delay_ms(1000);
    wdt_enable(WDTO_500MS);
    while(1);
}

Getestet mit WDTON Fuse 0/1 (Wobei Haken raus die korrekte Belegung zu 
sein scheint, bezogen auf AVRStudio 5.0 ISP Programmer), VCC jeweils 
mehrere Sekunden weggenommen nach programmieren von den Fuses, Problem 
besteht weiterhin.

Danke für die große Resonanz und die viele Vorschläge, hier nurmal kurz 
eingeschoben.
Gast #3427606
Lesenswert?

A. K. schrieb:
> Steffen schrieb:
>> Die LED kann ja nicht an gehn, nach 16ms kommt der Reset die macht das
>> so schnell das man das nicht sieht. Stell mal den WDT auf 1s
>
> Du hängst etwas. Er steht schon bei 500ms. Ausserdem ist für die Dauer
> der LED das Delay zuständig.

ja das simmt, der Tatort lenkt mich ab. Also ich würder bei der 
manuellen WDT Routine bleiben und am Anfang alles ausschalten. Dann das 
Programm laufen lassen und dann den Reset Starten. Das muss gehen. 
Wichtig die Fuse auf 1
Gast #3427621
Lesenswert?

Habe den ISP Stecker jeweils abgezogen. Das einzige was ich mir hierzu 
noch vorstellen kann ist, dass es sich um irgendeinen Hardwarefehler 
handelt, auch wenn ich diesen Controller in seiner Umgebung schon Wochen 
problemlos programmiere. Ich werde morgen mal ein anderes Board 
ausprobieren, vielleicht ergibt sich da was.
Gast #3427624
Lesenswert?

Jabu schrieb:
> Habe den ISP Stecker jeweils abgezogen. Das einzige was ich mir hierzu
> noch vorstellen kann ist, dass es sich um irgendeinen Hardwarefehler
> handelt, auch wenn ich diesen Controller in seiner Umgebung schon Wochen
> problemlos programmiere. Ich werde morgen mal ein anderes Board
> ausprobieren, vielleicht ergibt sich da was.

Naja oder das Programm (diesen Testcode) in einem komplett neuen Project 
erstellen.
Gast #3427628
Lesenswert?

Jetzt tun Sie mir doch den Gefallen und belegen, wie schon vor 
anderthalb Stunden vorgeschlagen, und auch nur als Schuss ins Blaue 
hinein, den Watchdog-Interrupt, wie auch immer das in C aussieht.
Dann kann ich nämlich endlich zu Bett gehen, die Nachtschwester meckert 
schon.
Gast #3427639
Lesenswert?

Wie der in C aussieht weiß ich leider genauso wenig und bevor ich da 
jetzt etwas hinklatsche werde ich das lieber die tage mal ausprobieren, 
Dennoch danke für die Idee. Wundern tut es mich trotzdem warum es nicht 
ohne zu gehen scheint...
#3427736
Lesenswert?

1
#ifndef F_CPU
2
  #error F_CPU not defined.
3
#endif
4

5
#include <avr/io.h>
6
#include <avr/wdt.h>
7
#include <util\delay.h>
8

9
int main(void)
10
{  
11
  MCUSR &= ~(1<<WDRF);
12
  wdt_disable();
13

14
  DDRD |= (1 << 7);
15

16
  for(unsigned char nInd = 0; nInd < 20; nInd++)
17
  {
18
    PIND |= (1 << 7);
19
    _delay_ms(50);
20
  }
21

22
  wdt_enable(WDTO_1S);  
23

24
  while(1)
25
  {
26
    PORTD &= ~(1 << 7);    
27
  }
28
}

Led blinkt 1s, leuchtet 1s, Watchdog schlägt zu, Spiel beginnt von vorn.

Ist die Watchdog-Fuse gesetzt, schlägt der Watchdog 16ms nach Reset zu, 
löst einen Reset aus... Die LED blinkt heftig.

Wenn das nicht so ist, ist deine Schaltung im A..., der Controller 
kaputt oder irgend jemand zu doof für diese Welt.

mfg.
Gast #3427756
Lesenswert?

Was machst du da mit PIND? Und warum läuft die for-Schleife um 20 mal 
eine Warteschaleife aufzurufen? Wie kommt es dass du PORTD &= ~(1 << 7) 
wieder und wieder in der while-schleife auf 0 setzt?

Ich habe das Programm so aufgespielt und es zeigt sich das gleiche wie 
mit dem anderen. Kein blinken. Hast du das Programm auf einem AVR 
getestet?
#3427771
Lesenswert?

Jabu schrieb:
> Ich habe das Programm so aufgespielt und es zeigt sich das gleiche wie
> mit dem anderen. Kein blinken. Hast du das Programm auf einem AVR
> getestet?

Gibts irgendwelche Fehler oder Warnungen, die "völlig unwichtig" sind? 
Es ist auch garantiert der richtige Controller und die Hardware hat 
alles, was das hiesige Tutorial empfiehlt?

Soll heissen: Mach mal ein Bild vom Aufbau.
#3427773
Lesenswert?

Jabu schrieb:
> Was machst du da mit PIND?
Toggeln.

> Und warum läuft die for-Schleife um 20 mal eine Warteschaleife
> aufzurufen?
Damit es 20 Mal blinkt.

> Wie kommt es dass du PORTD &= ~(1 << 7)
> wieder und wieder in der while-schleife auf 0 setzt?
Das PORTD &= ~(1 << 7) kann auch vor der while-Schleife stehen. Aber dem 
Controller ist das sowas von egal...

> Ich habe das Programm so aufgespielt und es zeigt sich das gleiche wie
> mit dem anderen. Kein blinken. Hast du das Programm auf einem AVR
> getestet?
Ja.

Übliche Fehler:
CKDIV8-Fuse gesetzt?
Falsches Hex-File geflasht?
Ich mache alles richtig!

Aber dann würde es laufen.

mfg.
Gast #3427778
Lesenswert?

Das Problem hat sich gelöst. Es hatte tatsächlich mit dem programmieren 
der FUSE bits zu tun, diese Programmierung wurde wohl nicht korrekt 
ausgeführt und eine unscheinbare Fehlermeldung ist erschienen.

Danke nochmal für die Hilfe.
Gast #3427792
Lesenswert?

Jabu schrieb:
> Das Problem hat sich gelöst. Es hatte tatsächlich mit dem programmieren
> der FUSE bits zu tun, diese Programmierung wurde wohl nicht korrekt
> ausgeführt und eine unscheinbare Fehlermeldung ist erschienen.
>
> Danke nochmal für die Hilfe.

Das ist nicht dein Ernst.

A. K. schrieb:
> Naja, glauben wir das mal... ;-)

Ich nicht so wirklich.

Mir ist da glaub ich noch n Fehler aufgefallen mit der while(1);

Jabu schrieb:
> Letzter Stand des Programms:
>     while(1);

Sollte das nicht so aussehen?
1
while(1) {}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren