Hallo Lt. Tutorial ist es ja günstig, dieses RS-FlipFlop zu verwenden. Kann man diese Schaltung auch benutzen, wenn man nur nen simplen Taster hat? bzw. diese ein wenig abwandeln, damit es klappt? Danke
Johannes Hofmann schrieb: > Hallo > > Lt. Tutorial ist es ja günstig, dieses RS-FlipFlop zu verwenden. Eigentlich macht man Tastenentprellung am besten in Software. Das ist universeller, kostet nichts und funktioniert absolut zuverlässig.
Ok, wenn ich mir die Komfortroutine für C anschaue und 2 Taster habe, die nicht gedrückt und dann gehalten werden, welche Teile des Codes benötige ich denn dann? Das Problem ist nämlich, dass ich nen MP3-Player habe, dessen Spielroutine ich nur für 800us unterbrechen kann, weil der Datenstrom dann nämlich abreißt. Deswegen wollte ich das eigentlich mit Hardware-Entprellung machen. Wie würdest du das machen?
Hi, die Entprellroutine vom Dannegger besteht doch nur aus ein paar binären Operationen. Und wenn du nen Quarz mit z.b. 16 MHz hast, dann sind 800 µs doch ne Ewigkeit und reichen locker aus, um ein paar Tasten zu entprellen. Ich hab auch schon nen MP3 Player mit nem VS1053 IC gebaut, an dem ich 12 Taster hatte. Die konnte ich während des MP3-Abspielens ohne Probleme entprellen. Gruß C.H.
Du brauchst die Timer Overflow Routine und natürlich die Auswertefunktionen > Das Problem ist nämlich, dass ich nen MP3-Player habe, dessen > Spielroutine ich nur für 800us unterbrechen kann 800us sind fast 1ms. Also massig Zeit. Solange braucht die Overflow Funktion ja gar nicht. Und ausserdem wird die ja nur alle heilige Zeiten aufgerufen (Du kannst auch die Zeitberechnung für das Nachladen des Timers aus der ISR rausnehmen. Wenn die ISR so alle 5 bis 20ms aufgerufen wird, dann reicht das. Das muss nicht sonderlich genau sein, mit dem Prescaler kommt man normalerweise ausreichend gut in einen vernünftigen Bereich hinein)
Gast
#1528584
Sorry aber etwas kapierre ich hier nicht. Wenn ich das richtig im Kopf habe dann ist die Prellzeit von tastern/Schaltern durchaus im Millisekundenbereich, gerne auch mal bei nicht so hochwertigen mehr als 20 mS. Wie bitte kann ich die innerhalb von weniger als 0,8yS dann softwareseitig entprellen???? Dazu müsste ich doch die Tastenausleseroutine in eine zyklisch (Timer) über Timer aufgerufene Routine machen, die sich die Zustände auch noch merkt.
Gast
#1528603
Wie schon von Udo geschrieben, ist Entprellen hier der falsche Weg. Solange hast du nicht Zeit. Am einfachsten ist es mit der ersten Flanke einen Interrupt auszulösen und dann alle folgenden für ~20ms zu verwerfen.
Udo. R. S. schrieb: > Dazu müsste ich doch die Tastenausleseroutine in eine zyklisch (Timer) > über Timer aufgerufene Routine machen, die sich die Zustände auch noch > merkt. Und genau das macht eben diese Entprellroutine. Sie tastet 4-mal ab im Abstand von 10ms Timerinterrupt. Peter
Esko schrieb: > Wie schon von Udo geschrieben, ist Entprellen hier der falsche Weg. Udo hat dasnur deswegen geschrieben, weil er noch nicht durchschaut hat, wie das funktioniert. > Solange hast du nicht Zeit. Braucht er auch nicht. > Am einfachsten ist es mit der ersten Flanke einen Interrupt auszulösen > und dann alle folgenden für ~20ms zu verwerfen. Äh nein. Das ist nicht einfacher. Wie machst du das denn 'die folgenden für 20ms verwerfen'? Am enfachsten ist es die Entprellroutine zu benutzen. Die verbraucht minimal Rechenzeit, entprellt zuverlässig, merkt sich einen gedrückte Taste, erkennt kurze und lange Tastendrücke und kann auf wunsch auch einen Autorepeat auf die Taste legen. Und das beste am ganzen: sie verbraucht praktisch keine Rechenzeit.
Udo. R. S. schrieb: > Wie bitte kann ich die innerhalb von weniger als 0,8yS dann > softwareseitig entprellen???? Musst du auch nicht. Die Entprellroutine erkennt einen Tastendruck dann als gültig an, wenn 4 mal hintereinander, im Abstand von x Millisekunden die Taste als gedrückt erkannt wurde. Sobald die Taste das erste mal prellt, beginnt die 4-er Zähleung erneut zu laufen. Der Code macht im Grunde nichts anderes als: Schau alle x Millisekunden die Tasten durch, ob sich etwas verändert hat. Das geht schnell. Im Grunde ist das wie beim Autofahren: Du konzentrierst dich auf die Strasse und alle paar Sekunden wirfst du einen Blick in den Rückspiegel. Das geht schnell genug, damit dir nichts entgeht. Genauso hier: Alle x Millisekunden sieht die Overflow-ISR nach, ob eine Taste gedrückt wurde. Durch die Konstruktion der ISR gilt aber nicht jeder 1->0 Übergang als Tasterndruck, sondern nur dann, wenn danach bei 4-maligem erneuten Hinschauen die 0 immer noch anliegt.
Hallo
Wie mach ich das aber, wenn ich bei meinem Player Pause machen will und
dies mittels dieser Schleife tun will:
while(PAUSE){} ?
Da komm ich ja dann nicht mehr raus.
Denn ich wollte über den Interrupt diesen PAUSE-Wert togglen.
Aber das klappt ja dann nicht mehr in Software.
Deswegen würd ich nochmal gern wissen, ob ich mit nem RS-Flip-Flop und
nem Taster arbeiten kann, oder ob das Ding nur bei einem Wechselschalter
benutzbar ist.
Weiterhin noch ne Frage: In dem Tutorial wird das Timerinterrupt-Intervall so gesetzt. Zu ersteinmal die Frage, was die beiden uint8 und int16 da zu bedeuten haben. Und von denen wird dann der Wert 1,47 (bei 1e+06 als F_CPU) abgezogen. Daraus werd ich nicht ganz schlau. TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); Danke euch
Johannes Hofmann schrieb: > Hallo > > Wie mach ich das aber, wenn ich bei meinem Player Pause machen will und > dies mittels dieser Schleife tun will: > while(PAUSE){} ? > Da komm ich ja dann nicht mehr raus. Wer oder was ist PAUSE Im übrigen: Du hast es immer noch nicht verstanden. Die Overflow ISR läuft eigenständig 'im Hintergrund' mit und überwacht die Tasten. Wann immer es dir passt rufst du get_key_short auf und die liefert der den Wert ob eine Taste gedrückt wurde. Deine Schleife ist dann while( ! get_key_short( 1 << PAUSE_KEY ) ) ; wobei PAUSE_KEY die Pinnummer des Pause Tasters ist Die musst du natürlich noch richtig konfigurieren. Welche Tasten hast du und an welchem Port und an welchem Pin sind sie angeschlossen. zb.:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
Sobald der Timer läuft, brauchst du dich um nichts mehr kümmern. Du rufst get_key_short auf und die Funktion teilt dir mit, ob die Taste seit dem letzten Aufruf gedrückt wurde oder nicht. > Denn ich wollte über den Interrupt diesen PAUSE-Wert togglen. > Aber das klappt ja dann nicht mehr in Software. Doch, das klappt wunderbar. > Deswegen würd ich nochmal gern wissen, ob ich mit nem RS-Flip-Flop und > nem Taster arbeiten kann, oder ob das Ding nur bei einem Wechselschalter > benutzbar ist. Du machst dir zu viele Sorgen. Dein main() wird dann in etwa so aussehen
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
Die Hauptschleife dreht ständig ihre Runden Abfragen, ob irgendeine Taste gedrückt wurde und behandeln wenn ja Dem MP3 Chip wieder ein paar Daten vorwerfen, so dass er spielen kann, während die nächste Runde Tastenabfragen durchläuft. Und nein, das Tastenabfragen kostet nicht viel. Das sind ein paar µs die dafür draufgehen. Die spürst du kaum bis gar nicht.
Johannes Hofmann schrieb: > Weiterhin noch ne Frage: > In dem Tutorial wird das Timerinterrupt-Intervall so gesetzt. > Zu ersteinmal die Frage, was die beiden uint8 und int16 da zu bedeuten > haben. > Und von denen wird dann der Wert 1,47 (bei 1e+06 als F_CPU) abgezogen. > Daraus werd ich nicht ganz schlau. > > TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); Das ist die Berechnung des Timerwertes, so dass der Timer zum Hochzählen von diesem Wert bis auf 255 ziemlich genau 10ms benötigt. Wie gesagt: das kannst du meistens auch weglassen. Ob das jetzt 10ms sind oder 20, spielt keine allzugroße Rolle.
Gast
#1529525
@ Karl Heinz Stimmt, ich habe mir die Routine nicht im Detail angesehen (zumal ich in AVR assembler mangels Übung etwas eingerostet bin :-)) und nebenbei arbeiten muss. Wie ich aber aus den Beiträgen herauslese macht die Routine genau was ich gesagt habe, nämlich zyklisch über einen Timerinterrupt aufgerufen werden und sich die Zustände der Taster/Schalter merken (muss er ja sowiso bei autorepeat). Die eigentliche Portabfrage und der Vergleich des Istzustandes mit dem vorherigen Zustand braucht dann natürlich nur ein paar Taktzyklen. Wenn ich tatsächlich mal wieder den Platz und die Zeit zum Basteln habe dann schaue ich mir die Routine genau an und bedanke mich schon mal im Voraus dafür die benutzen zu dürfen.
Hallo Karl-Heinz, Die Sache mit dem Timer-Interrupt hab ich verstanden, keine Angst ;) PAUSE wird zwischen 0 und 1 hin und hergesetzt. Das Problem ist halt, dass ich meinen Player gern mit 2 Tasten steuern möchte. Mit der einen Taste drücke ich mehrmals, je nachdem, ob ich Pause(1xdrücken), oder leiser(2x) oder lauter(3x) machen möchte und mit der anderen Taste bestätige ich diese Folge dann und die gezählten "Drücker" werden dann an eine Switch-Anweisung weitergegeben und ausgewertet. Und diese beiden Taster hängen dann natürlich an den Interrupt-Eingängen. Deswegen kann ich für die Pause-Anweisung auch nicht deine Variante nehmen. Und deswegen auch nochmal die Frage bzgl. des RS-FFs.
Johannes Hofmann schrieb: > Das Problem ist halt, dass ich meinen Player gern mit 2 Tasten steuern > möchte. Mit der einen Taste drücke ich mehrmals, je nachdem, ob ich > Pause(1xdrücken), oder leiser(2x) oder lauter(3x) machen möchte und mit > der anderen Taste bestätige ich diese Folge dann und die gezählten > "Drücker" werden dann an eine Switch-Anweisung weitergegeben und > ausgewertet. Ist damit überhaupt kein Problem:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Peter
P.S.: Muß natürlich get_key_press() heißen. Peter
Gast
#1529869
> Lt. Tutorial ist es ja günstig, dieses RS-FlipFlop zu verwenden. > Kann man diese Schaltung auch benutzen, wenn man nur nen simplen Taster > hat? bzw. diese ein wenig abwandeln, damit es klappt? Nein. Deswegen gibt es unterschiedliche Schaltungen, je anch vorhandenm Taster http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.29.1 > Und diese beiden Taster hängen dann natürlich an den > Interrupt-Eingängen. Das ist grober Schwachsinn, denn die Pellimpulse von den Tasten können so schnell kommen, schneller als dein uC den Interrupts folgen kann. So eine Lösung wird auch nirgends vorgeschlagen. Mach einen Interrupt der (länger als die Prellzeit der Taster, also z.B.) alle 20msec nachguckt, wie die Tastereingänge stehen. on Timer_interrupt: copy Port -> Tastenzustandvariable aktueller_Zustand und lass dein Hauptprogramm (in einer Schleife) entscheiden, was es tun soll, wenn sich der Tastenzustand geändert hat (nun gedrückt, nun nicht mehr gedrückt) if alter_Zustand != aktuelle_Zustand tu was alter_Zustand:= aktueller_Zustand Warum habne alle Leute so massive Probleme, zu verstehen, was prellen ist ?
MaWin schrieb: > Mach einen Interrupt der (länger als die Prellzeit der Taster, also > z.B.) alle 20msec nachguckt, wie die Tastereingänge stehen. > > on Timer_interrupt: > copy Port -> Tastenzustandvariable aktueller_Zustand > > und lass dein Hauptprogramm (in einer Schleife) entscheiden, was es tun > soll, wenn sich der Tastenzustand geändert hat (nun gedrückt, nun nicht > mehr gedrückt) > > if alter_Zustand != aktuelle_Zustand > tu was > alter_Zustand:= aktueller_Zustand mit anderen Worten: nimm die PeDa Tastenentprellung :-) und freu dich darüber, dass es funktioniert und geniesse den Zusatzkomfort
MaWin schrieb: >> Und diese beiden Taster hängen dann natürlich an den >> Interrupt-Eingängen. > > Das ist grober Schwachsinn, denn die Pellimpulse von den Tasten können > so schnell kommen, schneller als dein uC den Interrupts folgen kann. > So eine Lösung wird auch nirgends vorgeschlagen. Ein im Mikrosekunden Bereich prellender Taster? Hui ;)
Gast
#1529901
> Ein im Mikrosekunden Bereich prellender Taster? Hui ;)
Natürlich, im Moment der Kontaktgabe bzw. des Kontaktöffnens bilden sich
kleine Funken aus, und die sind (das Wort Funkstörungen kommen nicht
ohne Grund daher) sehr schnell am Abreissen und neubilden, auch in
weniger als Mikrosekunden.
Dass neben der Funkenströrung auch noch das mechanische Prellen
hinzukommt, wo der Kontakt, wenn er schliesst, eventuell wieder
"weghüpft" bevor er erneut schliesst, macht die Sache nicht einfacher.
Bei einem normalen Eingabetaster? Wo Ströme um die 1mA fließen? Wo hast du denn die Horrorgeschichte her!
Ich bin ja sehr dankbar für euer Bemühen, aber wenn ich nun in einer
Schleife mit while(PAUSE){} bin, dann komm ich doch gar nicht anders
raus, als wenn PAUSE durch einen Interruptgenerierten Vorgang wieder auf
0 gesetzt wird.
Und natürlich werden die Taster auch nicht direkt an die
Interrupteingänge angeschlossen. Deswegen such ich ja nach so einer
Vorbeschaltung.
Ich hab schon bei Conrad nach so nem Inverter mit
Schmitt-Trigger-Eingängen gesucht, aber konnte keinen finden. Die haben
ja auch eine blöde Suche.
Könnt ihr mir da weiterhelfen?
Sorry Mawin, aber dein Link zu diesem Kompendium lässt meinen FF
abstürzen :(
Johannes Hofmann schrieb: > Ich bin ja sehr dankbar für euer Bemühen, aber wenn ich nun in einer > Schleife mit while(PAUSE){} bin, dann komm ich doch gar nicht anders > raus, als wenn PAUSE durch einen Interruptgenerierten Vorgang wieder auf > 0 gesetzt wird. Mit anderen Worten. Du hast das alles schon fertig aufgebaut, hast festgestellt dass es nicht so richtig funktioniert und suchst nun nach einer Lösung wie du das verkorkste Design noch möglichst billig retten kannst. nenn doch die Dinge beim Namen
Bei einer Liedpause den ganzen Mikrocontroller aufhören lassen zu rechnen ist nicht gerade klug. Die Uhrzeit auf dem Display wird nicht mehr geupdatet. Er ist über Ethernet nicht mehr zu erreichen. Der USB Datenlink bricht ab.. ;)
Quatsch! Da ist noch nix fertig aufgebaut und wie kommst du auf "Billig retten"??? Ich hätte es nur gern so gemacht, wie ich es beschrieb. Und dafür benötige ich die Hardware-Entprellung. Und somit steht wieder die Frage vom Thread-Anfang. Doch leider killt ja der Link von MaWin meinen FF.
Johannes Hofmann schrieb: > Quatsch! > Da ist noch nix fertig aufgebaut und wie kommst du auf "Billig > retten"??? Weil ich lang genug hier im Forum mitlese :-) Wenn sich jemand standhaft weigert eine Softwarelösung anstelle einer aufwändigeren Hardwarelösung einzusetzen, dann bedeutet das im Regelfall nur eines :-) > Ich hätte es nur gern so gemacht, wie ich es beschrieb. Und dafür > benötige ich die Hardware-Entprellung. > Und somit steht wieder die Frage vom Thread-Anfang. Im Artikel "Entprellung" ist ja dann auch noch die Hardware-Lösung für Einfachtaster angegeben. Ausser das die einfacher ist als das FF, was genau gefällt dir daran nicht? http://www.mikrocontroller.net/articles/Entprellung#Einfacher_Taster
Weil ich mir bei Pollin grad paar NAND-ICs gekauft habe. Leider hab ich das mit Wechselschalter und Taster übersehen. Deswegen die Frage, ob man auch nen Taster mit ner Flip-Flop-Schaltung entprellen kann. In jedem anderen Fall hätte ich natürlich sofort die Software-Lösung benutzt. Gar keine Frage. Und meine Standhaftigkeit habe ich ja hoffentlich ausreichend erläutert. Ne ganz harte Variante wäre ja auch die Nutzung eines 2. uC für die Entprellung. Oder wie war das mit den Kanonen und den Spatzen... Könnt ihr anderen den Link vom MaWin öffnen?
Johannes Hofmann schrieb: > Ich bin ja sehr dankbar für euer Bemühen, aber wenn ich nun in einer > Schleife mit while(PAUSE){} bin, dann komm ich doch gar nicht anders > raus, als wenn PAUSE durch einen Interruptgenerierten Vorgang wieder auf > 0 gesetzt wird. Und wo ist dabei das Problem?
1 | |
2 | |
3 | |
4 | |
5 | |
So einfach ist das mit den Entprellfunktionen. Peter
Aber nichtsdestotrotz probiere ich natürlich grade mit der Routine, auch zwecks Lerneffekt. Doch leider will es nicht wie ich wohl will. Im Moment sieht der Code bei mir so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
Mein uC läuft mit 8 MHz. Muss ich da beim Timerinterrupt noch was anpassen?
get_key_short und get_key_long darf man nur dann benutzen, wenn man die Drückdauer auswerten will und dann auch immer beide! Peter
Und entweder den Optimierungsschalter: -fno-inline-small-functions oder key_press als volatile. Peter
Gast
#1530442
> Wo hast du denn die Horrorgeschichte her! Simon, Ball flachhalten, auch wenn du den Blitz nicht geissend hell aus dem Gehäuse rauskommen siehst, heisst das nicht, dass nicht welche entstehen. Sie entstehen bei jedem Stromfluss und jeder Spannung. > Könnt ihr anderen den Link vom MaWin öffnen? 500kB Datei, dauert länger.
taster entprellen mit einem FF geht nicht allgemein steh ich nich auf hardwareloesungen wenn es auch per software geht, da die schaltung dann nur unnoetig groesser wird. Taster hardwaremaesig entprellen noch dazu nicht zuverlaessiger als eine brauchbare software loesung, ausser das man die hardware hirnlos nachbauen kann ;-) Ach das mit der "Horrorgeschichte" stimmt natuerlich, auch bei kleinen Spannungen entstehen Funken wenn sich kontakte naehern. Das manche taster mehr und manche weniger prellen haengt daher mit der mechanik und der beschaffenheit der kontaktflaechen ab. Es gibt natuerlich auch entprellte schalter aber die sind dann natuerlich nicht rein mechisch
Hello again. So mein Code sieht jetzt so aus. Klar hatte ich key_state und key_press als volatile, ich hatte bloß vergessen es in meinem letzten Post hinzuschreiben.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
Doch seltsamerweise wird beim Starten des uC einmal ohne mein Zutun KEY1 "gedrückt", sodass natülrich 'Counter' inkrementiert wird. Habt ihr da ne Idee, was da für "Geister" am Werk sind? Habe auch den Prescaler auf 8 gesetzt um wirklich eine zuverlässige Abtastung zu erreichen.Doch das brachte auch keine Besserung. Auch wenn die Taster gar nicht an den Ports hängen wird ein "Drücken" detektiert.
Taster gegen VCC und externe Pulldowns, statt gegen GND und interne Pullups? Peter
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.