mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frage zu Interrupt


Autor: Zoltan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hätte eine Frage zu AVR Studio(C), und zwar:
In einer Funktion wird ein Interrupt ausgelöst. Nachdem das Programmteil 
dort abgearbeitet wurde, wird das Programm an der Stelle wieder 
fortgesetzt, an welcher der Interrupt auftrat.?
Wie kann ich nun das Programm, nach Abarbeitung des Interruppts.., aber 
irgendwo anders, zB. in einer anderen Funktion weiterlaufen lassen?

Danke
Zoltan

Autor: mikki merten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht nach folgendem Schema:

POP   R16    ;alte Return Adresse vom Stack entfernen
POP   R16
LDI   R16,low(RETURN_ADRESSE)
push  R16
LDI   R16,high(RETURN_ADRESSE)
push  R16
reti

Alternativ geht auch:

POP   R16    ;alte Return Adresse vom Stack entfernen
POP   R16
JMP   RETURN_ADRESSE

Hier müssen allerdings mit CLI die Interrupts wieder freigegeben werden.

Autor: Zoltan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo miki.
Danke für die Antwort.
Ich programmiere das ganze aber in C, und Assembler ist nicht gerade 
meine Stärke.

Autor: Zoltan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry heisst natürlich mikki..

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
solche Sachen  sind in C nicht machbar. Du kannst aber Assemblerroutinen 
innerhalb des C-Programmes einfügen.
#asm
 Assemblerbefehle
#endasm
Und wie du die Adresse des Sprungziels in den Assemblercode bekommst, 
weiß ich auch nicht, geht aber wahrscheinlich.
Wofür soll das ganze eigentlich gut sein?
Gibt sicher ne andere Möglichkeit, daß sauber zu lösen.
Problematisch ist so eine Sache auf jeden Fall, vor allem in Bezug auf 
die Wartbarkeit solcher Programme.Mußt auch aufpassen, welche Register 
du in einem Assemblerteilprogramm verwendest, beim nächsten 
Compiler-update kann die Registerverteilung anders sein, ebneso beim 
Verwenden verschiedener Compileroptimierungen.

Autor: Zoltan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wofür soll das ganze eigentlich gut sein?

Ich möchte, nachdem irgendwo ein Interrupt auftrat, die Aufgaben im 
Intrerrupt abarbeiten und von da ins Main springen. Ich habe jetzt 
einfach am Ende der Interrupt Funktion noch folgendes eingefügt: main() 
, womit er ins Main springt, aber ich glaube Main darf man nicht 
aufrufen, oder?

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich sage einfach mal, daß geht schief. Du hast ja in einem C-Programm 
nicht nur den SP für die Adressen/push/pop, sondern auch noch den 
Datenstack. Stackfehler sind da vorprogrammiert. Funktionerende 
Holzhammermethode wäre ein Sprung nach Adr 0, kostet aber relativ viel 
Zeit und du verlierst alle Variablen, ist also auch nicht das Wahre.
Warum du das alles machen willst/mußt, hat sich mir aber immer noch 
nicht offenbart.

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

Bewertung
0 lesenswert
nicht lesenswert
Hallo crazy horse

Das Programm ist eine Steuerung für einen Modell-Uboot. Es wird zuerst 
die Pulsplänge vom Sender gemessen, dann die Signale von einem 
Drucksensor und einem Neigungssensor(ADXL202).Der Neigungssensor wird 
noch Temperaturkompensiert, daher die lange Tabelle am Anfang. UART und 
Handschaltung...

Das Problem ist, (es läft bis jetzt alles bestens), das ich noch einen 
Senderausfall programmieren wollte. Dabei wartet der MC 100ms. Wenn 
innerhalb dieser Zeit nichts vom Empfänger kommt, dann erzeugt er eine 
vorgeben Pulslänge für den Tiefenruderservo, so das das Boot 
"automatisch" auftaucht. Dabei tritt eben dieser Fall auf, welches ich 
oben beschrieben habe. Das Programm gerät durcheinander. Ich habs jetzt 
aber gelöst, indem ich im Interrupt nicht zurück, sonder nach main 
springe, da wollte ich auch hin. Aber das ist so,glaube ich, nicht 
schön??

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast recht, das ist nicht schön und obendrein noch fehlerhaft.

Wenn Du im Interrupt das main() aufrufst, dann beendest Du ihn ja nicht. 
Somit z.B. beim 10. Senderausfall läuft vielleicht Dein Stack über und 
das Programm stürzt ab.


Die übliche Herangehensweise:

Man setzt im Interrupt ein Bit und in der Main-Loop testet man dann 
dieses Bit ab und startet dort die entsprechende Behandlungsroutine.


Peter

Autor: Reiner Patommel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du unbedingt zu main() zurück willst, warum benutzt Du dann nicht 
den watchdog ?  Empfänger re-triggert WD.  Bei Ausfall des Triggers 
reboot.

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

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für Eure Antworten.
Ich habe das Problem jetzt ohne den Aufruf von Main lösen können. Der 
Aufruf war garnicht nötig, denn das Programm läuft sowiso in die Main 
Funktion. Ich habs mir halt wieder schwer gemacht...
Vollständigkeitshalber nochmal die geänderte Code im Anhang.

Autor: MarkusS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

generell kann man solche Probleme mit,
setjmp() und
longjump()
lössen.

Gruss,

MarkusS

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.