Forum: Mikrocontroller und Digitale Elektronik Per Interrupt aus der Hauptschleife ein-/aussteigen


von Johannes Permoser (Gast)


Lesenswert?

hi,

in meinem programm läuft normalerweise die Hauptschleife, in der
Messungen vorgenommen und abgespeichert werden.
nun möchte ich aber auf best. bytes des USART aus dieser Schleife
aussteigen bzw. dann wieder einsteigen können.
Aber im Tutorial steht was von 'Jede Interrupt-Routine muss mit reti
abgeschlossen werden, weil sich sonst der Stack zumüllt.'
Und mit reti komme ich genau wieder zurück an die Stelle in der
Hauptschleife, wo der Interrupt aufgetreten ist.

Wie kann ich trotzdem irgendwie auf die Hauptschleife Einfluss nehmen?

mfg, Johannes

von Andreas B. (Gast)


Lesenswert?

Du setzt im Interrupt einfach eine (globale) Variable (bei c als
volatile deklarieren) und fragst diese dann in der Mainloop ab,

Gruß Andreas

von D. W. (dave) Benutzerseite


Lesenswert?

Du hast 3 Möglichkeiten:
 - die von Andreas
 - In der Hauptschleife einfach das Interrupt-Flag zu überprüfen und
gar keine ISR zu erlauben
 - wenn in Assembler: beim Interruptvektor direkt mit (R)JMP zu dem
Teil zu springen

von Johannes Permoser (Gast)


Lesenswert?

danke euch, ich denke eine lösung wird dann schon passen ^^

von Karl heinz B. (kbucheg)


Lesenswert?

> - wenn in Assembler: beim Interruptvektor direkt mit (R)JMP zu dem
> Teil zu springen

Das ist keine Lösung. Zumindest nicht für einen Neuling
der noch keine Ahnung hat, was er da alles am Stack anrichtet
und welche Schritte er unternehmen muss um das wieder alles
ins Lot zu bringen.

von luxx (Gast)


Lesenswert?

@ karl heinz:
was muss man den genau machen um die nicht mehr benötigten
rücksprungadressen zu elimienieren? ich hatte auch schon öfters
probleme damit und mich würde es schon interisieren wie das geht.
ich meine in asm.

luxx

von Unbekannter (Gast)


Lesenswert?

@luxx:

Naja, Da wo das "reti" stehen würde, einfach den PC vom Stack poppen
und dann direkt dort hin springen.

Wenn Du in C programmierst, musst Du Dir eigene Prologs und Epilogs
bauen, damit das mit dem Rest des Codes funktioniert.

Am besten erst mal in Assembler üben.

von Christoph Kessler (db1uq) (Gast)


Lesenswert?

Am einfachsten sind zwei pop Befehle, damit kommt der Stackpointer auf
den Zustand vor dem Interrupt. Man kann natürlich auch den Stackzähler
um zwei ändern, aber das kostet mehr Aufwand.
Das Progrmm wird durch solche üblen Tricks allerdings sehr
unübersichtlich, eine Kommunikation über Semaphore ( "Leuchtzeichen")
oder Flags, was dasselbe ist, ist die anständige Methode. Am einfachsten
über das T-Flag, wenn man nur ein Bit an Information braucht.

von Hauke Sattler (Gast)


Lesenswert?

Also das mit dem direkten Rücksprung mit (r)jmp wird früher oder später
in einem Stackoverflow enden. (Im schlimmsten Falle landet der Stack
irgendwann in den IO Registern)
Mit dem Polling ist auch keine gute Lösung. Entweder frisst sie extrem
CPU Zeit oder es wird zu selten abgefragt.
Deshalb ist es mit interupt "eleganter zu lösen"

Da du ja im Prinzip drei Fälle hast,
A)- Normale Funktion
B)- UART hat das falsche byte empfangen
C)- UART hat ein richtiges Byte empfangen

Ich würde es so machen:
UART RX Complete Interrupt aktivieren.

In der ISR dann erstala die Entscheidung ob das empfangene Byte eines
der best. Bytes ist.
Wenn nein dann reti
Wenn ja, dann zwei bytes aus dem stack poppen (irgenwohin, du brauchst
diese nicht mehr) und die gewünschte Rücksprungadresse in den den Stack
pushen. (Achtung Bytereihenfolge beachten)
Danach das machen was du mit dem best. Byte machen wolltest und am Ende
wieder nen reti.

Nun warum nicht einfach raus poppen und am ende mit (r)jmp zurück?
Zum Einem: weil oft das SEI vergessen wird.
Zum Zweiten: weil man viele Sachen von Fall B und Fall C
(wiederherstellen vom Flags und Variablen) gleichzeitig verwenden kann
und beide fälle mit Einem reti abgeschlossen werden
Zum Dritten: Viele Simulatoren auf denen man seine code vorher testet,
reagieren allerisch auf call/pop/pop/jmp und zeigen dir trotdem nen
stackoverflow an.

bis dann
Hauke

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.