Forum: Mikrocontroller und Digitale Elektronik AVR Mega8 mit GCC, Interrupts


von Analog (Gast)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?


von Analog (Gast)


Lesenswert?

@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

von Andreas K. (a-k)


Lesenswert?


von Analog (Gast)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

Ein Quelltext als Anhang wäre nicht verkehrt . . .

von Andreas K. (a-k)


Lesenswert?

Nein. Beziehe mich da auf den letzten Absatz und erwarte, dass du 
ebendies nicht von uns erwartest.

von Jojo S. (Gast)


Lesenswert?

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?

von Analog (Gast)


Lesenswert?

#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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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!

von Falk B. (falk)


Lesenswert?

????
Du gibst mit sei() die Interrupt frei, obwohl KEINERLEI Interruptroutine 
vorhanden ist?

MfG
Falk

von Johannes M. (johnny-m)


Lesenswert?

> 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?

von Gerhard (Gast)


Lesenswert?

Wo ist denn die Interupt-Routine definiert?

von Analog (Gast)


Lesenswert?

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

von Andreas K. (a-k)


Lesenswert?

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.

von Johannes M. (johnny-m)


Lesenswert?

> _delay_ms(100);
Das geht in die Hose, sobald Deine Taktfrequenz größer ist als 2,62 MHz. 
Aber das nur am Rande...

von Analog (Gast)


Lesenswert?

@Gerhard: Das ist ja der Witz, ich habe gar keine definiert. Er scheint 
nach dem sei(); was zu machen. Aber was ????

von Johannes M. (johnny-m)


Lesenswert?

@Andreas Kaiser:
Oh, das UCSRB hatte ich grad völlig übersehen... Dann ist natürlich fast 
vorprogrammiert, dass es knallt.

von Andreas K. (a-k)


Lesenswert?

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.

von Analog (Gast)


Lesenswert?

@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.

von Johannes M. (johnny-m)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Analog (Gast)


Lesenswert?

@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.

von Andreas K. (a-k)


Lesenswert?

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.

von Analog (Gast)


Lesenswert?

@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.

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.