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
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.
Hallo miki. Danke für die Antwort. Ich programmiere das ganze aber in C, und Assembler ist nicht gerade meine Stärke.
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.
>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?
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.
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??
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
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.
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.
Hallo, generell kann man solche Probleme mit, setjmp() und longjump() lössen. Gruss, MarkusS
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.