Moin,
brauch mal euren Rat, wie man am sinnvollsten mit sehr großer Anzahla n
Ein- und Ausgängen umgeht. Um mal mit schönen Zahlen z urechnen runde
ich mal auf auf 64 Taster und doppelt sovielen Treiber-Ausgängen, die
jeweils einen Impuls rauswerfen sollen, wenn der zugehörige Taster den
Zustand toggelt sowie noch einmal 128 LED-Ausgänge um den Zustand
dauerhaft anzuzeigen.
Sonderlich zeitkritisch ist das ganze nicht, bis zu 'ner Drittel Sekunde
störts nicht wirklich.
Wer jetzt Tastaturmatrix schreit - Nö, es sollen mehrere gleichzeitige
Tastendrücke möglich sein. AFAIK geht das mit einer Matrix dann nicht
mehr so ohne weiteres? Dachte jetzt an PISO-Schieberegister, die man
dann einliest. Ausgabe dann über SIPO-Schieberegister.
Soweit die Grundidee - aber wie setzt man das nun um? Zwischen Erfassen
des Eingangstastendrucks und ausgabe sollen noch diverse
Verriegegelungbedingungen abgeprüft werden, man mus also ggf. jeden
Ein/Ausgang mehrfach verarbeiten.
Ist es nun sinniger, jeweils das Eingangsabbild am Stück zu lesen und
auc hz speichern? So als riesen bitfeld oder dergleichen? (gibt's da ein
Größenlimit?). Entprellung durch Abgleich mit den letuten beiden
Einlesevorgängen, auf das sich nix mehr ändert?
Oder geht man da besser "Kanalorientiert" ran und speichert für jeden
Taster + zugehörige Ausgänge die diversen anfallenden Daten in einer dem
eigenen Variabeln/Bitfeld pro "Kanal"? Also Meinetwegen letzte 3
Eingangszustände, 2 bits für aktuellen Ausgangszustand, 2 bit für
angeforderten Ausgangszustand, 2 Ausgangs-LED, 2 Treiber-Ports, 3 bit
minimalst-Timer zur Treiberpulslängenbegrenzung, ggf. noch zwei Flags
für blockiert durch verriegelung und blinkmodus.
Welche Variante ist Vorteilhafter? Es jeweils in einer Variablen
abzuhandeln oder am Stück? Kann man die manipulierte Variable in einer
Schleife einfach höchzählen? Also nich 'nen Wert ++ oder += sondern die
Funktion auf die nächste der 64 variablen loslassen, um nich alle 64 mal
nen aufruf tippen zu müssen. Lassen sich Pointer da einfach mit ++
passend im Speicherberiech weiterschalten?
schöne Grüße,
Trabi
Zumindest bei so einer großen Anzahl Taster, wäre es ja schon fast
praktischer eine Tastatur(PS/2) zu verwenden und das Protokoll dazu zu
benutzen. Damit weißt du über die Scancodes von der Tastatur direkt was
gedrückt wurde. Auch gleichzeitige Tasten sind dabei möglich.
Ob A jetzt ein A irgendwo hinschreibt, oder du sonst was damit
anstellst, entscheidest du ja beim programmieren.
Teletrabi wrote:
> Wer jetzt Tastaturmatrix schreit - Nö, es sollen mehrere gleichzeitige> Tastendrücke möglich sein. AFAIK geht das mit einer Matrix dann nicht> mehr so ohne weiteres?
Na klar.
Hmm, wie macht man das bei 'ner Matrixanordnung und mehreren zugleich
gedrückten Tasten?
Tastatur - scheidet aus, die Taster sollen in bestimmter Form auf einem
Schaltpult angeordnet werden. Geht also nicht nur um möglichst viele
Tasten sondern schnelle Zuordnung zur gewünschten Funktion.
Gruß,
Trabi
>64 Tasten, das sind 8 mal 74HC165 + Pullups 8*4,7k, fertsch.
Warum nicht 1x74HC595, 1x74HC165 und 8xPullUp...?
Eine Matrix kann doch mehrere Tasten zugleich erkennen..
Matrix.
Scannen musste die sowieso.
Und wenn mehrere Tasten auftreten kann man das auch sauber erkennen.
Ev. zum Rechenleistung sparen nen kbhit() (oder per ISR) realisieren, wo
ein freier ausgang des select chips (z.B. 3->8) gleichzeitig
(Dioden-ODER) alle selects auf HIGH legt.
Danach dann per ScanMatrix() die Matrix auslesen. Der User wird die
Taste schon lange genug festhalten (vom uC aus gesehen...) :-)
VG,
/th.
Matthias Lipinsky wrote:
> Warum nicht 1x74HC595, 1x74HC165 und 8xPullUp...?>> Eine Matrix kann doch mehrere Tasten zugleich erkennen..
Dann hast Du aber noch die 64 Dioden vergessen.
Das sind dann 67 Bauteile anstelle nur 16 Bauteile bei meinem Vorschlag.
Aber auch, wenn Du nur 2 Tasten gleichzeitig erkennen willst, brauchst
Du noch 8 Dioden, sonst kämpfen die 74HC595-Ausgänge gegeneinander.
Peter
Skua wrote:
> Matrix mit Dioden entkoppeln.
Dioden sind unnötig, wenn man die Zeilentreiber-Pins, die nacheinander
low werden, nicht allesamt gleichzeitig auf Output programmiert, sondern
wenn man immer nur den Pin auf Ausgang programmiert, den man gerade
low-setzen möchte; die anderen bleiben Inputs, aber mit int. Pullup. So
gibt es keine gegenseitigen Kurzschlüsse beim gleichzeitigen Drücken
mehrerer Tasten, und man kann dennoch gleichzeitiges Drücken einwandfrei
auswerten.
Natürlich: die Software ist etwas aufwendiger.
Günter R. wrote:
> Dioden sind unnötig
Quatsch.
Nimm ne 2*2 Matrix und dann drücke 3 Tasten.
Ohne Dioden kannst Du nicht erkennen, welches die nicht gedrückte Taste
ist.
Peter
>Matrix.>Scannen musste die sowieso.
Bloß keine Matrix :-) Das Abklappern der Matrix benötigt unnötig viel
Zeit.
Mit Schieberegistern und dem SPI (USI) Interface eines AVR werden
Ausgaben und Eingaben schnell erledigt. Vorteilhaft ist zudem, daß die
I/O-Leitungen dezentral verlegt werden können; die Schieberegister
werden entsprechend angeordnet.
Ausgaben erfolgen nur, wenn sich der Zustand einer LED geändert hat.
Entprellen muß Du permanent (10-30ms Intervalle). Jede Änderung eines
Tasters würde ich als Wert mit Tastennummer und Zustand in ein FIFO
schreiben, welches dann im Hauptprogramm ausgelesen wird und
entsprechende Reaktionen auslöst.
Um ein EMV-leises System zu bekommen, kann man den Tastern noch
XOR-Gatter spendieren, die - kaskadiert - jede Zustandsänderung an den
µC melden und erst dann eine Abfrage der Schieberegister veranlassen
(z.B. CMOS 4531).
Seit wann braucht man bei einer Tastenmatrix denn Dioden? Ich bin mir
ziemlich sicher, dass meine Tastatur nach ziemlich genau dem gleichen
Prinzip funktioniert :P
Einfach (wie schon gesagt) jede Zeile nacheinander abscannen und die
Eingänge einlesen.
EDIT: Ich glaube nicht, dass die Schieberegister Variante zeitlich
irgendeinen Vorteil gegenüber der Scan Variante hat. Eher andersherum
würde ich jetzt behaupten.
> Bloß keine Matrix :-) Das Abklappern der Matrix benötigt unnötig viel Zeit.
Dummfug!
Daher die kbhit - schaltung.
Habe das selber mal auf nem M16C gemacht, wo ich massig Rechenleistung
für was anderes brauchte.
VG,
/th.
Peter Dannegger wrote:
> Günter R. wrote:>>> Dioden sind unnötig>> Quatsch.>> Nimm ne 2*2 Matrix und dann drücke 3 Tasten.> Ohne Dioden kannst Du nicht erkennen, welches die nicht gedrückte Taste> ist.>>> Peter
Da hast Du recht. Ich muß etwas zurückrudern: bei meiner Methode können
bis zu 2 gleichzeitig gedrückte Tasten erkannt werden; mehr
gleichzeitige Tastendrucke führen zu Fehlerkennung.
Lothar Miller wrote:
>> Seit wann braucht man bei einer Tastenmatrix denn Dioden?> Was kommt denn heraus, wenn Scanline A aktiv ist?
Hm, ich könnte schwören ich hab das mal irgendwo ohne Dioden gesehen,
finde es aber gerade nicht wieder.
Na gut, gebe ich mich erst mal geschlagen. Wenn das schon so viele hier
behaupten, ziehe ich lieber den Kürzeren ;)
> Hm, ich könnte schwören ich hab das mal irgendwo ohne Dioden gesehen,> finde es aber gerade nicht wieder.
Ich verwende so eine Matrix auch ohne Dioden. Allerdings lasse ich nur 1
Tastendruck zu. Werden mehrere Tasten gleichzeitig betätigt (mehrere
Return-Lines sind low) dann wird dieser Zustand solange ignoriert, bis
nur noch 1 Taste aktiv ist.
Lothar Miller wrote:
> Ich verwende so eine Matrix auch ohne Dioden. Allerdings lasse ich nur 1> Tastendruck zu. Werden mehrere Tasten gleichzeitig betätigt (mehrere> Return-Lines sind low) dann wird dieser Zustand solange ignoriert, bis> nur noch 1 Taste aktiv ist.
Genau so mache ich es auch, vorzugsweise mit fertigen Folientastaturen
von Hoffmann & Krippner (für Labor-Modelle). Dort gibt es keine Dioden.
Mahlzeit,
hab noch einen Vorschlag. Man könnte das Problem mit EINEM IC
(MAX6954-55)erschlagen. Ist nicht ganz billig, aber das Ding steuert bis
zu 128 LEDs und 32 Taster an. Mit nem kleinen Trick gehen auch 64
Taster. Die Ansteuerung geht entweder über SPI(MAX6954) oder I2C
(MAX6955).
(Gibt es bei DigiKey)
Gruss Uwe
>Habe das selber mal auf nem M16C gemacht, wo ich massig Rechenleistung>für was anderes brauchte.
Hut ab, Du scheinst ja ein Profi zu sein. Hast Du in Deiner Matrix auch
Schalter abgefragt?
Und wie ist Dein Lösungsvorschlag für die vielen, vielen LEDs und die
vielen, vielen Treiberausgänge? Gibt es dafür auch eine Matrix?
Wie auch immer: ich nehm dafür ein CPLD und mach da einen SPI-Slave
rein. Schwuppdiwupp, fertig sind 64 Aus- und Eingänge mit einem billigen
XC95144 von Xilinx (für 6,60 Euro bei Angelika).
Oder wenns nicht unbedingt 5V resistent sein muß: X2C-Familie oder
MachXO-FPGAs (aber das ist dann schon eine andere Liga).
Lothar Miller wrote:
> Wie auch immer: ich nehm dafür ein CPLD und mach da einen SPI-Slave> rein. Schwuppdiwupp, fertig sind 64 Aus- und Eingänge mit einem billigen> XC95144 von Xilinx (für 6,60 Euro bei Angelika).
Was, so teuer?
Je 8* 74HC165 und 74HC595 gibts bei Angelika für nur 3,12€.
Peter
Lothar Miller wrote:
>> XC95144 von Xilinx (für 6,60 Euro bei Angelika).
Ich sehe grad im Datenblatt, der frißt ja im low power mode stolze
160mA.
Damit gewinnst Du aber keinen Umweltpreis.
Peter
Wieso verwendest Du nich einfach I2C-Bus I/O Expander, z.B. der weiter
oben bereits erwähnte PCF8575 (16 IOs pro Chip)
Ich bin mir sicher, das ist in diesem Fall die beste und einfachste
Lösung...
> Damit gewinnst Du aber keinen Umweltpreis.
Das war nie meine Absicht ;-)
Natürlich ist dieses CPLD ein uralter Zombie, andere könnnen das besser.
Mir gings um die Richtung: 1 IC mit wenig Layoutfläche und vielen Pins.
> Und was kostet der bei Angelika?
Den gibts da nicht, da mußt du wonaders suchen :-/
Gasst wrote:
>>oben bereits erwähnte PCF8575 (16 IOs pro Chip)>> Davon sind max. acht Stück an einem IIC-Bus adressierbar. Ich fürchte> nur, das reicht nicht aus.
Und außerdem kommt man preislich doppelt so hoch aus, als würde man
einfache Schieberegister verwenden.
Die Schieberegister kann man übrigens kaskadieren, das ist im Prinzip
noch besser als 8 einzelne Chips an nem I2C Bus anzubinden.
Peter Dannegger wrote:
>>> XC95144 von Xilinx (für 6,60 Euro bei Angelika).> Ich sehe grad im Datenblatt, der frißt ja im low power mode stolze 160mA.
Der XC95144XL begnügt sich schon mal mit 45mA bei 1MHz ...
... und könnte notfalls bis über 150MHz Taktfrequenz ;-)
Moin,
schönen Dank schonaml für eure Vorschläge.
Mal gucken, ob ich mir die Arbeit mit dem Dioden löten machen will. ich
tendiere eher zu den Schieberegistern, als SMD aufgelötet, andere Seite
aös GND und sich schonmal nen haufen bohrungen sparen mittels
Flachbandkabel-Platinensteckverbinder und dann je zwei Adern zum
Schalter geführt. Ist glaub ich insgesamt der wenigste Hardware-Aufwand.
Noch interessanter ist für mich eher die Softwareseite. Bislang
favorisiere ich da, jeweils ein Eingangs- und Ausgangsabbild zu
erstellen und mit entsprechenden Verarbeitugnsfunktionen die Verbindung
dazwichen herzustellen. Hat den Vorteil, ich kann ohne den weiteren
Ablauf zu stören einfach eine fragliche Verarbeitung auskommentieren und
muss nich nach jedem gelesenen Eingangsbit schon wissen, was ich damit
mach bzw. im Probiermodus jedesmal in den Eingangslese und
Ausgangschreibfunktionen rumeditieren.
Nur - wie parkt man die 64 bzw 2x128 bit am sinnigsten?
Als eine Bitfeld-Structure? Geht das mit solch großer Anzahl?
Oder als ein Array? Oder nützt mir Union hier was?
Zum Bitfeld-Ansatz - ich befürchte mal, der unten angehängte Code wird
so nicht laufen, weil einmal die Referenzierung innerhlab der Structure
".1", ".2" usw. ein Art Name ist, während Bitplatz eine Int-Zahl
darstellt und damit vermutlich nicht geeignet um per structure.bitzahl
drauf zuzugreifen? Gibts eine Möglichkeit in einer Schleife im Bitfeld
entlangzulaufen oder muss man da bis zu 128 den Befehl mit dem passenden
Bitplatz innerhalb der Structure aufrufen?
Lässt sich so ein Bitfeldinhalt vielleicht mittels Shift / Rotate-Befehl
verschieben?
Soweit ich das überschaue sind Pointer ja unzulässig? Oder nur nicht
offiziell unterstützt aber doch möglich? Liegt denn der Speicherbereich
überhaut nebeneinander oder landet man dann irgednwo, abe rnur nich im
zweiten Structure-Byte, wenn man den Zeiger erhöhen würde?
Anderer Ansatz - Array. Hier ist ja ein entlanglaufen halbwegs
problemlos möglich. Gibts denn ein Bit-Array? Oder belegt er wie ich
vermute gleich ein Byte pro gewünschtem Bit? (okay, notfalls kann man
ein Byte ja noch als Bitfeld missbrauchen, wird nur recht
unübersichtlich)
Wie krieg ich nun am besten bis zu 128 bit leicht ansprechbar für
vergleiche und leicht per schleife abarbeitbar umgesetzt?
schönen Dank im vorraus,
Trabi
#define inputanzahl = 16
#define inp_clk = PB7
#define inp_date = PB6
#define inp_load = PB5
struct {
unsigned char 1:1; // je ein bit
unsigned char 2:1;
// [...]
unsigned char 15:1;
unsigned char 16:1;
} inp;
// Function prototypes
[...]
int read_inp ()
{
//Port initialisieren:
// [....]
// PISO-Register laden:
// [...]
// Daten in Eingangs-Bitfeld übernehmen:
for (int bitplatz = 0; bitplatz <inputanzahl; )
{
set_PORTB_bit (1<<inp_clk);
set_PORTB_bit (0<<inp_clk);
inp.bitplatz = (PINB & (1<<inp_data));
bitplatz++;
}
return 1;
}
Hallo,
also wenns preiswert sein soll könnte die Matrix mit Dioden die Lösung
sein, andererseits ist das hier ein Microcomputer-Forum, das schreit
doch irgendwie nach einer eleganten Lösung wie
- M8 als Slave mit jeweils 8 Leds und 8 Tastern
- I2C-Bus zur Verbundung zum Master
- Master z.B. M32 je nach Applikation auch kleiner
Gruß,
Michael
P.S.: bitte das Entprellen nicht vergessen !!!
Teletrabi wrote:
> Noch interessanter ist für mich eher die Softwareseite. Bislang> favorisiere ich da, jeweils ein Eingangs- und Ausgangsabbild zu> erstellen und mit entsprechenden Verarbeitugnsfunktionen die Verbindung> dazwichen herzustellen.
Ja, so mache ich das auch.
Das SPI schaufelt Bytes in und aus dem SRAM.
Damit das gut lesbar ist, vergebe ich den Bits Namen.
Dazu benutze ich das Macro RBIT (siehe Anhang):