Hallo Leutz... hoffe mir kann jemand helfen... ich möchte bei einem attiny24 in der ISR das programm welches in er main läuft wechseln..... ISR(INT0_vect) { if(bla ==0) { bla = 1; fu_pointer = (myfcnptr) blaufadeinout; } else { bla = 0; fu_pointer = (myfcnptr) rotf; } } das funktioniert auch soweit..in der main wird einfach dauernd dieser funktionspointer aufgerufen!! Jedoch erfolgt der wechsel des programms erst bei beenden des gerade laufenden programms. Gibt es eine möglichkeit den wechsel sofort auszuführen?? Also den wechsel in der main , ich will die funktion nicht in der ISR aufrufen da es bei mehreren programmen dann wohl etwas zu zeitaufwändig für ne ISR wird.... gruß noveX
> Jedoch erfolgt der wechsel des programms erst bei beenden des gerade > laufenden programms. Gibt es eine möglichkeit den wechsel sofort > auszuführen?? Ja, die vom Funktionspointer adressierte Unterroutine muss ebenfalls möglichst oft und regelmäßig das Statusflag bla prüfen und sich graziös beenden, wenn der Status durch INT0 gewechselt wurde.
Ob und wie man das macht hängt von den fraglichen Funktionen ab. Für einen Anfänger (Du schreibst leider nichts über den Umfang Deiner Erfahrungen) ist es aus einer Reihe von Gründen nicht empfehlenswert das zu tun. Einer der wesentlichen Gründe dafür ist, das man sicherstellen muss, das die Funktionen bzw. die von Ihnen behandelten und erzeugten Daten immer in einem konsistenten Zustand hinterlassen werden müssen, falls und wenn der Interrupt den Programmfluss umgesteuert hat. Selbst Fortgeschrittene werden dieses Verfahren nicht oder nur "unter Zwang" anwenden, wenn überhaupt. Eine viel bessere, weil übersichtlichere, Möglichkeit ist es die beiden Funktionen als eine Vereinigung von zwei Zustandsmaschinen zu implementieren und in den in Frage kommenden Zuständen einen Übergang zu anderen Zuständen in Abhängigkeit von einem Flag, das im Interrupt gesetzt wird, zu implementieren. Das ist nur eine einfache Erweiterung des Entwurfsschemas, das sowieso zu bevorzugen ist, in dem eine in main abgehandelte Zustandsmaschine abgearbeitet wird und Zustandswechels auch von in INTs gesetzten Flags abhängen. Ich möchte Dir ernsthaft empfehlen das Problem in dieses Schema einzupassen. Die Probleme bei dem ursprünglich von Dir angedachten Weg sind nur mit hohem Aufwand zu beherrschen. Gehe diesen Weg lieber nicht.
Zunächst mal die Standardfrage bei solchen Ideen: WARUM? willst du das? Wenn du das neue Programm "jungfräulich" starten willst, ohne das es im vorherigen Zustand weitermachen soll, dann schreib den neuen Funtionspointer in der ISR ins EEPROM, und ziehs dann über einen Pin Reset auf GND ;) Im Hauptprogramm liest du den Pointer aus dem EEPROM, und springst dann dahin. Oliver
Oliver schrieb: > Zunächst mal die Standardfrage bei solchen Ideen: > > WARUM? willst du das? > > Wenn du das neue Programm "jungfräulich" starten willst, ohne das es im > vorherigen Zustand weitermachen soll, dann schreib den neuen > Funtionspointer in der ISR ins EEPROM, und ziehs dann über einen Pin > Reset auf GND ;) > > Im Hauptprogramm liest du den Pointer aus dem EEPROM, und springst dann > dahin. > > Oliver Wird zwar funktionieren ....jedoch hört es sich nicht so optimal an den controller nur wegen einem internen programmwechsel gleich zu reseten :-/
> Eine viel bessere, weil übersichtlichere, Möglichkeit ist es die beiden > Funktionen als eine Vereinigung von zwei Zustandsmaschinen zu > implementieren und in den in Frage kommenden Zuständen einen Übergang zu > anderen Zuständen in Abhängigkeit von einem Flag, das im Interrupt > gesetzt wird, zu implementieren. Das ist nur eine einfache Erweiterung > des Entwurfsschemas, das sowieso zu bevorzugen ist, in dem eine in main > abgehandelte Zustandsmaschine abgearbeitet wird und Zustandswechels auch > von in INTs gesetzten Flags abhängen. Ja so hab ich es mir auch erst gedacht...jedoch ist das problem dabei wenn funktion1 ein programm ist das 4 sekunden lang dauert und ich drücke nach einer sekunde den taster dauert es noch 3 sekunden bis das programm wechselt..... Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was ja auch nicht gerade eine schöne lösung ist..
Wenn du dir wirklich selber in den Fuß schiessen willst: Beim Funktionswechsel in der ISR: Per Inline-ASM den Stackpointer zurücksetzen, goto main; (Gibt es eigentlich setjmp/longjmp in der avr-libc?)
Kevin Rombach schrieb: > Ja so hab ich es mir auch erst gedacht...jedoch ist das problem dabei > wenn funktion1 ein programm ist das 4 sekunden lang dauert und ich > drücke nach einer sekunde den taster dauert es noch 3 sekunden bis das > programm wechselt..... > > Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was > ja auch nicht gerade eine schöne lösung ist.. Das alles sind ernsthafte Indizien, dass deine jetzigen Einzelprogramme schon Mist sind. Wahrscheinlich wimmelt es nur so von _delay Aufrufen und das ist jetzt die Quittung dafür.
> Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was > ja auch nicht gerade eine schöne lösung ist.. Wenn du funktion1 unschön abwürgen willst, ohne ihr eine Chance zu geben, sich sauber zu beenden, dann benutz die Lösung von Oliver. Die ist wenigstens sicher, weil funktion2 einen sauberen Stack und initialisierte Daten vorfindet. Den Reset an sich kannst du auch über den Watchdog auslösen.
Edding schrieb: > (Gibt es eigentlich setjmp/longjmp in der avr-libc?) Ja gibt es ;) Also ohne inline-asm:
1 | jmp_buf return_to_main; |
2 | |
3 | ISR(xxx) { |
4 | ....
|
5 | ... fptr umbiegen; |
6 | longjmp(return_to_main,1); |
7 | }
|
8 | |
9 | |
10 | void main() { |
11 | ... init .. |
12 | setjmp(return_to_main); |
13 | sei() |
14 | while (true) { fptr aufrufen... } |
15 | }
|
>Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was >ja auch nicht gerade eine schöne lösung ist.. Ob das nun "schön" ist oder nicht, darüber lässt sich nicht streiten, da "schön" nicht objektivierbar ist. Die Aussage, das eine Funktion 4 Sekunden lang einen nicht unterbrechbaren Vorgang durchführt halte ich zumindest für hinterfragbar. Was ist das genau für ein Vorgang? Wie sieht er aus? Wie ist er programmiert? Eine Schleife? Ein Delay? Und die Frage "wozu" das Ganze ist hier auf jeden Fall interessant. Ehrlich gesagt möchte ich mich da ohne weitere Angaben und genaue Beschreibung nicht weiter auf Diskussionen einlassen. Erfahrungsgemäß beruhen solche Fragestellungen auf ungenügendem Verständnis von Algorithmen und Programmierschemata. Wenn Du darauf nicht eingehst halte ich jede weitere Diskussion für nutzlos.
Karl heinz Buchegger schrieb: > Kevin Rombach schrieb: > >> Ja so hab ich es mir auch erst gedacht...jedoch ist das problem dabei >> wenn funktion1 ein programm ist das 4 sekunden lang dauert und ich >> drücke nach einer sekunde den taster dauert es noch 3 sekunden bis das >> programm wechselt..... >> >> Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was >> ja auch nicht gerade eine schöne lösung ist.. > > Das alles sind ernsthafte Indizien, dass deine jetzigen Einzelprogramme > schon Mist sind. Wahrscheinlich wimmelt es nur so von _delay Aufrufen > und das ist jetzt die Quittung dafür. so ein schwachsinn hier... da ist nicht ein delay drin du Held!!!! Es geht hier um eine RGB LED steuerung....und wenn ich nunmal mehrere farben nacheinander ein und ausfaden lasse und farbspiele betreibe geht ne funktion nunmal nicht nur 200ms !!!!!
Kevin Rombach schrieb: > so ein schwachsinn hier... da ist nicht ein delay drin du Held!!!! Oha, schnell weg hier, nicht dass ich auch noch zum Helden mutiere.
Kevin Rombach schrieb: > so ein schwachsinn hier... da ist nicht ein delay drin du Held!!!! Es > geht hier um eine RGB LED steuerung....und wenn ich nunmal mehrere > farben nacheinander ein und ausfaden lasse und farbspiele betreibe geht > ne funktion nunmal nicht nur 200ms !!!!! So ein Schwachsinn. Die funktion braucht nur ein paar µs. Neue PWM-Werte berechnen, in die Register schreiben, fertig. das ganze Faden, Farbwechsel, Animationszeug aussenrum: State Machine, wie dir schon mehrfach geraten wurde. Davon abgesehen: Deine Wunschlösung hab ich dir gepostet. Werd damit glücklich.
Es handet sich einfach um eine Kleine Platine an die Über den Attiny24 und einer ULN2803 4 RGB LED´s und 2 WW LEDS gesteuert werden sollen... Die FarbwechselProgramme der RGB´s sin halt über PWM und schleifen in denen die PWM werte erhöht und gesenkt werden .... und das dauert nunmal wenn ich schöne übergänge von zwischen den 4 RGB´s erzeugen will!! SO darum geht es.... Und wenn ich nun den taster drücke und das Farbprogramm wechseln will und das programm dann erst nach ein paar sekunden gewechselt wird wirkt das ganze so träge und ist nicht so toll..
Kevin Rombach schrieb: > Und wenn ich nun den taster drücke und das Farbprogramm wechseln will > und das programm dann erst nach ein paar sekunden gewechselt wird wirkt > das ganze so träge und ist nicht so toll.. Deswegen: State Machine. Davon abgesehen: Deine Wunschlösung hab ich dir gepostet. Werd damit glücklich.
Kevin Rombach schrieb: > SO darum geht es.... Und er ganze Ansatz ist Unsinn, du Antiheld. Mach dich mal über State-Maschinen schlau und wie man sowas macht. AUch wenn du keinen _delay drinnen hast, so hast du doch Warteschleifen und genau da hakt es jetzt eben. Wie ich schon sagte: Dein ganzer Programmansatz ist Mist. Das muss bereingt werden und auf einmal wird dann dein "Problem" ganz einfach.
Wie soll ich sonst eine schrittweise erhöhung der PWM werte machen wenn nicht in einer schleife ? Rekursiv ? irgendwo muss ja ne wiederholte anweißung sein um das zu realisieren ?
Karl heinz Buchegger schrieb: > AUch wenn du keinen _delay drinnen hast, so hast du doch Warteschleifen > und genau da hakt es jetzt eben. > Naja in den Schleifen wird ja immerhin bei jedem durchlauf der PWM wert erhöht...somit wird ja nicht nur gewartet ?
Novex Xevon schrieb: > irgendwo muss ja ne wiederholte > anweißung sein um das zu realisieren ? In der State Machine, zum Xten mal. Hab dir ein Beispiel, ich glaube hier aus der Codesammlung, angehängt. Farbwechsler (HSV-Farbmodell) mit Soft-PWM für RGBW-LED auf Tiny13. Die Schleife in der main läuft ständig durch, nur wenn der (250Hz-)Timer Bescheid gibt, werden die Farbwerte geändert. Auf Tastendrücke könnte innerhalb von µs reagiert werden.
@ Novex Xevon Bitte beachte, das K. H. Bucheregger Deinen Programmieransatz als "Mist" bezeichnet hat und nicht Dich persönlich angegriffen hat. Deine Reaktion "Schwachsinn" bringt uns hier nicht weiter und ist gerade in Bezug auf K.H. Buchegger absolut unangebracht. Denn gerade er ist einer derjenigen, die auch auf den unangemessensten Lösungsansatz noch hilfsbereit und geduldig reagiert (Ich hoffe es geht ihm nicht schon auf den Nerv, das ich ihn wieder mal verteidige, aber er ist darin mein Vorbild :-) Vielmehr solltest Du die in vieler Hinsicht übereinstimmende Reaktion von erfahrenen Leuten hier zum Anlass nehmen unseren Gedankengängen zumindest probeweise mal zu folgen und als Anfänger und Unerfahrerener, als der Du Dich hier darstellst, versuchen ob Du dies nicht mit Gewinn tuen kannst anstelle Dich auf eine einmal vorgefasste Meinung zu versteifen.
Nimm mal an, Du hast eine einfache Schleife vorliegen.
1 | for (i = 0; i <10; i++) |
2 | Funktion_1 (i); |
3 | Funktion_2 (); |
Wie kannst Du die als Statemachine darstellen?
1 | int i = 0; |
2 | int state = 0; |
3 | |
4 | switch (state) { |
5 | case 0: |
6 | Funktion_1 (i); |
7 | i++; |
8 | if (i >= 10) |
9 | state = 1; |
10 | break; |
11 | case 1: |
12 | Funktion_2 (); |
13 | break; |
14 | default:
|
15 | break; |
Du siehst, das eine scheinbar nicht unterbrechbare Schleife doch als unterbrechbare Statemachine programmierbar ist. (Syntaxfehler mal vorbehalten).
@Huch: Scheibar hat novex auch eine Leseschwäche, sonst würde er nicht nur immer auf den letzten Post reagieren, sondern auch die dazwischen lesen. Dann hätte er sich z.B. schon mit setjmp/longjmp aus dem Staub machen können. Exakt die Lösung, die er sich gewünscht hat... aber trotz mehrfachen erneuten Hinweisen, keine Reaktion dazu. Klar, ist keine schöne Lösung, aber hey, er wollte es so.
> > switch (state) { > case 0: > Funktion_1 (i); > i++; > if (i >= 10) > state = 1; > break; > case 1: > Funktion_2 (); > break; > default: > break; > [/c] > > Du siehst, das eine scheinbar nicht unterbrechbare Schleife doch als > unterbrechbare Statemachine programmierbar ist. > > (Syntaxfehler mal vorbehalten). Okay.... so in der art hatte ich es auch mal...bzw. ich hatte halt eine globale variable welche halt den status des hauptpgrogrammes bestimmt hat!! jedoch war halt da das problem das der zustand des proramms nicht direkt beim tastendruck verändert wurde :-/ und nein ich habe KEINE Leseschwäche!!
>jedoch war halt da das problem das der zustand des proramms nicht >direkt beim tastendruck verändert wurde :-/ Aha. Ist das eine Frage oder ein Einwand? Oder ist es Dir jetzt klar, wie Du die Reaktionszeit minimierst? Denke daran, das eine Reaktionszeit von ca. 100 bis 200ms für den Benutzer nicht wirklich als Verzögerung bemerkt wird. Bei diesem Ansatz musst Du natürlich die in den einzelnen Zuständen auszuführenden Aktionen auf eine solche Zeit begrenzen. Dann gehts.
Novex Xevon schrieb: > Okay.... so in der art hatte ich es auch mal...bzw. ich hatte halt eine > globale variable welche halt den status des hauptpgrogrammes bestimmt > hat!! jedoch war halt da das problem das der zustand des proramms nicht > direkt beim tastendruck verändert wurde :-/ Tja, dann... gibt es wohl keine Loesung fuer Dein Problem. In dem Fall wuerde ich Dir raten, dein Gebastel wegzuschmeissen und Dir nen fertigen RGB-Controller zu kaufen. Patrick
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.