Forum: Mikrocontroller und Digitale Elektronik Meine Variante zur Tasterentprellung


von Dennis S. (dennnis)


Lesenswert?

Hallo Zusammen,

da ich ehrlich gesagt die im Tutorial beschriebenen Varianten zur 
Tasterentprellung als Newbie nicht so recht verstanden habe, habe ich 
mich mal rangesetzt und folgende Variante programmiert. Für mich war es 
wichtig zu verstehen wie die Entprellung funktioniert und das ich kein 
delay benutze. Außerdem sollte es egal sein wie lange ich den Taster 
drücke, ohne das er mehrfach die gleichen Daten über die UART sendet.

Was haltet ihr davon?

Ach ja: MC ist ein ATMEGA8 mit 8MHz

#include <avr/io.h>
#include <avr/interrupt.h>
#include "uart.h"
#define F_CPU 8000000UL
#define UART_BAUD_RATE 9600


int main(void)
{
DDRB = 0x01;
PORTB |= (1<<PB1);
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
sei();
int16_t Trigger = 5000;
int16_t Zaehler = 0;
char Taster_ist_gedrueckt =0;

while(1)
{
  if (PINB & (1<<PINB1))
  {
    if (Zaehler >= -Trigger)
    {
      Zaehler--;
    }
    else
    {
      Taster_ist_gedrueckt =0;
    }
      PORTB &= ~(1<<PB0);  //LED aus
    }
    else
    {
      if (Zaehler <= -Trigger)
      {
        Zaehler ++;
      }
      else
      {
        if (Taster_ist_gedrueckt==0)
        {
        uart_puts("X"); //Sende String
        PORTB |= (1<<PB0);  //LED an
        Taster_ist_gedrueckt = 1;
        Zaehler = 0;
        }
      }
    }
}
}

Zur Erklärung: Wenn der Taster gedrückt wird, fängt der MC an die 
Variable 'Zähler' hoch zu zählen. Wenn der Trigger Wert erreicht ist, 
werden die Daten gesendet und die Variable 'Taster_ist_gedrückt' mit 1 
aktiviert. Das verhindert das mehrfach das gleiche gesendet wird. Wenn 
der Taster nicht gedrückt ist oder prellt, zählt er solange die Variable 
runter bis der negative Trigger-Wert erreicht ist und Setzt 
'Taster_ist_gedrückt' wieder auf 0.

Über den Triggerwert kann man je nach MC-Frequenz und restlichem Code 
bestimmen wie lange er wartet/zählen muss um den Taster als gedrück zu 
erkennen.

Gruß
Dennis

von Ingo (Gast)


Lesenswert?

Ist Schrott bzw. unbrauchbar, die Zeit die dein Trigger decrementiert 
wird ist abhängig von der Zykluszeit deines Programms. Ich persönlich 
finde die Variante mit Timer am Beste:
1
if( 
2
    (!(PINB & (1<<PINx)))
3
    && (Debounce)
4
  )
5
{
6
   Funktion();
7
   Debounce = xyz;
8
}
9
10
11
12
ISR (Timer){
13
 if(Debounce){
14
 Debounce--;
15
 }
16
}

Relativ wenig CPU Auslastung und keine Delays...
Lässt sich für beliebig viele Pins anwenden, wenn nötig kann man noch ne 
Fallunterscheidung einbauen wie lange der Taster gedrückt ist. Finde ich 
besser als die hier oft empfohlene Version von Peter Dannegger (is ja 
auch ok)




Ingo

von Ingo (Gast)


Lesenswert?

Muss natürlich heißen:
1
if( 
2
    (!(PINB & (1<<PINx)))
3
    && (!(Debounce))
4
  )


Ingo

von Dennis S. (dennnis)


Lesenswert?

Hallo Ingo,

wo finde ich denn den ganzen Code zu der Debounce-Variante mit Timer?

von Frank D. (Firma: Spezialeinheit) (feuerstein7)


Lesenswert?

Hat da gerade einer "Jehova" gesagt?

von Ingo (Gast)


Lesenswert?

Dennis Scholz schrieb:
> wo finde ich denn den ganzen Code zu der Debounce-Variante mit Timer?
Keine Ahnung, hab noch keine Vorlage gebraucht.

Timer ISR auf 1ms-10ms setzen.
Rest siehe oben.


Wenn du Fragen hast, können wir die gerne klären. Copy Paste ist meist 
immer Schrott wenn man es nicht versteht. Wenn man es verstanden hat 
braucht man keine Copy Paste Vorlage ;-). Is wirklich nicht schwer, isch 
schwöer ;)


Ingo

von Peter D. (peda)


Lesenswert?

Dennis Scholz schrieb:
> und das ich kein
> delay benutze.

Dann mußt Du einen Timerinterrupt benutzen.
Eine Entprellung, die abhängig von der Laufzeit der Mainloop ist, taugt 
nichtmal das Schwarze unterm Fingernagel.
Die Mainloop darf daher nur das Ereignis auswerten, daß der 
Timerinterrupt aufbereitet hat.


Peter

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
Noch kein Account? Hier anmelden.