www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMEGA32 + Watchdog


Autor: Sara (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin am verzweifeln.
Ich programmiere z.Z. mit einem ATMEGA32 auf einem STK500 Board.

Habe ein einfaches Programm zur Datenübertragung mit der UART 
geschrieben.

Nun habe ich das Problem, dass mein Programm einen Reset auslöst sobald 
die Funktion zur Datenübertragung der UART eingebunden ist.

void uart_send(unsigned char c)
{
  while (!(UCSRA & (1<<UDRE)))
    {}
    UDR = c;
  return;
}

Der Reset erfolgt auch im AVR Studio Ver 4.14 Simulator, also kein HW 
Problem?

Nun gehe ich davon aus, dass der Watchdog eingreift.
Daraufhin habe ich

#include <avr/wdt.h>

eingwebunden und mit dem Befehl

wdt_disable();

den WD ausgeschaltet. Jedoch macht das weder auf dem Controller noch in 
der Simulation einen Unterschied.

Kann mir bitte jemand helfen, ich bin extrem verzweifelt weil ich schon 
seit Stunden davor hänge und einfach nicht weiterkomme :(

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moeglicherweise ist das WDTON-Fuse programmiert, dann ist der Wachhund 
immer aktiv.

Autor: Sara (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das gibt es aber meines Wissens nach nicht beim ATMEGA32. Weder im 
Datenblatt noch im AVR Studio ...

Im Datenblatt wird folgendes vorgeschlagen

void WDT_off(void)
{
/* reset WDT */
_WDR();
/* Write logical one to WDTOE and WDE */
WDTCR |= (1<<WDTOE) | (1<<WDE);
/* Turn off WDT */
WDTCR = 0x00;
}

Die Funktion

_WDR();

kennt AVR Studio irgendwie nicht ... wo finde ich die ... wenn ich sie 
auskommentiere klappt es zwar aber hat keine Einwirkung in der 
Simulation oder auf meinem Controller

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, gibt es nicht... muss also ein anderes Problem sein.

Autor: oha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich wuerd mal auf ASM-View schalten und die paar Befehle anschauen und 
steppen. Es sind ja hoechstens 5 ASM Befehle, die man eh koennen muss.

Autor: Michael Appelt (micha54)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

der häufigste Grund für so einen Reset sind falsche oder fehlende 
Interruptroutinen....meine Lieblingsfehler sind falscher Timer oder 
Overflow statt Compare

Gruß,
Michael

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Sara:

Ich bezweifel deine Analyse. Wäre es der Watchdog, würde er unabhängig 
vom Programm immer irgendwann zuschlagen, nur halt an unterschiedlichen 
Stellen. Wenn der "Reset" nur dann auftritt, wenn du die Funktion 
uart_send benutzt, ist es eher wahrscheinlich, dass du versehentlich den 
Transmission-Complete-Interrupt freigeschaltet hast.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde Stefan zustimmen.
Ansonsten findest du hier die Doku zur Beschreibung der Watchdog 
Routinen in der avr-libc:
http://www.nongnu.org/avr-libc/user-manual/group__...

Du müstest mal den kompletten Sourcecode posten, dann könnte man dir 
besser helfen.

900ss

Autor: Sara (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mein kleiner Testcode.

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

#define F_CPU 8000000L

int main(void)
{
  wdt_disable();

  DDRD |=  (1<<PD1);  //Initialisierung des UART Ports TXD
  DDRD &= ~(1<<PD0);  //Initialisierung des UART Ports RXD
  DDRA = 0xFF;

  UCSRB |=  (1<<TXEN)  | (1<<RXEN);
  UCSRB |=  (1<<TXCIE) | (1<<RXCIE);
  UBRRL = 25; //19200

  SREG =  (1<<7);    //Global Interrupts enable

  uart_send(0x14);

  while(1)
  {
      PORTA = 0x00;
      PORTA = 0xFF;
  }
}

void uart_send(unsigned char c)
{
  while (!(UCSRA & (1<<UDRE)))  // auf Senden warten
    {}
    UDR = c;
  return;
}


Am Temrinalprogramm wird anstatt 1x 0x14, ständig 0x14 ausgegeben :(
Verstehe nur noch Bahnhof. Den Atmega32 habe ich auch mal getauscht, 
ohne Erfolg.

Optimization steht auf Os
Wenn ich an der Zeile ->uart_send(0x14);<- einen Breakpoint in der 
Simulation setze, gelange ich dort auch immer wieder hin :(

Autor: dummy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  UCSRB |=  (1<<TXCIE) | (1<<RXCIE);

Lösch diese Zeile

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  UCSRB |=  (1<<TXCIE) | (1<<RXCIE);

Es ist genau das, was ich vermutet hatte. Du schaltest Interrupts frei, 
hast aber gar keine ISRs dafür.

Autor: Sara (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube das Problem ist, dass ich den Transmit Interrupt setze, aber 
keine Routine dafür angelegt habe ... danke für den Hinweis von Michael 
:)

Autor: Sara (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow, Du bist schnell :)
Vielen Dank dafür, da hätte ich noch einige Zeit gesucht ;)

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.