Hallo an Alle, ich habe fünf Taster(aktiv-Low) deren Zustand ich gern einlesen würde.Ist ein Taster gedrückt, soll eine Aktion ausgeführt werden.Aber nicht solange der Taster gedrückt ist, sondern pro Tastendruck eine Aktion(Entprellen). Als Sicherheit will ich verhindern, dass zwei Tasten gleichzeitig gedrückt werden können. Wie kann ich das ganze umsetzen, wenn ich nun 3 Taster an PORTD 5-7 habe und zwei an PORT 6-7? Vielen Dank,... Tschüß Thomas
Mach das abfragen einfach mit ner fallenden Flanke. Bsp: if (bit_is_set(PIND, PIND5) { loop_until_bit_is_clear(PIND, 5); ...
ich habe das ganze jetzt erstmal so gelöst: if (bit is clear(PIND, PIND5) { ... if (bit is clear(PIND, PIND6) { ... if (bit is clear(PIND, PIND7) { ... if (bit is clear(PIND, PINE6) { ... if (bit is clear(PIND, PINE7) { ... in der Schleife habe ich jeweils einen Counter hochgezählt zum Entprellen. Aber irgendwie ist das ganz schön viel Code für so ein bissl Entprellen. Geht das nicht irgendwie einfacher? Danke an Alle, Thomas
Man könnte die Bits zusammen fassen und dann meine Entprellroutine (Codesammlung) nehmen: i = (PIND >> 2) | (PINE & 0xC0); // Bit 3,4,5,6,7 i ^= ~key_state; // key changed ? usw. Peter
Hi Peter, Deine Routine habe ich mir schon angeschaut. Dabei konnte ich nicht genau feststellen, ob das ganze über den Timer gesteuert wird oder alles ohne Timer funktioniert. Kannst Du mir diesbezüglich vielleicht eine kleine Erklärung geben? Vielen Dank, Ahoi Thomas
Der Timer macht den Entprelltakt, kann aber noch für andere Sachen benutzt werden. Das ist besser als die Zeit nutzlos zu verwarten. Lies Dir mal den ganzen Thread in Ruhe durch, das dürfte alles erklären. Peter
Hi Peter, habe mir jetzt nochmal Deine Entprell-Routine angeschaut und es versucht in meinem Programm zu realisieren. Leider entprellt es bei mir nicht :-(! Was könnte ich also noch falsch gemacht haben? Habe den Counter0 initialisiert und mit blinkender LED überprüft...das geht also. Dann habe ich Deinen Code reingehackt...dabei habe ich i= (PIND 0xE0) |(PINE 0xC0); so gesetzt. Soll also für PIND5-7 und PINE6,7 sein. Danach so weiter wie Du geschrieben hast. In meiner for();; Schleife habe ich die Interrupts aktiviert(sei;) und ne Abfrage nach meiner Taste gemacht: if(bit_is_clear(PIND, PIND5)) { if(key_press)....also nur wenn Taste entprellt ist {... }} Leider wird so nichts entprellt. Kannste mir vielleicht noch einen Hinweis geben, was ich da noch nicht richtig verstanden habe? Danke Thomas
Hey Peter,...wo bist Du? Hab gerade noch ein wenig probiert und bei mir ist Key_press immer 1, wenn keine Taste gedrückt ist! Was mache ich falsch? Danke Thomas
if(bit_is_clear(PIND, PIND5)) { if(key_press)....also nur wenn Taste entprellt ist {... }} Ne, doppelt gemoppelt geht nicht. Die Routine macht alles für Dich, d.h. vergiß die Pins, lies nur key_press aus (und setz es zurück). Peter
Hallo, bit_is_clear (, ); Die Funktion bit_is_clear prüft, ob ein Bit gelöscht ist. Wenn das Bit gelöscht ist, also auf 0 ist, wird ein Wert ungleich 0 zurückgegeben. Diese Erklärung ist in der AVR-GCC-Einführung in der Wiki zu finden. Du kannst auch die ganz normalen ANSI-C-Befehle verwenden (Variable & (1<<Bitnummer)). Gruß Elektrikser
Halli hallo, also ich habe das jetzt nochmal ausprobiert und leider habe ich das Problem immer noch nicht lösen können. Also ich habe zur Zeit nur noch eine Abfrage und zwar: if(key_press) { ... key_press=0; } Das hat zur Folge das sofort beim Einschalten OHNE Tastendruck...die Aktion ausgeführt wird! Und wenn ich die Taste drücke, tut sich leider gar nichts! Wo kann denn da jetzt noch der Fehler liegen? Ich bin mir nicht sicher wie die Klammern zwischen den ganzen Bitoperationen gesetzt werden müssen. Zum Beispiel in der Zeile: ct1=ct0^ct1&i Was hat denn da den Vorrang? Ist die Vorinitialisierung der Variablen von Bedeutung? Noch eine Frage, wenn ich nur noch Key_press Abfrage, dann ist es mir ja nicht mehr möglich zu unterscheiden, welche Taste jetzt gedrückt worden ist oder täusche ich mich da? Wenn nich, wie kann ich denn die Tasten unterscheiden? Wäre nett, wenn Ihr mir nochmal helfen könnt...
Hier ist ein Beispiel, welches Du leicht auf dem STK500 ausprobieren kannst: http://www.mikrocontroller.net/forum/read-4-49709.html#new Daraus geht auch hervor, wie Du die Tasten einzeln abfragst: Danach kannst Du dann die Erweiterung auf verschiedene Ports probieren. Anbei die Rangfolge in C. Peter
Hi Peter, heute Morgen habe ich mir in aller Ruhe nochmal das Schedule-Programm angeschaut. Obwohl ich durch die vielen Funktionen nicht 100 prozentig durchgesehen habe, konnte ich bei meinem Programm einen kleinen Erfolg verzeichnen. Es entprellt jetzt und es erkennt die richtigen Tasten. Nur konnte ich die Tasten noch nicht kombinieren. Dazu habe ich mal noch ein paar leichte Fragen. Ich check das einfach mit dem Schieboperator nicht. Ich versteh zwar Links-oder Rechtsschieben, aber nicht in Verbindung mit folgenden Kommandos: i=(PIND>>2) Was wird denn dabei geschoben??? Was steht denn jetzt in i??? Deswegen versteh ich auch folgende Zeile Deines Schedule Codes nicht: if(get_key_press(1<<PB6))...z.Bsp. erstmal was soll (1<<PB6) bedeuten? Und zweitens PB6 ist ja ein Bit des Datenausgangsregister und ich will doch ne Taste einlesen??? Was hat das damit auf sich? Falls Du mir das mal erklären kannst, kann ich bestimmt auch verstehen, wie ich endlich die Tasten PIND5-7 und PIN6-7 auf i legen kann: i=(PIND & 0xE0)|(PINE & 0xC0)...geht leider nicht. werden da Bit 6 und 7 überschrieben? Würde mich über eine Antwort sehr freuen. Vielen Dank schon mal im Vorraus, Ciao Thomas
Hi! Schieben (shiften) kann man mit multiplizieren (linksschieben) oder mit dividieren (rechtsschieben) ersetzen! i=(PIND>>2) Hier wird der Inhalt von PIND um zwei Stellen nach rechts verschoben, d. h., der Inhalt von PIND wird durch 4 (2**2) geteilt. Danach wird das Ergebnis i zugewiesen. if(get_key_press(1<<PB6)) Hier wird get_key_press(..) das Bit PB6 als Parameter übergeben. (1 << PB6) bedeutet, daß 1 um PB6 stellen nach links geschoben wird. In diesem Falle um 6 Stellen. Das wiederum entspricht einer Multiplikation mit 64 (2**6). Wenn Du verschiedene Pins von verschiedenen Ports in einer Variablen speichern willst, dann musst Du darauf achten, daß die bits Sortiert werden müssen und sich nicht gegenseitig überschreiben.
Hey OldBug, vielen Dank für die Erklärung...ich hoffe das habe ich soweit verstanden. Das mit den verschieden Pins haut bei meinem Programm leider nicht hin. Wieso weiß ich auch nicht? Ich habe mir das jetzt so gedacht: i=(PIND>>5)|(PINE & 0xC0); Dann müßten die Bits 0-5 von PIND nach rechts weggeschoben werden und der Rest mit PINE verodert werden. So das dann in i =PINE7,PINE6,0,0,0,PIND7,PIND6,PIND5...stehen müßte oder? CU Thomas
Hey OldBug und Peter, ich habs endlich hinbekommen!!!! Mich hat der Parameter bei get_key_press verwirrt. Ich dachte es muß PBx sein...sozusagen was in dem Bit steht. Aber nach der Erklärung von OldBug müßte ja zum Beispiel (1<<PB6) gleich (1<<6) sein. Sozusagen einfach um 6 Bit geschiftet. Auf jeden Fall habe es jetzt folgendermaßen gelößt: i=(PIND & 0xE0)|(PINE>>3); //PIND7,PIND6,PIND5,PINE7,PINE6,... i ^= ~key_state; ... if(get_key_press(1<<7)) Schalter PIND7 if(get_key_press(1<<6)) Schalter PIND6 if(get_key_press(1<<5)) Schalter PIND5 if(get_key_press(1<<4)) Schalter PINE7 if(get_key_press(1<<3)) Schalter PINE6 Die ersten Tests liefen erfolgreich. Vielleicht kann mir jetzt jemand das ganze auch noch erklären ;-)))... Ciao Thomas
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.