mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega128 --> Watchdog Komisches Verhalten nach POR


Autor: Detlev Neumann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich habe zum Test folgenden code geschrieben Nach dem Einschalten der 
Versorgungsspannung durchläuft der Controller zweimal den Code obwohl 
ich
nach meinem dafür halten den Controller in der Endlosschleife festhalten 
müsste und das schon beim ersten mal. (Gemesse mit meinem Ozi am 
Port-Pin ).

Mache ich was falsch übersehe ich was??

#define wdt_reset()  asm("wdr")


void enable_Watchdog(void)
{
  //Watchdog
   WDTCR &= ~( (1<<WDCE);
   WDTCR |=  ( 1 << WDE)|(1 << WDP2)| (1 << WDP1) | (1 << WDP0);
   NOP();
   NOP();
   NOP();
   wdt_reset();
 }

void main(void)
{
  unsigned int c;  
 
  init();  //initialisiert Port-Pins
  enable_Watchdog();
  PORTB &=~0x40; 
  c=50;
  do{c--;} while(c);
  PORTB |= 0x80;
  do{c--;} while(c);
  PORTB &=~0x40; 

  do{wdt_reset();} while(1);
}


Danke

Detlev

P.S. ich verwende den IAR - Compiler

Autor: Pothead (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs mal hiermit. Denke aber, dass das Problem woanders liegt. Was 
passiert wenn du den WDT nicht aktivierst?
#define wdt_reset()  asm("wdr")


void enable_Watchdog(void)
{
  //Watchdog
   WDTCR &= ~( (1<<WDCE);
   WDTCR |=  ( 1 << WDE)|(1 << WDP2)| (1 << WDP1) | (1 << WDP0);
   NOP();
   NOP();
   NOP();
   wdt_reset();
 }

void main(void)
{
  unsigned int c;  
 
  init();  //initialisiert Port-Pins

  enable_Watchdog();

  PORTB &=~0x40;

  c=50;

  do
  {
    c--;
    wdt_reset();
  } 
  while(c);

  PORTB |= 0x80;

  do
  {
    c--;
    wdt_reset();
  }
  while(c);

  PORTB &=~0x40; 

  do{wdt_reset();} while(1);
}


Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, wenn der Compiler auch nur halbwegs diesen Namen verdient, wird er 
die beiden "do{c--;} while(c);" Zeilen komplett wegrationalisieren. 
Sollte er das aus Versehen nicht tun, dann überleg mal, wie viele 
Durchläufe die zweite Schleife wohl macht und wie lange das dauert.

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Sollte er das aus Versehen nicht tun, dann überleg mal, wie viele
Durchläufe die zweite Schleife wohl macht und wie lange das dauert.


Hmmm, alle drei Bits beim Prescaler gesetzt wären beim ATmega8 > 2s.
Das wird wohl beim '128er' auch nicht wesentlich anders sein.

Da müsste der Controller schon mit einer Pendeluhr getaktet werden um in 
einen WD-Reset zu laufen ;-)

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde allerdings folgendermassen initialisieren:

WDTCR = (1<<WDCE);
WDTCR = (1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1 << WDP0);

oder noch einfacher:

http://www.nongnu.org/avr-libc/user-manual/group__...

#include <avr/wdt.h>

wdt_enable(WDTO_2S);

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vor dem Enablen des Watchdogs sollte ein wdt_reset() eingefügt werden. 
Der Watchdog-Prescaler läuft nämlich auch dann, wenn kein Enable 
vorliegt und kann sonst irgendwo stehen.

Die NOPs nach dem Enable in Verbindung mit dem nachfolgenden wdt_reset() 
haben dagegen keinen für mich erkennbaren Sinn.  Auch sollten während 
des Watchdog Enable die Interrupts gesperrt werden, wenn dies nicht 
anderweitig gesichert ist.

Übrigens, falls nicht so gewollt:  Die zweite while(c)-Schleife 
durchläuft den vollen Bereich einer Integer und nicht nur 50 
Schleifendurchläufe wie die erste (so sie überhaupt ausgeführt wird - 
ich habe mit Keil nur in uralten 8051-Zeiten gearbeitet, damals konnte 
er die sinnlose Schleife noch nicht erkennen).

Autor: Detlev Neumann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke ich versuche mal eure gedanken für mich umzusetzten

aber bei der zweiten schleife muss c=50 vorstehen habe es aber nur
vergessen abzuschreiben mein fehler

@Norbert leider kann ich die gcc Lib in IAR kompiler nicht verwenden 
(oder ich mache etwas dabei falsch

Danke für die Hilfe

Detlev

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Detlev Neumann schrieb:
> gcc Lib

Du meinst die avrlibc. Aber wenn ich das in der wdt.h richtig übersetzt 
hab, kommt da aus "wdt_enable(WDTO_2S);" etwa folgendes raus:
#define wdt_reset() __asm__ __volatile__ ("wdr")

  wdt_reset();
  WDTCR = (1 << WDCE) | ( 1 << WDE);
  WDTCR = (1 << WDE) | (1 << WDP2)| (1 << WDP1) | (1 << WDP0);
Das Original machts halt via inline Assembler und sperrt vorrübergehend 
noch die Interrupts (falls enabled).
Siehe hier:
http://www.nongnu.org/avr-libc/user-manual/group__...
http://www.nongnu.org/avr-libc/user-manual/wdt_8h_...

Autor: Detlev Neumann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke dem Mann ohne Namen es Funktioniert jetzt

Gruß

Detlev

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.