mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit Taste kurz / Taste lang!


Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich tüftle gerade daran, einen langen Tastendruck zu erkennen und damit 
eine Routine für eine LED-Dimmung auszuführen.

Wird die Taste 9 gedrückt, wird in der ISR "9" in Taste gespeichert. Der 
Tastenwert 9 bleibt also solange erhalten, bis eine andere Taste 
gedrückt wird.

Bei einem Tastendruck wird alle 35ms ein Interrupt ausgelöst.

Folgendes soll passieren:

Wenn Taste 9 == kurz --> dimm LED um + 20%
Wenn Taste 9 == lang --> dimm LED stufenlos solange Taste 9 gedrückt 
wird

Bitte um einen Vorschlag, wie ich das lösen kann!

Die Abfrage der Taste passiert in main unter
while(1)
{
    if( Taste == 9 und kurz)       
    {
        OCR0SA = valuetable[ value + 20% ];
    }
    if (Taste == 9 und lang)      
    {
        OCR0SA = valuetable[ value + x ];
    }
}

Hier die ISR:
ISR(INT2_vect)  // Int.2 on PB5
{
    Payload_RX(0x61, 0x00);    // Read FIFO payload

    Taste = SPDR;             // and store value in Taste

    Flush_RX();      // clear  RX-FIFO
}

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn es nur funktionieren soll, dann kannst du dir ja mal Peter 
Danneggers Routine anschauen.

Entprellung: Interrupt-Verfahren nach Peter Dannegger

- gerd

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, die Routine kenne ich. Sie hilft mir hier aber nicht weiter, da 
in meinem Fall der Tastenwert als fixer Wert zugewiesen wird und zwar 
solange, bis eine andere Taste gedrückt wird.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann baue einen Zähler ein für die Anzahl dieser Tastenwerte. Damit 
unterscheidest du kurze Tastendrücke (niedriger Zählerstand) von langen 
(hoher Zählerstand)

Damit das funktioniert brauchst du aber einen "Stopper" für den Zähler.

Der Stopper wäre idealerweise bei der Taste und liefert über SPI ein 
Event "Taste-Losgelassen". Dann brauchst du keine 2. Taste zu drücken.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heimo G. schrieb:
> Danke, die Routine kenne ich. Sie hilft mir hier aber nicht weiter, da
> in meinem Fall der Tastenwert als fixer Wert zugewiesen wird und zwar
> solange, bis eine andere Taste gedrückt wird.

Und?

Die Erkennung von Tasten und die Auswertung was ein Tastendruck machen 
soll, sollte man sowieso voneinander trennen. Der in der Danegger Lösung 
eingebaute Autorepeat erledigt deine Anforderungen mit Leichtigkeit.

Das einzige Problem: Du hast keine physischen Tasten am µC 
angeschlossen. Aber auch das lässt sich lösen indem man die Danegger 
Entprellung auf simulierte Tastenbits loslässt, die von deiner FIFO ISR 
entsprechend umgestellt werden.

Das heißt: Der entscheidende Schritt besteht nicht darin, da jetzt in 
der Auswertung rumzufuhrwerken. Der entscheidende Schritt ist die Frage: 
Wie sind eigentlich deine Tasten angeschlossen, bzw. wodurch wird der 
Interrupt ausgelöst bzw. wäre ein regelmässiges Polling (des 
Schieberegisters?) nicht eigentlich besser?

Autor: Artur R. (artur2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du kannst es so lösen:
Du nimmst einen Timer der per Interrupt alle 100ms eine Variabel 
hochzählt, z.B:

ISR(TIMER1_COMPA_vect){
  hSekunden++;
  if (hSekunden >= 864000)//24h vorbei,wieder auf 0
    Sekunden = 0;
}

Danach kommt dein Zeug ins Spiel:

while(1)
{
    if( Taste == 9)
    {
        i_var=hSekunden;
    }
    while ((Taste == 9 und (hSekunden-i_var)< 10) // eine Sekunde )
    {
        OCR0SA = valuetable[ value + 20% ];
    }
    while (Taste == 9 und (hSekunden-i_var) >= 10) // eine Sekunde
    {
        OCR0SA = valuetable[ value + x ];
    }
}

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kann ich so nicht lösen, da ich bei einem Tastendruck alle 35ms 
einen Interrupt auslöse!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heimo G. schrieb:
> Das kann ich so nicht lösen, da ich bei einem Tastendruck alle 35ms
> einen Interrupt auslöse!

Na dann nimmst Du eben nicht 10ms, sondern 50ms für den Timerinterrupt. 
Und die lang-/kurz Zeiten werden auf 50ms-Schritte berechnet.

Wird das Tasteinputbit alle 35ms gesetzt, ist es also nach 50ms 
garantiert gesetzt, solange gedrückt wird.


Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.