Forum: Mikrocontroller und Digitale Elektronik ATMEGA32 + Watchdog


von Sara (Gast)


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 :(

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Moeglicherweise ist das WDTON-Fuse programmiert, dann ist der Wachhund 
immer aktiv.

von Sara (Gast)


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

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

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

von oha (Gast)


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.

von Michael A. (micha54)


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

von Stefan E. (sternst)


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.

von 900ss (900ss)


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__avr__watchdog.html

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

900ss

von Sara (Gast)


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 :(

von dummy (Gast)


Lesenswert?

>  UCSRB |=  (1<<TXCIE) | (1<<RXCIE);

Lösch diese Zeile

von Stefan E. (sternst)


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.

von Sara (Gast)


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 
:)

von Sara (Gast)


Lesenswert?

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

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.