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
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
Muss natürlich heißen:
1 | if( |
2 | (!(PINB & (1<<PINx))) |
3 | && (!(Debounce)) |
4 | )
|
Ingo
Hallo Ingo, wo finde ich denn den ganzen Code zu der Debounce-Variante mit Timer?
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.