Hallo alle zusammen ich brauch wieder mal Eure Hilfe. Ich möchte, dass innerhalb eines Interrupts (extern) der Interrupt selbst nicht mehr aufgerufen werden kann. Also so dass beim Durchlaufen des im Interrupt implementierten Befehle, der Interrupt nicht erneut ausgelöst werden kann. Sinn des Ganzen ist, dass beim Drücken des Tasters ein Interrupt aufgerufen wird. Wird der Taster weiterhin gedrückt (1 Sekunde) so springt er in die if-Bedingung -> level=7. Der Taster soll auch innerhalb der einen Sekunde losgelassen werden dürfen. Mein Code (ATTINY84): ISR(INT0_vect) { cli(); // Deaktivierung des Interrupts??? GIMSK&=~(1<<INT0); // Deaktivierung des Interrupts??? _delay_ms(1000); if(TASTER_BETATIGT) { level=7; } else { level++; if(level>4) level=0; } durchlauf=1; GIMSK|=(1<<INT0); // Aktivierung des Interrupts??? sei(); // Aktivierung des Interrupts??? } Meiner Meinung nach sollte es so Funktionieren. Leider tut es aber so nicht.
Das lass mal alles bleiben * während eine ISR läuft, sind andere Interrupts sowieso gesperrt Du brauchst also nichts dazutun, eine ISR wird nicht durch eine andere ISR unterbrochen * Delays (ausser vielleicht ganz kurzen im µs Bereich) sollten für dich in einer ISR verboten sein. Merkregel: In einer ISR wird grundsätzlich nicht gewartet. Auf nix und niemanden * Tastenauswertung macht man nicht indem die Taste einen Interrupt auslöst. Such in den Artikeln nach "Entprellung" und du kriegst eine erstklassige Tastenauswertung auf dem Silbertablett serviert.
Leider muss ich bei dem Programm mit einem Interrupt arbeiten.
wenn ich in der ISR die Delay-Funktion aufrufe, wird diese nicht ausgeführt oder wie soll ich das verstehen??
Eugen V. schrieb:
> Leider muss ich bei dem Programm mit einem Interrupt arbeiten.
Warum musst du?
Eugen V. schrieb: > wenn ich in der ISR die Delay-Funktion aufrufe, wird diese nicht > ausgeführt oder wie soll ich das verstehen?? Doch. Genau das ist ja das Problem :-) Der Prozessor kann in der Zwischenzeit nichts anderes machen als Däumchen drehen, bis die Zeit rum ist. Wenn dir das egal ist, ok. Mir wäre es nicht egal, wenn mein µC 'einfriert' sobald ich eine Taste drücke.
Karl heinz Buchegger schrieb: > Eugen V. schrieb: >> Leider muss ich bei dem Programm mit einem Interrupt arbeiten. > > Warum musst du? Weil das Programm so konzepiert ist! >Eugen V. schrieb: >> wenn ich in der ISR die Delay-Funktion aufrufe, wird diese nicht >> ausgeführt oder wie soll ich das verstehen?? >Doch. >Genau das ist ja das Problem :-) >Der Prozessor kann in der Zwischenzeit nichts anderes machen als >Däumchen drehen, bis die Zeit rum ist. >Wenn dir das egal ist, ok. >Mir wäre es nicht egal, wenn mein µC 'einfriert' sobald ich eine Taste >drücke. Ja mir ist es nicht nur egal, es muss auch so sein. Das Problemm ist aber, dass bei erneuten Drücken des Tasters der interrupt nochmal gestartet wird! Ich möchte doch nur eine Erklärung warum es so passiert und keine Fragen wieso was im Programm wie sein muss.
Gast
#1498027
>Weil das Programm so konzepiert ist! Schlechteste Ausrede wo gibt. (Ausserdem heisst es "konzipiert".) >GIMSK|=(1<<INT0); // Aktivierung des Interrupts??? Danach solltest du dir mal das zugehörige Interrupt-Flag angucken und ggf. zurücksetzen. >Der Taster soll auch innerhalb der einen Sekunde losgelassen werden >dürfen. Kriegt dein Program gar nicht mit.
Eugen V. schrieb: >> Warum musst du? > > Weil das Programm so konzepiert ist! Im Regelfall: schlechte Konzeption >>Wenn dir das egal ist, ok. >>Mir wäre es nicht egal, wenn mein µC 'einfriert' sobald ich eine Taste >>drücke. > > Ja mir ist es nicht nur egal, es muss auch so sein. > > Das Problemm ist aber, dass bei erneuten Drücken des Tasters der > interrupt nochmal gestartet wird! > Ich möchte doch nur eine Erklärung warum es so passiert und keine Fragen > wieso was im Programm wie sein muss. Gut. Weil durch das Drücken des Tasters das Interrupt Flag gesetzt wird. Und bei der Ausführung des nächsten Befehls, bei dem die Interrupts wieder aktiviert sind, wird u.A. auch dieses Flag geprüft, festgestellt, dass in der Zwischenzeit eine Interrupt Anforderung eingegangen ist und die ISR erneut angesprungen. Details dazu finden sich, wie immer, im Datenblatt.
Eugen V. schrieb: > Karl heinz Buchegger schrieb: >> Eugen V. schrieb: >>> Leider muss ich bei dem Programm mit einem Interrupt arbeiten. >> >> Warum musst du? > > Weil das Programm so konzepiert ist! Dann ist das Konzept schlichtweg falsch! Tasten fragt man zwar in nem Interrupt ab, aber das ist der Timerinterrupt. Besonders effiziente Tastenroutinen liefern auch gleich noch die Flanke. Damit ist das Reagieren auf das gedrückt werden popeleinfach und das gedrückt halten hat keine negativen Auswirkungen. >>Mir wäre es nicht egal, wenn mein µC 'einfriert' sobald ich eine Taste >>drücke. > > Ja mir ist es nicht nur egal, es muss auch so sein. Dann bist Du der erste Programmierer auf der Welt, der das so will. > Das Problemm ist aber, dass bei erneuten Drücken des Tasters der > interrupt nochmal gestartet wird! Super, Du hast also schon gemerkt, warum ein externer Interrupt schlecht geeignet ist. > Ich möchte doch nur eine Erklärung warum es so passiert und keine Fragen > wieso was im Programm wie sein muss. Such mal nach Entprellung / Debounce. Peter
Gast
#1498036
>>Weil das Programm so konzepiert ist! >Schlechteste Ausrede wo gibt. Ist doch egal. Wenn er es so will, dann kriegt er es. Nicht unser Problem. @Eugen: Lass die Deaktivierung und Aktivierung weg, das macht alles der Compiler für dich. Auf Tastendruck kommst du in die ISR und wartest dort 1000 ms lang. Während dieser Zeit ist dein Programm absolut tot, kein LED-Blinken, keine Display-Ausgabe, keine Reaktion an irgendeiner Schnittstelle. Das Programm bleibt auf jeden Fall 1000 ms lang hängen - auch wenn die Taste schon nach 100 ms losgelassen wird, kommt die Reaktion erst nach der ganzen Sekunde. Wenn es das ist, was du willst, dann mach es so.
> cli(); // Deaktivierung des Interrupts??? Weg damit, macht die CPU eh. > GIMSK&=~(1<<INT0); // Deaktivierung des Interrupts??? Kann weg, ist doppelt gemoppelt. Wozu Interrupts verhindern, wenn eh keine ausgeführt werden? > _delay_ms(1000); 1000 ist nicht. Da liegt die Katze wohl im Sack und was Du sonst beobachtest, sind Folgefehler. Aus der Dokumentation zu <util/delay.h>:
1 | |
> [...] > sei(); // Aktivierung des Interrupts??? > } sei() direkt vor Ende der ISR vergrößert nur das Stack (evtl. anstehende Interrupts werden im Stack des vorangehenden ausgeführt) und sind überflüssig (der nachfolgende reti erlaubt Interrupts eh wieder).
STK500-Besitzer schrieb: >>Weil das Programm so konzepiert ist! > > Schlechteste Ausrede wo gibt. Nicht nur das, es macht ein funktionierendes Programm völlig unmöglich! Niemand ist fehlerfrei und damit auch kein Konzept. Programmmieren ist ein iterativer Prozess, wo Programmieren und Korrigieren des Konzepts in ständigem Wechsel erfolgen. Nur dann kann was Sinnvolles herauskommen. Peter
Karl heinz Buchegger schrieb: > Weil durch das Drücken des Tasters das Interrupt Flag gesetzt wird. Und > bei der Ausführung des nächsten Befehls, bei dem die Interrupts wieder > aktiviert sind, wird u.A. auch dieses Flag geprüft, festgestellt, dass > in der Zwischenzeit eine Interrupt Anforderung eingegangen ist und die > ISR erneut angesprungen. Aber wird das Interruptflag nicht bei Einsprung in die ISR gelöscht? Ich vermute eher, das der externe Interrupt auf "level" steht und damit so lange ausgelöst wird, wie die Taste gedrückt wird. > Details dazu finden sich, wie immer, im Datenblatt. Steht gleich in einem der ersten Sätze unter "External Interrupts" :-) Reinhard
Reinhard R. schrieb: > Karl heinz Buchegger schrieb: >> Weil durch das Drücken des Tasters das Interrupt Flag gesetzt wird. Und >> bei der Ausführung des nächsten Befehls, bei dem die Interrupts wieder >> aktiviert sind, wird u.A. auch dieses Flag geprüft, festgestellt, dass >> in der Zwischenzeit eine Interrupt Anforderung eingegangen ist und die >> ISR erneut angesprungen. > Aber wird das Interruptflag nicht bei Einsprung in die ISR gelöscht? Schon. Aber seine ISR wartet da drinnen 1 Sekunde. Wenn der Benutzer ungeduldig wird und auf der Taste rumhämmert, weil sich nichts tut, dann wird das entsprechende Flag wieder gesetzt. Dieses Flag ist ja unabhängig davon, was im Prozessor gerade ausgeführt wird.
STK500-Besitzer schrieb: >>Weil das Programm so konzepiert ist! > > Schlechteste Ausrede wo gibt. > (Ausserdem heisst es "konzipiert".) > > >>GIMSK|=(1<<INT0); // Aktivierung des Interrupts??? > Danach solltest du dir mal das zugehörige Interrupt-Flag angucken und > ggf. zurücksetzen. > >>Der Taster soll auch innerhalb der einen Sekunde losgelassen werden >dürfen. > > Kriegt dein Program gar nicht mit. Wenn ich mir das genau ansehe, frage ich mich, was das Folgende heißen soll: >> Schlechteste Ausrede wo gibt. zu >> (Ausserdem heisst es "konzipiert".) Außerdem heisst es nicht "Ausserdem", sondern "Außerdem", zu "heisst" schreibe ich mal nichts :) :P Habe noch zwei Fehler bei mir gefunden, "interrupt" muss groß und "Problemm" nur mit einem m geschrieben werden Spaß! Soll dich nicht angreifen. Ich glaube man versteht mich hier falsch. Ich möchte nichts entprellen, weil es bei diesem Taster nicht nötig ist. Das Problem ist aber, dass bei erneuten Drücken des Tasters der Interrupt nochmal gestartet wird! >>Der Taster soll auch innerhalb der einen Sekunde losgelassen werden >>dürfen. >> > Kriegt dein Program gar nicht mit. Sorry, die Beschreibung war ungenau. Wenn der Taster innerhalb der einen Sekunde losgelassen und sofort gedrückt und auch gedrückt gehalten wird, soll level=7 gesetzt werden.
Reinhard R. schrieb: > Karl heinz Buchegger schrieb: >> Weil durch das Drücken des Tasters das Interrupt Flag gesetzt wird. Und >> bei der Ausführung des nächsten Befehls, bei dem die Interrupts wieder >> aktiviert sind, wird u.A. auch dieses Flag geprüft, festgestellt, dass >> in der Zwischenzeit eine Interrupt Anforderung eingegangen ist und die >> ISR erneut angesprungen. > Aber wird das Interruptflag nicht bei Einsprung in die ISR gelöscht? > > Ich vermute eher, das der externe Interrupt auf "level" steht und damit > so lange ausgelöst wird, wie die Taste gedrückt wird. > >> Details dazu finden sich, wie immer, im Datenblatt. > Steht gleich in einem der ersten Sätze unter "External Interrupts" :-) > > Reinhard MCUCR ist so gesetzt, dass die fallende Flanke an INT0 einen Interrupt erzeugen.
Hazeh Zimmerer schrieb: > > 1000 ist nicht. Da liegt die Katze wohl im Sack und was Du sonst > beobachtest, sind Folgefehler. Aus der Dokumentation zu <util/delay.h>: >
1 | |
2 | |
vielleicht solltest du auch den nächsten Abschnitt zitieren
1 | |
2 | |
3 | |
4 | |
5 | |
tuppes schrieb: >>>Weil das Programm so konzepiert ist! >>Schlechteste Ausrede wo gibt. > > Ist doch egal. Wenn er es so will, dann kriegt er es. Nicht unser > Problem. > > @Eugen: > > Lass die Deaktivierung und Aktivierung weg, das macht alles der Compiler > für dich. > > Auf Tastendruck kommst du in die ISR und wartest dort 1000 ms lang. > Während dieser Zeit ist dein Programm absolut tot, kein LED-Blinken, > keine Display-Ausgabe, keine Reaktion an irgendeiner Schnittstelle. > > Das Programm bleibt auf jeden Fall 1000 ms lang hängen - auch wenn die > Taste schon nach 100 ms losgelassen wird, kommt die Reaktion erst nach > der ganzen Sekunde. > > Wenn es das ist, was du willst, dann mach es so. Ja das meinte ich! wenn der Taster am INT0 nach einer Sekunde immer noch gedrückt ist -> level=7. Habe einen Piezotaster, dieser reagiert nur auf Druckänderung und schließt die Kontakte für ca. 200ms-700ms. Meine Idee ist dass wenn ich den Taster die ganze Zeit tippe, dann soll level = 7 gesetzt werden, sonst nicht. leider wird beim Tippen der ISR mehrmals aufgerufen. (Drücke ich den Taster 2x, so wird level um 2 erhöht) :(
Ach ja, mit einem normalen Taster funktioniert es wie gewollt.
Eugen V. schrieb: > Reinhard R. schrieb: >> Ich vermute eher, das der externe Interrupt auf "level" steht und damit >> so lange ausgelöst wird, wie die Taste gedrückt wird. > ... > MCUCR ist so gesetzt, dass die fallende Flanke an INT0 einen Interrupt > erzeugen. Na dann passt es ja. Ansonsten kann ich mich nur den Vorpostern betreffs Delay in ISR anschließen. Überdenke Dein Konzept nochmal. Reinhard
Wie kann der Taster für 1 Sekunde gedrückt sein, wenn dein Piezzo-Taster einen Puls von max. 700ms Dauer abgibt?
Karl heinz Buchegger schrieb: > Wie kann der Taster für 1 Sekunde gedrückt sein, wenn dein Piezzo-Taster > einen Puls von max. 700ms Dauer abgibt? Immer Tippen. Das Problem ist, das bei erneuten Druck auf den Taster ISR gestartet wird. Naja ich schreibe mal meine Programmchen mal um, habe da eine Idee.
Aber nochmal. Interrupts sind eine 2-stufige Geschichte! Zum einen ist da das Interrupt Flag. Zum anderen ist da das Aufrufen der Interrupt Funktion. Das Setzen des Interrupt Flags kannst du nicht verhindern. Das macht die Hardware und ist als eine Art "Interrupt requested" zu sehen. Daran schliesst sich die Auswertung dieser Flags nach jedem µC-Befehl an. Ist das Requested Flag gesetzt UND ist der Interrupt freigegeben, dann wird die ISR aufgerufen. Mit jedem Tastendruck wird das Requested Flag erneut gesetzt, undabhängig davon, was der µC gerade macht. Aber man kann dieses Flag ja auch gezielt löschen, wenn man der Meinung ist, im Programm an einem Punkt angekommen zu sein, an dem durch den Taster ausgelöste weitere Anforderungen zu ignorieren sind. -> Datenblatt
Eugen V. schrieb: > Karl heinz Buchegger schrieb: >> Wie kann der Taster für 1 Sekunde gedrückt sein, wenn dein Piezzo-Taster >> einen Puls von max. 700ms Dauer abgibt? > > Immer Tippen. > Das Problem ist, das bei erneuten Druck auf den Taster ISR gestartet > wird. > > Naja ich schreibe mal meine Programmchen mal um, habe da eine Idee. Das wäre sowieso das beste. Aber selbst wenn nicht, solltest du dir endlich mal die Tipps zu Herzen nehmen und im Datenblatt die entsprechenden Abschnitte studieren!
Karl heinz Buchegger schrieb: > Aber nochmal. > Interrupts sind eine 2-stufige Geschichte! >.. > > -> Datenblatt Ja genau die Antwort auf meine Frage! Danke! Werde da mal nachschauen.
Justus Skorps schrieb: > Hazeh Zimmerer schrieb: >>
1 | |
2 | |
> > vielleicht solltest du auch den nächsten Abschnitt zitieren Vielleicht sollte ich mir eher eine aktuelle Ausgabe ausdrucken, denn in meinem libc-Maual (1.4.5) gibt es keinen nächsten Abschnitt, den man zitieren könnte ...
Habe diesen Effekt ausgenutzt und das Programm so verändert, dass das Selbe ereicht wird
Gast
#1498144
> Habe einen Piezotaster, dieser ... schließt die Kontakte > für ca. 200ms-700ms. Meine Idee ist dass wenn ich > den Taster die ganze Zeit tippe ... Also, mit Verlaub, mit kranken Softwarekonzepten, die aus der Not geboren sind, kann man ja unter Umständen leben, wenn das ne Hauptsache-klein-und-billig-Anwendung wird, die nicht gepflegt werden muss. Aber das da scheint mir ein krankes Bedienkonzept zu sein, Drücken und Halten geht nicht, also tippen wir uns eben den Wolf ... Wird das ein Gerät, das an Kunden verkauft werden soll? Schon mal versucht, die Bedienungsanleitung so zu formulieren, dass der Käufer sich nicht ver*rscht vorkommt?
tuppes schrieb: >> Habe einen Piezotaster, dieser ... schließt die Kontakte >> für ca. 200ms-700ms. Meine Idee ist dass wenn ich >> den Taster die ganze Zeit tippe ... > > Also, mit Verlaub, mit kranken Softwarekonzepten, die aus der Not > geboren sind, kann man ja unter Umständen leben, wenn das ne > Hauptsache-klein-und-billig-Anwendung wird, die nicht gepflegt werden > muss. > > Aber das da scheint mir ein krankes Bedienkonzept zu sein, Drücken und > Halten geht nicht, also tippen wir uns eben den Wolf ... > > Wird das ein Gerät, das an Kunden verkauft werden soll? Schon mal > versucht, die Bedienungsanleitung so zu formulieren, dass der Käufer > sich nicht ver*rscht vorkommt? WELCHER KÄUFER????? :)))))) Es ist keine Antwort auf meine Frage. Ich verstehe nicht wieso die Menschen in vielen Foren dazu neigen sowas reinzuschreiben???? Wenn man nicht mal weis was es ist und wo es eingesetzt wird, sollte man es auch nicht beurteilen. :) Ich muss gerade sogar lachen.
Gast
#1498167
Am schlimmsten bei Leuten wie Eugen V. ist, dass sie völlig lernresistent sind. Da wird ihnen tausendmal erklärt, warum etwas schon von der Konzeption her falsch ist, aber sie reagieren überhaupt nicht darauf...
Eugen V. schrieb: > Es ist keine Antwort auf meine Frage. Ich verstehe nicht wieso die > Menschen in vielen Foren dazu neigen sowas reinzuschreiben???? Wenn man > nicht mal weis was es ist und wo es eingesetzt wird, sollte man es auch > nicht beurteilen. Das ist relativ egal. Es gibt ganz einfach Konzepte, die sich bewährt haben und es gibt Konzepte die sich nicht bewährt haben. Taster an Interrupts anzuschliessen und dies zur Auswertung von Tastendrücken zu benutzen, ist ein Konzept, welches sich nicht bewährt hat. Und das ist unabhängig davon, ob man nur für sich selber programmiert, oder ob man seine Brötchen damit verdient. Das Problem ist, dass Profis das wissen. Sie haben sowas oft genug gemacht um das Kochrezept für eine wasserdichte Tastenabfrage zu kennen sowie das Kochrezept, wie man auf einem µC die grundsätzliche Programmstruktur anlegt, so dass die Grundstruktur leicht auf so ziemlich jede Aufgabenstellung angewandt werden kann. Als Folge davon entstehen bei ihnen Programme, die leicht wartbar sind und auch von anderen Programmierern, die das grundsätzliche Konzept natürlich ebenfalls kennen, leicht verstanden werden können. Lediglich die Nicht-Profi Liga erfindet immer wieder krude Konzepte von denen sie denkt, dass sie super-toll sind, die sich aber über kurz oder lang immer als Bumerang herausstellen. Da tritt dann oft genau dieser Effekt auf: Eine schnell-schnell Implementierung, die zwar anscheinend auf Anhieb gut funktioniert, bei der man aber ja nichts ändern darf, weil sonst alles zusammenbricht.
Ich machs für mich selbst:)
entschuldigt mich. Aber ich versuch was wo keiner weiss was es ist und wie der rest des Programms aussieht. Deshalb verstehen ich die Einwende nicht.
In der Codesammlung im Scheduler Beispiel habe ich ne Treppenhausbeleuchtung programmiert mit folgender Funktion:
1 | |
2 | |
3 | |
4 | |
Alles ist entprellt, nirgends wird gewartet. Daher macht die CPU noch 2 weitere Aufgaben gleichzeitig. Das zweimal Drücken ist deutlich nutzerfreundlicher, als eine Sekunde drauf rumhämmern. Peter
Peter Dannegger schrieb: > In der Codesammlung im Scheduler Beispiel habe ich ne > Treppenhausbeleuchtung programmiert mit folgender Funktion: >
1 | |
2 | |
3 | |
4 | |
5 | |
> > Alles ist entprellt, nirgends wird gewartet. Daher macht die CPU noch 2 > weitere Aufgaben gleichzeitig. > > > Peter Danke, ich schaue es mir gerade an.
Gast
#1498310
>Programmmieren ist ein iterativer Prozess, wo Programmieren und >Korrigieren des Konzepts in ständigem Wechsel erfolgen. Erzähl das mal meinem Kollegen, der scheinbar das perfekte Konzept für diverse Programme hat. Sein Konzept wird durchgezogen, egal, ob es fehlerhaft ist, oder nicht. >Außerdem heisst es nicht "Ausserdem", sondern "Außerdem", zu "heisst" >schreibe ich mal nichts :) Die Doppel-S-Schreibweise ist aber eine Alternative zur Schreibweise mit "ß". Deine Wortkreation ist einfach nur falsch (wie dein Konzept, um noch etwas draufrum zu reiten). Übrigens funktioniert dein Programm nicht, weil die DWIW-Unit des AVR noch sehr beta ist.
STK500-Besitzer schrieb: > >>Außerdem heisst es nicht "Ausserdem", sondern "Außerdem", zu "heisst" >>schreibe ich mal nichts :) > > Die Doppel-S-Schreibweise ist aber eine Alternative zur Schreibweise mit > "ß". Deine Wortkreation ist einfach nur falsch (wie dein Konzept, um Mal abgesehen davon, dass es Leute gibt, deren Tastatur besagtes Zeichen nicht hat...
Gast
#1498339
Leute, Schluss jetzt mit dem Rechtschreibtheater! http://potassium.1338.at/upload/share/hans.jpg
:)))))))))))))))
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
