mikrocontroller.net

Forum: Compiler & IDEs sei(); führt zu Absturz


Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Versuche gerade einen Interrupt auf meinem Mega16 zu programmieren, aber 
leider stürzt mein Programm immer ab wenn ich sei(); aufrufe (der µC 
startet neu/hängt sich auf).

Ich habe Timer2 so initialisiert:

TCCR2 = (1<<CS22) | (1<<CS21) | (1<<CS20) | (1<<WGM21);
OCR2 = 0x0012;
TIMSK |= (1<<OCIE2);

Dazu dann dann der Interrupt:

ISR(SIG_OUTPUT_COMPARE2)
{
  lcd_writeChar('T');
}

Woran könnte das liegen?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Bernd (Gast)

>Woran könnte das liegen?

Du hast den falschen interrupt erwischt. Und SIG_xxx ist der falsche 
Name.

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

MFG
Falk

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So weit ich weiß, ist OCIE2 der Compare Match für Timer 2. Also genau 
das, was ich brauche. Und im Tutorial steht:

/* Timer/Counter2 Compare Match */
#define SIG_OUTPUT_COMPARE2             _VECTOR(3)

Das passt doch bestens zusammen?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> So weit ich weiß, ist OCIE2 der Compare Match für Timer 2.

Ja.

> Und im Tutorial steht:
>
> /* Timer/Counter2 Compare Match */
> #define SIG_OUTPUT_COMPARE2             _VECTOR(3)
>
> Das passt doch bestens zusammen?

Hast du auch den dazugehörigen Text darüber gelesen?

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und Dein
lcd_writeChar('T');
ruft nicht wiederunm andere Interruptroutinen auf?

Mach doch mal:
ISR(SIG_OUTPUT_COMPARE2)
{
    do_something = TRUE;
}
und im Hauptprogramm
while (1)
{
  if (do_something) 
  {
      lcd_writeChar('T');
      do_something = FALSE;
  }
}

Rick

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Und Dein
>lcd_writeChar('T');
>ruft nicht wiederunm andere Interruptroutinen auf?

oder es braucht zu lange?

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Rolf Magnus:
Ja, den hab ich gelesen.


@ Rick Dangerus:
Die Funktion erzeugt keine weiteren Interrupts. Und lange braucht sie 
auch nicht. Sie wird nicht mal ausgeführt, um genau zu sein.....

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> @ Rolf Magnus:
> Ja, den hab ich gelesen.

Na dann weißt du ja, warum SIG_OUTPUT_COMPARE2 falsch ist.

Autor: OliverSo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch wenn
>ISR(SIG_OUTPUT_COMPARE2)

eine Mischung aus deprecated und aktuellen Makros und defines ist, weiss 
der Compiler doch, was damit zu tun ist, und auch der Rest sieht nicht 
verkehrt aus.

Insofern wie immer: Zeig mal den ganzen Code.

Oliver

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beide Namen sind definiert, also ists wurscht, welchen man nimmt.
Am Problem ändert das nichts, das muß also woanders liegen.


Mir ist kürzlich auch ein Programm in den Wald gelaufen und ich hab mich 
dumm und dusslig gesucht.

Der Grund war, ich hab für nen ATtiny85 compiliert, aber nur nen 
ATtiny45 eingesteckt.
Damit gehts nach dem ersten RET(I) ab ins Nirwana.


Peter

Autor: Bernd (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, nach langer Pause hier nun der Code. Vielleicht entdeckt jemand was?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> void SIG_OUTPUT_COMPARE2( void )
Was zum Geier ist das denn? Schau Dir mal ganz dringend im 
AVR-GCC-Tutorial oder in der libc-Doku an, wie Interrupt Handler 
definiert werden!

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heh, sorry dass ich dich so schockiere. Aber das habe ich per copy & 
paste aus einem anderen Projekt übernommen, an dem ich gerade arbeite. 
Und da funktioniert der Timerinterrupt tadellos. So falsch kann das also 
nicht sein...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd wrote:
> So falsch kann das also
> nicht sein...

Wenn du meinst .... :-)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd wrote:
> So falsch kann das also
> nicht sein...
Es gibt zwei Möglichkeiten:
1.: Normaler Interrupt-Handler, Deklaration mit ISR(VEKTORNAME_vect)

2.: Unterbrechbarer Handler, Prototyp mit __attribute__((interrupt)), 
dann Definition wie in Deinem Code (aber wenn's geht mit aktuellem 
Vektornamen und nicht mit dem veralteten SIGNAL-Zeugs). Bei Dir fehlt 
also mindestens das __attribute__((interrupt))...

Unterbrechbare Handler sollten aber eh nur dann eingesetzt werden, wenn 
es unbedingt sein muss. Also halte Dich besser an die Version unter 1.

EDIT:
Rick Dangerus hat schon mal (07.02., 13:45) eine Version gepostet, die 
zumindest funktionieren müsste und bis auf die Tatsache, dass er auch 
einen veralteten Vektornamen verwendet, auch OK ist.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:

> 2.: Unterbrechbarer Handler, Prototyp mit __attribute__((interrupt)),

Schnee von gestern. ;-)

http://www.nongnu.org/avr-libc/user-manual/group__...
ISR(TIMER0_COMPA_vect, ISR_NOBLOCK)
{
   //...
}

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Johannes M. wrote:
>
>> 2.: Unterbrechbarer Handler, Prototyp mit __attribute__((interrupt)),
>
> Schnee von gestern. ;-)
Hach, schon wieder was Neues... Schlimm. Seit welcher Version ist das 
so? Ich dachte ja eigentlich, ich hätte wenigstens ne einigermaßen 
aktuelle Version hier auf dem Rechner...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Seit 1.6.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich habe jetzt folgende Notationen ausprobiert. Und keine davon 
funktioniert! Die LCD Funktion wird nicht erreicht, und der µC startet 
neu...

void SIG_OUTPUT_COMPARE2( void )
{
  lcd_writeChar('T');
}


ISR(TIMER2_COMP_vect)
{
  lcd_writeChar('T');
}

ISR(SIG_OUTPUT_COMPARE2)
{
  lcd_writeChar('T');
}

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstens kann es ziemlich riskant sein, in einer ISR einen Aufruf einer 
Ausgabe-Funktion zu tätigen (je nachdem, wie die Funktion beschaffen 
ist), und zweitens müssten (vorausgesetzt, die avr/interrupt.h ist 
korrekt eingebunden!) die beiden letzten Versionen zumindest ohne die 
LCD-Ausgabe funktionieren.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Generell: LCD-Ausgabe im Interrupt ist nicht wirklich günstig, speziell 
wenn der Interrupt zufällig genau innnerhalb einer normalen LCD-Ausgabe 
erfolgt. Wenn Debug-Ausgabe nötig, dann per LED, notfalls Hardware-UART 
(ohne Interrupt).

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Interrupts.h ist korrekt eingebunden.

  "und zweitens müssten die beiden letzten Versionen [...] 
funktionieren."
Genau das ist ja das Problem ^^



Zur LCD-Ausgabe: Mir ist schon klar, dass das wenig sinnvoll ist. Aber 
mir geht es nur darum, ob diese Zeile überhaupt erreicht wird (habe dort 
einen Breakpoint gesetzt). Und das ist nicht der Fall. Der µC startet 
neu, bevor er überhaupt in die ISR springt...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd wrote:
> Die Interrupts.h ist korrekt eingebunden.
Die Header-Datei heißt interrupt .h mit einem kleinen "i" und ohne 
"s"! Und sie steht im Unterordner avr!

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja genau. Deswegen binde ich sie auch so ein: "#include 
<avr/interrupt.h>".

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, habe das Problem gerade gelöst. Leider ist die Löung ziemlich blöd:
Hab ein neues Projekt angelegt, den Code hineinkopiert und schon ging's.

Danke trotzdem für eure Bemühungen!

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.