Hallo, ich habe ein Problem. Ich arbeite schon sehr lange mit Mikrokontrollern und programmiere diese in C. Ich wollte nun endlich mal auf den GCC umsteigen, dieser ist schließlich auch kostenlos und soll eigentlich ganz guten Code erzeugen. Mein Problem ist folgendes. Alles läßt sich compilieren, alles tutti. Schalte ich aber die Interrupts ein - mit sei(); - dann führt mein Mega8 ständig einen Reset aus. Vektortablle im Headerfile haben ich überprüft , scheint alles richtig zu sein. Kennt jemand das Problem. Ich arbeite mit WinAVR (neuste Version) und dem AVRStudio. Danke im voraus für einen guten Tipp. Thomas
@falk: Danke für den Tipp, aber MCUCR,TIMSK,GICR ist alles richtig eingestellt, Vektortabelle stimmt auch. Der gleich Code macht mit einem anderen Compiler keinen Reset. Der Reset schein ca. 10ms nach dem Start zu sein. WD ist es auch nicht. Fuses stimmen, WD habe ich extra im Code nochmal deaktiviert. Gruß, Thomas
Hey Geil. Ich verstehe, Du meinst ich soll solange in eine Glaskugel starren, bis ich so hypnotisiet bin, daß der Mega8 keinen Reset mehr macht ? Gruß, Thomas
Nein. Beziehe mich da auf den letzten Absatz und erwarte, dass du ebendies nicht von uns erwartest.
gibts auch keine Warnings wegen SIGNAL oder ISR Name? die Namen wurden mal geändert und es gab nur Warnings wenn es den Interrupt_xy nicht gab. Oder läuft noch ein Timer oder anderer Interrupt für den keine ISR existiert?
#include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> void uart0_init(void) { UCSRB = 0x00; //disable while setting baud rate UCSRA = 0x00; UCSRC = 0x86; UBRRL = 0x19; //set baud rate lo UBRRH = 0x00; //set baud rate hi UCSRB = 0xD8; } void putchar1(unsigned char c) { while (!(UCSRA&(1<<UDRE))); UDR=c; } void main(void) { char i; //init_devices(); uart0_init(); cli(); MCUCR = 0x00; WDTCR=0x00; GICR = 0x00; TIMSK = 0x00; //timer interrupt sources SEI(); i=100; putchar1(85); while(1) { i++; putchar1(i); if (i==120) i=100; _delay_ms(100); } } Das Programmiert springt nicht mal in die while-Schleife. Es macht einen Reset nach der Ausgabe eines "U"s (chr(85)). Es ist nur ein Testprogramm. Gruß, Thomas
Deine bisherigen Informationen reichen nicht aus und Antworten wären Wahrsagerei. Raff' mal zusammen, was du noch zur Problemstellung beitragen kannst: Schaltbild, Angaben zu Stromverbrauch und Stabilität der Spannungsversorgung, Makefile. Wenn du Probleme hast den aktuellen Quellcode zu veröffentlichen, dann strippe den soweit runter, dass man den ursprünglichen Zweck nicht mehr sieht aber trotzdem noch das Problem reproduziert werden kann. Hast du schon die Schoose im Simulator (AVR Studio) gehabt und treten dort ebenfalls Resets auf? ADD: Im vorhergehenden Code sehe ich keinen einzigen Interrupthandler!
???? Du gibst mit sei() die Interrupt frei, obwohl KEINERLEI Interruptroutine vorhanden ist? MfG Falk
> SEI();
Erstens ist c Case-sensitiv. Es heißt sei() und nicht SEI(). Zweitens
hast Du nirgends einen Interrupt Handler stehen. Da Du offensichtlich
auch keine Interrupts freigegeben hast: Was soll das sei überhaupt
bewirken?
Wird das sei(); auskommentiert dann passiert es nicht. Übrigens SEI() = makro asm("sei"); . Nicht wundern, daß es groß geschrieben ist. Habe nur die wesentlichen Teile gepostet. Der Rest von meinem Programm wird eh nicht ausgeführt. Ich habe den Verdacht, das die MCUCR,GICR etc. Einstellungen gar nicht ausgeführt werden. Vielleicht ist ein Fehler in der Definition des Mega8 vom WinAvr - iom8.h . Kann aber nichts entdecken. Vielmehr habe ich auch nicht gehofft, daß man das Problem hier löst. Sondern, daß jemand anderes genau das Problem schon mal hatte. Gruß, Thomas
Es gibt grössere Wunder. UCSRB = 0xD8; schaltet fast alle Interrupts ein die du finden konntest. Aber kein einziger davon ist implementiert. Klar dass ohne sei() nix passiert. Klar auch dass es mit sei() nicht lang funktioniert.
> _delay_ms(100);
Das geht in die Hose, sobald Deine Taktfrequenz größer ist als 2,62 MHz.
Aber das nur am Rande...
@Gerhard: Das ist ja der Witz, ich habe gar keine definiert. Er scheint nach dem sei(); was zu machen. Aber was ????
@Andreas Kaiser: Oh, das UCSRB hatte ich grad völlig übersehen... Dann ist natürlich fast vorprogrammiert, dass es knallt.
Analog wrote:
> Aber was ????
Irgendeinen der Interrupt-Vektoren aufrufen. Weil der mangels
Interrupt-Handler die Ursache des Interrupts aber nicht beseitigt, hast
du ein Problem.
@Andreas: Das war es , vielen Dank !!!!!!!!!!!!! Die anderen compiler sind da nicht so , aber ich habe folgenden (leeren) ISRs implentiert - kein Reset mehr ! SIGNAL (SIG_UART_RECV) { interrupt=1; cmd=UDR; UDR=cmd; //_inline_fifo_put (&infifo, UDR); } SIGNAL(USART_TXC_vect) { } SIGNAL (USART_UDRE_vect) { } Danke nochmal an alle die geantwortet haben.
Bitte nicht SIGNAL verwenden. Das ist veraltet. Nimm ISR. Und nen leeren Handler kannste auch mit
1 | EMPTY_INTERRUPT(USART_UDRE_vect); |
machen... Bei anderen Compilern kann es höchstens sein, dass die bei Vektoren, zu denen keine Handler existieren, einfach ein reti reinschreiben statt des Aufrufs des "bad interrupt"-Handlers, der dann (beim AVR-GCC) defaultmäßig einen jump nach 0x0000 macht...
Analog wrote: > @Gerhard: Das ist ja der Witz, ich habe gar keine definiert. Er scheint > nach dem sei(); was zu machen. Aber was ???? Nicht nach dem sei() Beim Auftreten des Interrupts. Der gcc baut einen Default Interrupt Handler ein, der - man staune - den Prozessor resettet. Dieser Interrupt Handler kommt defaultmäßig auf alle Interruptvektoren. Erst wenn du selbst einen Interrupt Handler implementierst löst der den dafultmaßigen ab. Da du keinen eigenen Handler hast - tja, Pech für die Kuh Elsa.
@Johannes: das mit SIGNAL, ISR habe ich irgendwo gelesen. Mache ich. Freue micht total auf die Arbeit mit dem GCC. :) Der Code scheint sogar schneller abzulaufen als mit dem gekauften Compiler.
Was du natürlich auch machen könntest: Nur diejenigen Interrupts einzuschalten und mit sinnvollen Handlern versehen, die du tatsächlich benötigst. So macht man das nämlich normalerweise.
@kbucheqq: Verstehe, dann löse ich diesen mit dem Putchar1-Kommando selber aus. Und da die ISR - USART_TXC_vect ausgelöst wird , gibt es einen default handler jmp 0x0000 oder so ähnlich !? Egal erstmal hauptsache es geht jetzt.
Analog wrote: > @kbucheqq: Verstehe, dann löse ich diesen mit dem Putchar1-Kommando > selber aus. Und da die ISR - USART_TXC_vect ausgelöst wird , gibt es > einen default handler jmp 0x0000 oder so ähnlich !? Ganz genau so ist der Ablauf. Ich glaub jetzt hat er's.
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.