hiho...
mich würde einma interessieren ob man die im AVR Tutorial beschriebene
einfache Tastenentprellung auch dann verwenden kann, wenn man eben diese
Entprellung auf einen Taster anwenden möchte, der den ext. Interrupt
auslöst?
Es ist ja so, dass bei Anliegen eines Signales sofort INTF0 high wird
und die Interruptroutine auslöst. Oder muss man nur etwas bestimmtes
beachten?
okay,
ich habe ein Möglichkeit gefunden...
man setzt einfach im Interupthandler das Bit INTF0 auf 1(damit kein
neues Interrupt erzielt werden kann) arbeitet eine Pausenschleife ab und
setzt dann INTF0 zurück auf 0 um erneute Interrupts in Empfang zu
nehmen.
Nur leider kann ich in meiner Programmierung das Bit INTF0 nicht auf 1
setzen. Es ist nich Bitaddresierbar und muss mit einer Maske geschehen.
Leider bekomm ich das nich hin, kann mir jemand helfen?
Danke euch...
welcher Prozessor?
Du willst das Flag löschen, richtig? (selber setzen, so dass man es als
1 lesen kann geht natürlich nicht)
Allgemein ginge es so (WENN in <flagregister> NUR interruptflags stehen)
1
ldi r16, 1<<INTF0
2
out <flagregister>, r16 ; GIFR, EIFR - Name hängt vom AVR ab
3
; sts <flagregister>, r16 FALLS bei "out" eine Meldung kommt:
4
; "Operand out of range"
Aber deine 'Lösung' hat noch das Problem, dass du nicht weißt wielange
der letzte Interrupt her ist - oder willst du etwa mehrere Milisekunden
in der ISR warten?
hth. Jörg
na ich habe mir das so gedacht...
wenn ein Interuppt kommt...setzt es ja INTF0 auf 1 und geht unverzüglich
in den Interrupthandler und INTF0 wird wieder 0 gesetzt. Als ersten
Schritt in diesem Handler setze ich sofort wieder dieses Flag auf 1 und
starte dann eine 30 ms Pausenschleife damit in diesen 30 ms kein ext.
Interrupt mehr ausgelöst wird. Das stellt dann quasi meine
Tastentprellung dar. Nach der Pause möchte ich das am Anfang von mir auf
1 gesetzte INTF0 Flag rücksetzen, damit ich dann wieder auf einen ext.
Interrupt reagieren kann. Und ja die ganze Pause von 30 ms soll in dem
Interuppthandler stattfinden, da ich in der Zeit nicht auf ev. andere
Interrupts reagieren muss(ev. TimerOverFlow Flags o.ä.)
Es gibt eigentlich nur einen triftigen Grund, eine Taste an einen
externen Interrupt zu legen, und zwar das Aufwecken des AVRs aus dem
"Tiefschlaf" (Power-Down-Sleep).
Dazu benutzt man (wenn kein PC-Int verfügbar ist) den Low-Level-Mode des
externen Interrupts, der auf Low-Pegel reagiert. In dieser ISR schaltet
man den Sleep-Mode wieder auf Idle (was die Timer aktiviert) und
deaktiviert den ext. Int. Nun ist der Interrupt-Portpin ein ganz
normaler Portpin, der im Timer-Interrupt abgefragt und entprellt wird.
Ein Beispiel mit Tiny15 ist hier zu finden:
http://www.hanneslux.de/avr/divers/melody/melody04.html
...
hmmm naja,
das Problem ist, das ich nicht eine ständige Abfrage des Eingangs machen
möchte/kann, deswegen kommt mir der ext. Interrupt sehr entgegen. Er
läuft ja quasi automatisch ab.
Danke an Jörg X. Dein Programmiervorschlag hat funktioniert und ich muss
sagen die Tastentprellung auf diese Art und Weise funktioniert
einwandfrei.
Ich bin jetzt auch nich der Profiprogrammierer, aber seinen Zweck
erfüllt es allemal.
Soweit so gut...ich danke euch!
Grüße Jürgen.
Jürgen B. wrote:
> hmmm naja,>> das Problem ist, das ich nicht eine ständige Abfrage des Eingangs machen> möchte/kann,
Das erkläre mal etwas genauer. Ich vermute da ein ganz großes
Missverständnis.
Denn die Entprellung von bis zu 8 Tastern auf dem AVR kostet 11
Taktzyklen alle 10ms, also bei 1MHz alle 10000 Takte. Rechnet man noch
den Overhead des Timer-Interrupts dazu, so sind das etwa 20 Taktzyklen
alle 10000 Takte, das sind gerade mal 0,2% der verfügbaren
Rechenleistung.
> deswegen kommt mir der ext. Interrupt sehr entgegen. Er> läuft ja quasi automatisch ab.
Der macht eigentlich nur Sinn, wenn man den Controller total abschaltet
(Power-Down) um Strom zu sparen. Denn dann greift nur noch der
Low-Level-Mode des externen Interrupts oder (wenn vorhanden) der
Pinchange-Interrupt. Zum eigentlichen Entprellen der Tasten ist
zyklische Abfrage per Timer-Interrupt (der nebenbei noch andere Dinge
erledigen kann) die beste und einfachste Methode.
...
kurze Erklärung zu: ldi tmp, (1<<INTF0)
out gifr, tmp
wenn in der Abarbeitung der Schleife ein weiterer ext. Interrupt
vorliegt(was durch das Prellen an sich entsteht) wird er an diesem Punkt
wieder gelöscht, genauer das overflowflag welchen einen erneuten Sprung
in den Interrupthandler bedeuten würde.
--------------------
so das ist jetzt mein interrupt handler, wenn ein externer interrupt
ausgelöst wurde (durch Drücken eines tasters), springt das Programm
hinein.
Ich weiß das ist jetzt nicht die Krönung des Programmierens aber müsste
doch funktionieren?
@ hannes Lux: ich weis glaube was du meinst.
du gehst sicher in der form heran du die in regelmäßigen zeiträumen
einen timeroverflow erzeugst und dann den eingang abfragst. das problem
was ich habe ist jedoch das ich bei meinen attiny15 nur 2 timer zur
verfügung habe und diese schon in benutzung sind.
Jürgen B. wrote:
> @ hannes Lux: ich weis glaube was du meinst.>> du gehst sicher in der form heran du die in regelmäßigen zeiträumen> einen timeroverflow erzeugst und dann den eingang abfragst. das problem> was ich habe ist jedoch das ich bei meinen attiny15 nur 2 timer zur> verfügung habe und diese schon in benutzung sind.
Wo ist das Problem? Die Tastenentprellung kann ein Timer nebenbei, also
neben seiner normalen Aufgabe, erledigen. Notfalls kann man ja auch den
ADC als Timer missbrauchen. Hier ist ein Beispiel mit Tiny15:
http://www.hanneslux.de/avr/divers/melody/melody04.html
...