Guten Nachmitag, im Zuge eines Projektes (Taschenrechner selbst erstellen) muss ich eine Tastatur erstellen. Da ich keine komplizierte Taster-Matrix verwenden möchte (bin noch Neuling im Gebiet der µC Programmierung), habe ich mich für eine Porterweiterung per piso Register (74HC165) entschieden. Als Kontroller verwende ich für Testzwecke einen ATMEGA48-20PU, später soll eine ATMEGA168-20PU zum Einsatz kommen (was für den Quellcode keine Unterschied machen sollte?). Nun zum Problem, da die beiden Pins PB4 und PB3 (MISO und MOSI) bereits in Verwendung sind, ist es mir nicht mehr möglich die Schieberegister seriell mithilfe des µC auszulesen. Also habe ich mich für die Softwarevariente mithilfe dreier I/O Pins am Controller entschieden. Als Programmiersprache verwende ich C. Das Problem bei der Ausgabe am Display wird Angezeit, dass jedes Eingangspin des Inputregisters high ist, obwohl dies in der Schaltung nicht der Fall ist. Hier der Verwendete C-code: #include <avr/io.h> #include <util/delay.h> #include "lcd-routines.c" #define PC4 4 #define PC3 3 #define PC5 5 #define CLK PC4 #define PL PC3 #define DATA PC5 volatile char cSchiebreg[16]; int main(void) { lcd_init(); set_cursor(0, 1); DDRC &=~ ( (1 << DATA) ); //data als Eingang fürs serielle einlesen DDRC = ( (1 << CLK) | (1 << PL)); //CLK und PL als Ausgang PORTC |= (1 << PL); //PL wird high while (1) { _delay_ms(500); dataFromReg(); } return 0; } void dataFromReg(void) { uint8_t i = 0; PORTC |= (1 << CLK); //clk auf high wegen des Aufbaus PORTC &=~ (1 << PL); //pl auf Wert der Register einfrieren PORTC |= (1 << PL); //pl high für den nächsten Aufruf for (i = 0; i < 16; i++) { PORTC |= (1 << CLK); //clk high erstes Bit kann gelesen werden if ( PINC & ( 1 << DATA ) ) cSchiebreg[i] = '1'; //wenn serieller Ausgang des Inputregisters high ist 1 ins array schreiben else cSchiebreg[i] = '0'; /wenn serieller Ausgang des Inputregisters low ist 0 ins array schreiben PORTC &=~ (1 << CLK); //clk low um die Werte des Registers weiter zu schieben } for (i = 0; i < 16; i++) lcd_data(cSchiebreg[i]); //für testzwecke Ausgabe auf dem Display }
Bin selbst noch Neuling vieleicht liegt es aber daran, dass deine for-Schleife bis 16 zählt, ein Register dieser Art aber nur 8 Eingänge hat.
Danke für die Antwort. Leider kann das aber auch nicht das Problem sein, da ich zwei kaskadierte Register, wie es im AVG Tutorial (http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister) für Schieberegister angegeben ist, verwende. Trotzdem danke für deine Antwort
> Da ich keine komplizierte Taster-Matrix verwenden möchte
Da ist nichts kompliziertes dran - es ist viel einfacher als Dein "piso"
und benötigt im einfachsten Fall keine zusätzliche Hardware.
Otto
Das mag vieleicht sein. Mein µC hat jedoch nur noch 3 i/o-Pins zur Verfügung und ich benötige mindestens 24 Tasten. Ist das mit einer Mtrix überhaupt noch realisierbar? Danke für die Antwort gast
nein - das ist ein gutes Argument - aber wahrscheinlich nicht richtig. Du kannst die Displayausgänge für die Tastatur mitbenutzen. oder: weshalb steigst Du nicht auf einen Typen mit mehr I/O um ?
>Ist das mit einer Mtrix überhaupt noch realisierbar?
Nein. Da benötigt man ja 5 Ein- und 5 Ausgänge.....
Sowas aber auch..
/CE des 74..165 ist auf low? Ich würde die Kommunikation mit einem Oszilloskop anschauen, um Hardwarefehler auszuschließen bzw. lange delays in die Software einbauen, und mir alles mit LEDs anschauen. So richtig offensichtlich scheint mir kein Fehler im Source zu sein.
/CE des 74..165 ist auf low? ja ce wurde auf Masse gezogen. delays habe ich bereits eingebaut und die Flankenwechsel mit dem Multimeter nachkontrolliert? weshalb steigst Du nicht auf einen Typen mit mehr I/O um ? Der Umstieg ist leider nich mehr möglich, da die Bestellung eines neuen µC zu lange dauern würde und der Abgabetermin der 31.03 ist;-)
Wie bereits geschrieben, können die Leitungen des Display mit verwendet werden - bei 8 Anschlüssen für das Display und 3 freien Eingängen kämst Du hin..... Das auch nur als Backup, fall das mit dem piso nicht läuft.... Otto
Also muss die Matrix als Notlösung herhalten, obwohl mir die piso -Register lieber wären. Wie werden also die Taster zu einer Matrix zusammengeschlossen? Wie funktioniert das Auslesen und Entprellen der einzellen Taseter? Danke inzwischen
Wenn Du 8 Datenleitungen zum Display zur Verfügung hast, schaltest Du jede Datenleitung auf die eine Seite von 3 Tastern - die andere Seite jedes Tasters auf je einen Eingang. Es gibt also 8 Taster auf Eingang 1, 8 auf Eingang 2 und 8 auf Eingang3. (Kurz gesagt: 8 Spalten und 3 Reihen.) Die Abfrage läuft so, dass Du das Display ausschaltest, eine Display-Datenleitung auf "1" schaltest und anschliessend "nachsiehst", wo die "1" zurückkommt. Das ganze in einer Schleife. Zur Beachtung: ============== Wenn Du mehrere Tasten auf einmal drückst, funktioniert die Abfrage nicht mehr - zue Entkopplung werden dann 24 Dioden benötigt.
Ach ja - das Entprellen: Eine neue gleiche Taste (erneuter "1"-Pegel) wird nur akzeptiert, wenn Du an der Spalte und Reihe eine "0" ausgelesen hast. D. h. Taste gelesen -> merken -> wenn "neue Taste = alte Taste" ignorieren.
Die Taste frage ich dann also in einem Timerinterrupt ab? Ich setze in der Interruptroutine den ersten der 8 Ausgänge auf 1, Frage der Reihe nach die 3 Eingänge ab und weiß welcher der 3 Taster gedrückt wurde? Setze den ersten Ausgang wider auf 0 und gehe weiter zum zweiten (das ganze bis zum Ausgang 8). Das müsste so hinhauen? Müssen dabei die Pullabwiderstände an den 3 Eingängen aktiviert werden und die drei Eingänge entprellt werden? Und wie Funktioniet die Endkoppelung mit den Dioden?
> Die Taste frage ich dann also in einem Timerinterrupt ab? ja - oder Du pollst schnell genug > Ich setze in der Interruptroutine den ersten der 8 Ausgänge auf 1, Frage > der Reihe nach die 3 Eingänge ab und weiß welcher der 3 Taster gedrückt > wurde? Setze den ersten Ausgang wider auf 0 und gehe weiter zum zweiten > (das ganze bis zum Ausgang 8). Das müsste so hinhauen? ja - die 3 Eingänge kannst Du auch quasi-parallel - also direkt hintereinander abfragen. > Müssen dabei die Pullabwiderstände an den 3 Eingängen aktiviert werden nein - an den 3 Eingängen empfiehlt sich ein 10k Pull-Down oder Du invertierst die Logik - schiebst also eine "0" durch und fragst auf diese ab - dann werden für dir 3 Eingänge die pull-up aktiviert. > und die drei Eingänge entprellt werden? hier habe ich oben noch einen Post nachgeschoben. > Und wie Funktioniet die Endkoppelung mit den Dioden? Bei Abfrage auf "1": Datenleitung ->|- Taster 1.1 Eingang 1 1 ->|- Taster 1.2 Eingang 2 ->|- Taster 1.3 Eingang 3 Datenleitung ->|- Taster 2.1 Eingang 1 2 ->|- Taster 2.2 Eingang 2 ->|- Taster 2.3 Eingang 3 usw.
>Ach ja - das Entprellen: Sorry für meine Dummheit, aber das mit der Entprellung ist mir nicht ganz klar? Also eine Taste prellt und ändert mehrmals die Flanke high - low - high (neue Taste?). Frage ich am Eingangspin die Taste nun ab wenn sie nicht durchgeschlaten ist (also low -Pegel), ist es so als ob die Taste nicht gedrückt worden wäre. Frag ich die Taste ab wenn sie high ist erhalte ich am Eingangspin eine 1 und ich weiß, dass die Taste gedrückt wurde. Kann ich das ganze Problem nich umgehen wenn ich die Tasten wie im Tutorial (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial) angegeben mit, der inline uint8_t debounce(volatile uint8_t *port, uint8_t pin) Funktion an den Eingängen abfrage? Das mit der Endkopplung sollte kein Problem mehr sein Danke
OK - Du hast gewonnen - ich hatte nicht zu Ende gedacht ;-) Nimm das Beispiel aus dem Tutorium (Beachte, ob Du mit dem Nachteil leben kannst) Otto
Ich verstehe die Funktion zwar nicht völlig (was nicht das Problem ist). Bei Testzwecken (Taster direkt am i/o pin abfragen) hat sie aber gut funktioniert und das Prellen der Tasten behoben. Was für ein Nachteil ergibt sich duch das verwenden der genannten Funktion?
das 200ms "Stillstand" entstehen, wenn eine Taste betätigt wird.
Ok das hatte ich mir schon gedacht aber damit kann ich leben. Da ich nur einen Timerinterrupt verwende dürfte dies zu keinen Problem führen. Ich werden mich bei der nächsten Gelegenheit an die Arbeit machen. Danke für die Umstimmung, es scheint wirklich nicht sehr kompliziert zu sein. Ich hoffe ich kann bei möglichen Fertigungsproblemen;-) nochmals drauflosfragen Danke
auf jeden Fall - ich hoffe, dass ich es dann auch sehe - aber wenn nicht, sicher ein Anderer ;-) Viele Grüsse Otto
Sorry für die erneute Fragerei. Ich bin gerade dabei einen Schlatplan für die Matrix zu entwerfen. Also die Dioden müssen vor jeden Taster geschaltet werden? Oder ist es besser wenn ich sie wie im Schaltplan (Anhang) nach den Tastern einsetze? Und ist es in Ordnung wenn ich einen der beiden Diodentypen (1n4148 oder 1n4004) verwende?
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.