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?
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.
Klar ist auch möglich, nur wollte ich eben diese 2,3 Zeilen mehr Code vermeiden.
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.
Und das hilft ihm jetzt wie genau weiter? Wenn ihr nicht helfen wollt, dann lasst es doch bitte.
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.
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...?
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.
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.
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.
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.
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.
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.
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
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?
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.
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 ?
@Karl Heinz, Du hast den gleichen 'Verdacht' wie ich und warst wieder schneller. /-)
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.
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
@ 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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.