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.
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.
>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
>>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
The maxiamal possible delay is 262.14ms/F_CPU in MHz.
> [...]> 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
> The maxiamal possible delay is 262.14ms/F_CPU in MHz.
2
>
vielleicht solltest du auch den nächsten Abschnitt zitieren
1
When the user request delay which exceed the maximum possible one,
2
_delay_ms() provides a decreased resolution functionality. In this
3
mode _delay_ms() will work with a resolution of 1/10 ms, providing
4
delays up to 6.5535 seconds (independent from CPU frequency). The
5
user will not be informed about decreased resolution.
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) :(
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
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.
>> The maxiamal possible delay is 262.14ms/F_CPU in MHz.
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 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.
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.
In der Codesammlung im Scheduler Beispiel habe ich ne
Treppenhausbeleuchtung programmiert mit folgender Funktion:
1
Licht aus & einmal drücken -> Licht an, Timer läuft ab
2
Licht an & einmal drücken -> Timer läuft neu ab
3
Licht an & zweimal drücken innerhalb 0,8s -> Licht aus
4
Licht an & Timer abgelaufen -> Licht aus
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
> Licht aus & einmal drücken -> Licht an, Timer läuft ab
2
> Licht an & einmal drücken -> Timer läuft neu ab
3
> Licht an & zweimal drücken innerhalb 0,8s -> Licht aus
4
> Licht an & Timer abgelaufen -> Licht aus
5
>
>> Alles ist entprellt, nirgends wird gewartet. Daher macht die CPU noch 2> weitere Aufgaben gleichzeitig.>>> Peter
Danke, ich schaue es mir gerade an.
>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...