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.ä.)
//Edit Prozessor is von der ATTiny Serie
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. ...
hmmm naja, ich weiß auch nicht recht :(
1 | int0_handler: |
2 | inc Zaehler ;wird im Programm genutzt |
3 | ldi Entprellung, 0 ;Register r17 |
4 | int0_back: |
5 | inc Entprellung |
6 | cpi Entprellung, 120 |
7 | brne int0_back |
8 | ldi tmp, (1<<INTF0) |
9 | out gifr, tmp |
10 | reti |
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 ...
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.