Forum: Compiler & IDEs switch:case durch Interrupt unterbrechen


von YunPe (Gast)


Lesenswert?

Hallo, ich bin gerade am programmieren.

In meinem Programm gibt es eine switch:case Anweisung. Diese würde ich 
gerne durch einen Interrupt unterbrechen lassen, bzw. durch den 
Interrupt direkt in einen bestimmten Zustand springen lassen.

z.B.

switch(A)

case 1:
case 2:
case 3:
case 4:
case 5:

In Case 3 findet ein Interrupt statt, wodurch er sofort in Case 4: 
springt. Wenn ich den Zustand im Interrupt setzte, bleibt das Programm 
hängen, aber warum?
Also Interrupt und Programm an sich funktioniert, wurde getestet.
Eine Möglichkeit währe es noch im Interrupt z.b. T=1 setzen und in den 
einzelnen Cases abfragen. Allerdings springt er dann nicht sofort in den 
richtigen Case, und ab 10,15 cases wird das auch einiges an unnützen 
Codes.
Habt ihr vlt. eine Idee?

von Jens P. (Gast)


Lesenswert?

Kannst du nicht eine variable setzen (oder den Case ändern), die 
Select-Anweisung mit einem Break beenden und halt aussenrum ne do 
while-Schleife setzen?

Das verändern der variablen dann auch am besten in eine kleine sub, so 
hast du pro case ein/zwei Zeilen mehr code.

von YunPe (Gast)


Lesenswert?

Klar ist auch möglich, nur wollte ich eben diese 2,3 Zeilen mehr Code 
vermeiden.

von (prx) A. K. (prx)


Lesenswert?

YunPe schrieb:

> Klar ist auch möglich, nur wollte ich eben diese 2,3 Zeilen mehr Code
> vermeiden.

Ich nehme an, du bist Kettenraucher und experimentierst gerne mit 
Schwarzpulver? Denn ungefähr das hast du vor.

von Karl (Gast)


Lesenswert?

Und das hilft ihm jetzt wie genau weiter? Wenn ihr nicht helfen wollt, 
dann lasst es doch bitte.

von (prx) A. K. (prx)


Lesenswert?

Ihm wurde bereits geholfen: 
Beitrag "Re: switch:case durch Interrupt unterbrechen"
Für mehr Hilfe müsste man mehr über das Problem wissen.

Ein Hinweis, dass man auf dem Holzweg ist, ist auch eine Hilfe.

von Karl (Gast)


Lesenswert?

Aha, vlt. gibt es auch Leute die es gerne verstehen.

von YunPe (Gast)


Lesenswert?

A. K. schrieb:
> Für mehr Hilfe müsste man mehr über das Problem wissen.

Was musst du noch mehr wissen? Ich habe 10 Cases, in einem davon findet 
ein Interrupt statt. Findet dieser statt, soll in einen bestimmten Case 
gesprungen werden. Was brauchst du noch für Infos? Und warum 
Schwarzpulver? Was ist daran so gefährlich, verkehrt...?

von (prx) A. K. (prx)


Lesenswert?

YunPe schrieb:

> Ich habe 10 Cases, in einem davon findet
> ein Interrupt statt.

Um mit dieser Beschreibung etwas anzufangen müsste ich deinen Kopf 
aufsägen und reinsehen, sorry. Da musst du schon etwas mehr ausholen.

Interrupts sind meisten kein Bisschen synchron mit dem Hauptprogramm, 
sondern geschehen an beliebiger Stelle.

> Schwarzpulver? Was ist daran so gefährlich, verkehrt...?

Aus einem Interrupt-Handler unter Umgehung des normalen 
Rückkehrverfahrens ins Hauptprogramm zu springen ist keine Lösung, 
sondern ein Problem.

von YunPe (Gast)


Lesenswert?

Ok, dann nochmal genauer....

Ich habe 10 Cases, die laufen ganz normal ab,... Dann wird z.B. durch 
einen Taster ein externer Interrupt ausgelöst. Durch diesen Interrupt 
soll sofort, egal in welchem Case er gerade arbeitet zum Case 9 
gesprungen werden. ... Hoffe das reicht.

von (prx) A. K. (prx)


Lesenswert?

Das reicht um festzustellen, dass dieser Ansatz nicht sinnvoll ist. 
Entweder erledigst du die Aktion "case 9" direkt im Interrupt-Handler, 
oder du baust den Code im Hauptprogramm so um, dass er auf eine vom 
Handler entsprechend gesetzte Variable reagiert.

Denk ausserdem dran, dass Taster prellen.

von YunPe (Gast)


Lesenswert?

Also direkt im Case9 erledigen ist schlecht, da dass Hauptprogramm ja 
nicht weitermachen soll, wenn Interrupt.

An das mit dem Handler hab ich auch gedacht, aber dann eben der 
zusätzliche Code. Dachte, bzw. hätte mir gewünscht, dass es so auch 
geht. Also dass der Interrupt einfach sagt,..so jetzt Case9. Schade.

von Karl H. (kbuchegg)


Lesenswert?

YunPe schrieb:
> Also direkt im Case9 erledigen ist schlecht, da dass Hauptprogramm ja
> nicht weitermachen soll, wenn Interrupt.
>
> An das mit dem Handler hab ich auch gedacht, aber dann eben der
> zusätzliche Code. Dachte, bzw. hätte mir gewünscht, dass es so auch
> geht. Also dass der Interrupt einfach sagt,..so jetzt Case9. Schade.

Es sieht wohl so aus, dass der ganze Ansatz mies ist.
Jede Wette, da sind wieder mal Warteschleifen und _delay_ms und 
dergleichen im Spiel.

Für eine vernünftige Lösung müsste man wohl das komplette Programm 
kennen, die Aufgabenstellung kennen und da erst mal einen gscheiten 
Ansatz austüfteln, das vorhandene Programm wegwerfen und das alles 
vernünftig und sauber nach den Regeln der Kunst machen.

Und diese Lösung funktioniert dann auch.

von Jens P. (Gast)


Lesenswert?

Also ich erledige dergleichen eigentlich immer mit einer funktion 
"CyclicTests", bei der eben ständig (meist hat man ja eh n haufne 
schleifen) gewisse Flags, welche durch Interrupts und Zähler beeinflusst 
werden, abgefragt werden.

Klar bedeutet das mehr code, aber wer mehr Funktion braucht, braucht 
halt mehr code.

Selbst wenns manchmal etwas "ungeschickt" über ISR setzt variable 
DoBreak=True und dann muss man halt an entsprechender Stelle im Programm 
ein

If DoBreak=TRUE then
break
end if

einbauen.

PRozedurale Programmierung bedingt halt manchmal ein geknödel, vor allem 
wenn sinnvoll auf Interrupts reagiert werden soll.

Was so schlimm an den paar Zeilen mehr (10 Cases, 3 Zeilen= 30 Zeilen 
mehr code, ist das so schlimm?) sein soll, verstehe ich auch nicht. Ich 
würde da ganz klar der Funktion der Vortritt vor der Eleganz lassen.

von Falk B. (falk)


Lesenswert?

Man nehme eine statemachine und vergessen dem ISR-verbiegt-switch 
Murks.

von Oliver (Gast)


Lesenswert?

YunPe schrieb:
> An das mit dem Handler hab ich auch gedacht, aber dann eben der
> zusätzliche Code. Dachte, bzw. hätte mir gewünscht, dass es so auch
> geht. Also dass der Interrupt einfach sagt,..so jetzt Case9. Schade.

Klar geht das. In der ISR die auf dem Stack liegende Rücksprungadresse 
durch die von case 9: ersetzen, fertig.

Aber: Vergiß das ganz schnell wieder. Solche Spielchen sind 
grundsätzlich und immer ein Zeichen für ein völlig ungeeigneten 
Programmkonzeptes.

DAS MACHT UND BRAUCHT MAN NICHT, ausser, man schreibt Kernel für 
Echtzeitbetriebssysteme, oder was in der Art, und deine Frage lässt 
erahnen, daß du das nicht vorhast.

Oliver

von YuPe (Gast)


Lesenswert?

Falk Brunner schrieb:
> Man nehme eine statemachine und vergessen dem ISR-verbiegt-switch
> Murks.

Hm, habe mir die Statemachine mal angesehen. Aber diese wird doch auch 
per switch case realisiert und somit ergibt sich das gleiche Problem. 
Oder habe ich da jetzt was falsch verstanden?

von Karl H. (kbuchegg)


Lesenswert?

Zeig endlich dein komplettes Programm.

Der Witz in der µC Programmierung besteht darin, dass es nur EINE 
dauernd laufende Schleife gibt.

int main()
{
   ....

  while( 1 ) {

     .... // B
  }
}


dies ist die einzige Schleife, die ständig läuft. Wenn da an der Stelle 
B ein switch case existiert, dann ist das ok. Aber: Deine ganze 
Fragestellung stellt sich nicht! Denn es besteht keine Notwendigkeit da 
von einem 'case' zu einem anderen zu springen. Man verändert die Werte 
für die switch-Abfrage und beim nächsten Durchlauf durch die Schleife 
wird dann eben ein anderer case genommen.

Schon alleine dadurch, dass du diese Frage überhaupt stellst, drängt 
sich die Vermutung auf, dass du da bei irgendeinem case eine Schleife 
hast. Und die ist das Problem. Die muss da weg.

von Uwe (de0508)


Lesenswert?

Hallo,

die "Statemachine" wird immer erst bis zum Ende ausgeführt, bis beim 
nächsten Durchlauf neue Ereignisse zu einem anderen Zustand führten und 
somit sich die Programmausführung in diesem Zustand abläuft.

D.h. das externe Ereignis kommt erst ein paar µs später zum 'Zuge'.

Ereignisse (Events) könnte:
- Interrupts,
- ADC Wanderergebnisse,
- Zeit Events oder
- Tastenevents
- z.B. neue logische Ereignisse sein.

Die Darstellung stellt nur eine mögliche Aufschlüsselung von einfachen 
bis komplexen Events dar !

Für die Konstruktions einer "Statemachine" gibt es verschiedene 
Methoden.

Z.B. ein Zustandsdiagramm und auf den Pfeilen dann die Ereignisse oder 
ein Petrie-Netz um komplexere reale "Welt"-Strukturen zu beschreiben..

Genaueres lies bitte über Google oder Wikipedia nach.

ok ?

von Uwe (de0508)


Lesenswert?

@Karl Heinz,

Du hast den gleichen 'Verdacht' wie ich und warst wieder schneller. /-)

von Karl H. (kbuchegg)


Lesenswert?

Und nochwas:
Wenn du jetzt wieder mit einer verbalen Beschreibung kommst, wie die 
Dinge deiner Meinung nach laufen müssen, dann schmeiss ich dich raus.

Entweder du machst jetzt Nägel mit Köpfen und bringst was, mit dem man 
auch arbeiten kann oder du lässt es bleiben. In letzterem Fall bist du 
aber beratungsresistent und damit ist es sinnlos, wenn jemand noch was 
dazu schreibt. Denn dann willst du keine vernünftige Lösung sondern nur 
irgendwie deinen verkorsten Ansatz retten.

Deine ganzen Beschriebungen lssen bei allen hier die Alarmglocken 
klingen, dass in Wirklichkeit dein ganzes Programmkonzept verkorkst ist! 
Sowas lässt sich meistens nicht mit 1 oder 2 Zeilen Code hier und da 
korrigieren, sondern das muss man sich konkret komplett ansehen, die 
Aufgabenstellung analysieren und mit etwas Neuem hochkommen. Aber 
diesmal richtig und nicht wieder Murks.

von Oliver (Gast)


Lesenswert?

YuPe schrieb:
> Aber diese wird doch auch
> per switch case realisiert und somit ergibt sich das gleiche Problem.
> Oder habe ich da jetzt was falsch verstanden?

Der Witz bei der Reaktion auf einen Tastendruck in einem 
Mkrocontrollerprogramm liegt darin, daß das nicht "sofort" passiern muß. 
sondern in aller Ruhe an einer passenden Stelle im Programm zu einem 
passenden Zeitpunkt. Da sdauert zewar dann einige ms, aber das merkt 
kein Mensch.

Oliver

von Falk B. (falk)


Lesenswert?

@  YuPe (Gast)

>per switch case realisiert und somit ergibt sich das gleiche Problem.

nein.

>Oder habe ich da jetzt was falsch verstanden?

Ja. Die state machine bleibt nicht in den case Zweigen stecken sondern 
läuft da sehr schnell durch. Wenn jetzt ein Ereignis in einer ISR 
festgestellt wird, setzt dieses eine Variable, aka Flag. Diese wird beim 
nächsten Durchlauf der state machine ausgewertet und wenn es denn sein 
soll springen alle State in State x. Nix Stackmanipulation, alles ganz 
ordentlich.

von YunPe (Gast)


Lesenswert?

Ok, dank für die vielen Tips. Werd jetzt versuchen, das Programm ohne 
switch:case hinzubekommen. Bzw. Richtung Statemachine.
Werde mich dann wieder melden, sollte das nicht gelingen werde ich mein 
programm posten. Würde es gern zuerst ein bisschen selbst probieren.

von Karl H. (kbuchegg)


Lesenswert?

YunPe schrieb:
> Ok, dank für die vielen Tips. Werd jetzt versuchen, das Programm ohne
> switch:case hinzubekommen.

Du sollst es nicht ohne switch-case hinkriegen, an dem ist höchst 
wahrscheinlich nichts auszusetzen.
Du sollst es ohne 'Wir warten aufs Christkind' hinkriegen.
Das ist der springende Punkt.

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.