Hallo, ich grad ein kleines Problem damit die Tasterentprellung per Flankenerkennung aus folgendem Artikel richtig zu verstehen. https://www.mikrocontroller.net/articles/Entprellung#Flankenerkennung Warum ist bei dieser Methode kein delay notwendig? Wenn der Controller schnell genug läuft um einen "ganzen Prellvorgang" abtasten zu können werden hier doch nach wie vor mehrere Tastendrücke erkannt oder?
Michael schrieb: > Warum ist bei dieser Methode kein delay notwendig? Ist es: "Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms." Die Funktion taster() wird also in der Programmhauptschleife eingesetzt, die eine Laufzeit passend zur Entprellung haben sollte oder mit einem Delay dahingehend verlangsamt werden sollte.
1 | while(1) |
2 | {
|
3 | |
4 | if(taster()) |
5 | {
|
6 | }
|
7 | :
|
8 | _delay_ms(10); |
9 | }
|
Ich behaupte das macht sie auch nicht. Hier wird lediglich, wie in der Überschrift steht, die Flankenerkennung durchgeführt. Für eine Software Entprellung fallen mir nur zwei möglichkeiten ein : 1. Per Delay eine gewisse "Prellzeit" warten. 2. Das Signal regelmässig abtasten und ab einer gewissen Schwellzeit davon ausgehen das dass Prellen vorbei ist. 3. Möglichkeit 2 mit dem Stoff der "Flankenerkennung" kombinieren.
MaWin schrieb: > while(1) > { > > if(taster()) > { > } > : > _delay_ms(10); > } So kann ich die Entprellung nachvolziehen. Vielleicht sollte man diesbezüglich im Artikel einen kleinen Hinweis einfügen!?
Thomas W. schrieb: > Ich behaupte das macht sie auch nicht. > Hier wird lediglich, wie in der Überschrift steht, die Flankenerkennung > durchgeführt. Der Code auf dem ich in meinem ersten Post verwiesen habe befindet sich allerdings im Artikel mit dem Titel "Entprellung". Daher wäre es meiner Meinung nach Sinnvoll das Kapitel um einen entsprechenden Hinweis zu ergänzen.
Was spräche gegen eine Hardwareentprellung ?? Ok, etwas mehr Aufwand und mehr Kosten bei Massenproduktionen aber man könnte die Software damit entlasten und ggf. auch beschleunigen, falls nötig.
Ich mache die Entprellung mit einem Timer :
interrupt timer0-overflow() {
..reload timer fuer 10ms tick..
timercame=1;
}
main ()
timer=0;
..
loop forever{
if timercame==1 {
..
if taste.. { .. }
timer=0;
}
}
Dh der Softwareaufwand ist fast Null. Das per hardware zu schlagen ist
eigentlich nicht moeglich.
Das stimmt. Die Timer Variante habe ich auch immer gemacht aber mit der Hardwarevariante wäre man softwareunabhängig und weniger fehleranfällig. Aber trotzdem schön zu hören, warum man trotzdem auf Software greift und auf welche Art.
Outi O. schrieb: > Was spräche gegen eine Hardwareentprellung ?? > > Ok, etwas mehr Aufwand und mehr Kosten bei Massenproduktionen aber man > könnte die Software damit entlasten und ggf. auch beschleunigen, falls > nötig. Es ging mir nicht darum die beste Methode zu finden. Ich wollte lediglich die oben genannte Variante korrekt verstehen und nachvollziehen können.
Jetzt N. schrieb: > Dh der Softwareaufwand ist fast Null. Du hast keine einzige Zeile eingespart, sondern musst zusätzlich den Hardware timer intialisieren, eine Interrupt-Routine schreiben, UND brauchst trotzdem denselben Aufwand in der Hauoptschleife, die auch nicht zu langsam sein darf, sonst reagiert deine Tastatur nicht. So ist das also Unsinn. Es können andere, zusätzlich Gründe dafür sprechen in der Programmhauptschleife einen festen Timertick auswerten zu können, aber bloss für die Tastaturabfrage lohnt das nicht.
1 | uint8_t tasten,gedrueckt; |
2 | |
3 | while(1)// die Programm-Hauptschleife |
4 | {
|
5 | tasten=PIND; // 8 Taster auf ein mal, liefern 1 wenn gedrückt (sonst ~PIND) |
6 | gedrueckt=tasten&~gedrueckt; |
7 | if(gedrueckt&1) |
8 | {
|
9 | // Taster 1 wurde gerade runtergedrückt, mach was
|
10 | }
|
11 | if(gedrueckt&2) |
12 | {
|
13 | // Taster 2 wurde gerade runtergedrückt, mach was
|
14 | }
|
15 | // mach was sonst in der Programm-Hauptschleife passieren muß
|
16 | gedrueckt=tasten; |
17 | _delay_ms(10); // damit sie bestimmt länger dauert als eventuelles Prellen |
18 | }
|
Michael schrieb: > Warum ist bei dieser Methode kein delay notwendig? "Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms." Und sowas ist absoluter Murks^3. Kurze Laufzeiten muß man durch Delays auffüllen bzw. lange Laufzeiten lassen Drücke vergessen. Man erlegt sich damit nur unnötige Einschränkungen auf, an die man ständig denken muß. Ich will keine Nebeneffekte beachten müssen, sondern mich beim Programmieren voll auf die eigentliche Aufgabe konzentrieren können. Man sollte immer Routinen bevorzugen, die sowenig wie möglich Seiteneffekte haben oder Vorbedingungen stellen.
mawin :
>Es können andere, zusätzlich Gründe dafür sprechen in der
Programmhauptschleife einen festen Timertick auswerten zu können, aber
bloss für die Tastaturabfrage lohnt das nicht.
Ich habe bei allen Anwendungen einen festen Tick. Wie soll man eine
Controlleranwendung ohne Tick schreiben ? Denn delay() gibt es nicht. Es
darf gar nirgends gewartet werden sonst wird man nie eine Echtzeit
Performance erreichen.
Peter D. schrieb: > Man sollte immer Routinen bevorzugen, die sowenig wie möglich > Seiteneffekte haben oder Vorbedingungen stellen. Guter Vorschlag! Hier wird nicht einmal ein Timer gebraucht: Beitrag "Re: EIN-AUS mit Taster per Interrupt, ATtiny25 o.ä." ;-)
Michael schrieb: > Hallo, > > ich grad ein kleines Problem damit die Tasterentprellung per > Flankenerkennung aus folgendem Artikel richtig zu verstehen. > https://www.mikrocontroller.net/articles/Entprellung#Flankenerkennung Genau ab dieser Stelle wird eine Funktion "taster" beschrieben, die aus einer anderen Funktion aufgerufen.. > > Warum ist bei dieser Methode kein delay notwendig? ..das "delay" ist in der aufrufenden Funktion erforderlich.. > > Wenn der Controller schnell genug läuft um einen "ganzen Prellvorgang" > abtasten zu können werden hier doch nach wie vor mehrere Tastendrücke > erkannt oder? ..yepp. Alternativ kann man auch das Tastenbit in eine uint8_t Variable von recht nach links schieben:
1 | uint8_t tastenstate = 0; |
2 | :
|
3 | if(systemzeit >= Tastenabfragezeitpunkt) { |
4 | tastenstate <<= 1; |
5 | tastenstate |= TASTENPINBIT; // ist 1, wenn Taster betätigt |
6 | :
|
7 | switch (tastenstate & 0x03) { |
8 | case 0: Zustand = NICHT_GEDRUECKT; break; |
9 | case 1: Zustand = STEIGENDE_FLANKE; break; // wird gerade betätigt |
10 | case 2: Zustand = FALLENDE_FLANKE; break; // wird gerade losgelassen |
11 | case 3: Zustand = GEDRUECKT; break; |
12 | }
|
13 | }
|
14 | :
|
15 | if (tastenstate > 0xfe) TASTE_KLEMMT; // ;-) |
Es kommt auch immer darauf an, wie die Taste betätigt wird; - ein von Hand betätigter Taster -> reicht den alle 100ms abzufragen, - Tastimpuls von einem (mechanischen) Impulsgeber / (Reed)Relais -> mind. 10ms - 20ms Abfragezyklus. - Optokoppler ? - Schaffste 'ne ms Schleifendurchlauf? Einen mechanischen Taster auf einen INT Eingang zu packen, und in der ISR einen Zähler hochzählen ist nur etwas für delay()_Junkies..
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.