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 :(
Moeglicherweise ist das WDTON-Fuse programmiert, dann ist der Wachhund immer aktiv.
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
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.
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
@ 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.
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
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 :(
> UCSRB |= (1<<TXCIE) | (1<<RXCIE);
Es ist genau das, was ich vermutet hatte. Du schaltest Interrupts frei,
hast aber gar keine ISRs dafür.
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 :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.