moin ! ich habe 8 taster an dem port d angeschlossen diese taster möchte ich auf zwei verschiedene methoden auslesen: 1. normal ob er gedrücktist (entprellen) 2. ob er für mind. 3 sekunden gedrückt ist. ich hab schon einiges gelesen und leute genervt und trotzdem weiß ich noch nicht wie ich es anstellen soll - habe mir jetzt folgendes überlegt: ich mache einen interrupt der alle 50ms ausgeführt wird (der µC läuft bei 1Mhz) am anfang dieses int's ist eine große schleife die abfragt: ist t1 or t2 or t3 or t4 or t5 or t6 or t7 or t8 gedrückt ?? nein: interrupt beenden und zu main zurückkehren ja: dann kommt eine switch anweisung die herausfindet WELCHER der taster gedrückt ist Case t1 Case t2 Case t3 Case t4 ... ... In jeder sieser case blöcke steht jetzt: eine kleine schleife zum entprellen die 65025 zyklen nachschaut ob der jeweilige taster gedrückt ist bzw bleibt. DANACH könnte man den druck ja schon als kurzen tastendruck intapretieren aber es soll ja weiterhin überürüft werden ob es nicht im einen langer tastendruck (3 sekunden) handelt. also soll der zähler jetzt weiter hochzählen bis 3millionen (3sekunden bei 1MHz) wird der taster beim inkrementieren zwischen 65.025 und 3.000.000 unterbrochen (durch loslassen) wird der interrupt unterbrochen und zur funktion t1_kurz gewechselt hat der zähler 3.000.000 erreicht wird der interrupt auch unterbrochen und zur funktion t1_lang gewechselt 1. kann man das so machen, mus sich dabei was besonderes beachten oder gibt es da intelligentere lösungen ?! 2. als was muss ich eine variable deklarieren um die bis 3.000.000 hochzählen zukönnen ? viele grüße lordchen
1.) Man kann das vielleicht so machen... s. u. 2.) uint32_t, die geht bis 4 Milliarden Erstens sollte man Interruptfunktionen so knapp wie möglich halten. Also keinesfalls ellenlange Warteschleifen dort hineinbringen. Zweitens, wenn Du sowieso einen Zeitgeber benutzt, dann laß ihn doch einfach nur den Status der Tasten abfragen, wie er gerade ist, und schreibe das in einer Art FIFO hintereinander auf (für alle Tasten). In der Auswertung (die ggf. noch im Interrupt erfolgen kann oder auch außerhalb) siehst Du nach, ob eine bestimmte Taste mittlerweile 3 mal denselben Zustand hatte und ob der zuletzt germerkte ausgewertete Zustand vom derzeitigen differiert. Wenn ja, dann hast Du eine Flanke erkannt (Taste gedrückt oder losgelassen). Abfrageintervall würde ich auf 10 ms legen, mit 3 Abfragen hättest Du dann die Entprellung. Wenn Du Dir außerdem noch die ,,absolute Zeit'' mitmeißelst, an der Du die letzte Flanke erkannt hast, dann kannst Du später auch noch feststellten, ob die Taste ,,lange'' gedrückt worden ist (durch Vergleich der aktuellen Zeit mit der gemerkten). Mit ,,absoluter Zeit'' meine ich dabei die einfach mitgezählten timer ticks, sinnvollerweise wohl auch in einem uint32_t (pro Taste) gemerkt. Bei 10 ms hast Du dann einen Überlauf von 497 Tagen, d. h. nach 497 Tagen Laufzeit wirst Du die lange gedrückte Taste nicht mehr erkennen, wenn sie just vor dem Überlauf gedrückt worden ist. Das war mal irgendwann die Maximaldauer, die man ein Linux am Stück laufen lassen konnte, weil danach die ,,jiffies'' übergelaufen sind, die dazumals von vielen Treibern als Kriterium benutzt worden sind. Gleicher Bug war im Win95, nur daß dort der Zeitgeber mit 1 ms tickt, so daß nach 49,7 Tagen der Mauszeiger nicht mehr reagierte... Es hat bezeichnenderweise mehrere Jahre gedauert, bis dieser Bug bekannt geworden ist, d. h. der Großteil der Win95 hat diese uptime ohnehin nie erreicht. ;-)
hmm also du meinst alle 10ms wird der int. ausgelöst in der int-funktion wird bei jedem aufruf nachgesehen welche taster gedrückt sind also für jeden taste eine variable und jedesmal wenn der int einen gedrückten taster feststellt wird die dazugehörige variable z.B: taster1 um eins incrementiert beim 3. int stellt er fest oh taster1 = 3; dann führt er die funktion_taster1_kurz aus , setzt alle tasterX-Variablen af 0 und beendet den interrupt wird taster1 durchgehend gedrückt hat der interrupt die variable taster1 nach 4 sekunden auf 400 hochgezählt (400 * 10ms = 4Sekunden) Wenn also taster1=400 wird funktion_taster1_lang ausgeführt Mit einer 32bit variablen kann man bis 4.294.967.295 zählen aber ich brauch doch nur bis 400 oder nicht ? .. verstehe das nicht !??? aber das gesamtergebnis der taster abfrage soll aber nur ein garkeintaster gedrückt / tasster C lang gedrückt oder taster x kurz gedrückt sein denn es soll davon ausgegangen werden, das nur ein taster gleichzeitig grdrückt wird... wie muss man das anstelen ?.
Guckst Du mal Codesammlung: http://www.mikrocontroller.net/forum/read-4-16594.html Da ist ein "C_tast.c51" von mir mit Repeat-Funktion, wenn eine Taste länger gedrückt ist. Peter
COOL danke das klappt auch ... die hex zumindest wennich die C datei hex-en will bekomm ich den fehler: seit der neien AVR-GCC version muss man ja /avr angeben ... das hab ich schon gemacht aber danngibt es noch fehler, bei denen ich leider nicht weiter komme : D:\Mikrocontroller\entprell>compile.bat D:\Mikrocontroller\entprell>C:\WinAVR\bin\avr-gcc-mmcu=at90s8515 -Os -o kofi.out kofi.c kofi.c:39: error: syntax error before "char" kofi.c:40: error: syntax error before "char" kofi.c:107: error: `TIMER0_OVF0_vect' undeclared here (not ina function) kofi.c:107: error: parse error before "timer0_int" kofi.c: In function `main': kofi.c:118: warning: return type of `main' is not `int' kann mir da einer helfen sonst kann ich mit dem programm leider nichts anfangen ;-(( danke schonmal im vorraus
hab die teil-angepasste file vergessen ..bin mir auh nichtganz sicher ob das wasich da verändert hab richtig ist auf jedenfall gibts schonmal weniger fehler *g*g*
OK also mit peters debouncerkannich nix anfangentrotzdem danke ! mein programm machtzwar fortschritte funzt aber immernoch nicht ! ich weiß nicht wie ich das jezt machen soll SIGNAL(SIG_OVERFLOW1) { if(~PIND & 1) { t1++; if (t1 == 3) { t1 = 0; lcd_clrscr(); lcd_puts(" Taster 1 "); delay(); delay(); } if (t1 == 10) { t1 = 0; lcd_clrscr(); lcd_puts("=Taster 1="); delay(); delay(); } } else { } TCNT1 = 0xfd24; } Also das die sequwnz wo t1 10 wird gar nicht ausgeführt werdenKANN weil sie bei 3 schon auf null gesetzet wird ist ja klar aber wie soll ich es sonst machen ?! ich muss ja auch den kuren tastendruck feststellen können außerdem wie kann man aus einem int. zurückkehren und gleichzeitig eine bestimmt funktion ausführen ? die funktion soll ja nicht mehr im int. ausgeführt werden
Erledige nicht zuviel in der Interruptroutine, setze hier nur
Merker/Flags, die du dann in main() auswertest.
> ich muss ja auch den kuren tastendruck feststellen können
Was ist der Unterschied zwischen langem und kurzem Tastendruck? Richtig,
beim kurzen Tastendruck wird die Taste früher losgelassen. Du mußt also
das Loslassen auch noch auswerten, um zwischen kurz und lang zu
unterscheiden.
Schmittchen.
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.