Gleiche Tastenzeilen gleichzeitig drücken

9

Ich entwerfe eine Tastatur in VHDL. Alles funktioniert gut, wenn nur eine einzige Taste gedrückt wird. Ich scanne jede Spalte nach einem Tastendruck in einer Zustandsmaschine und wenn keine Taste gedrückt wird, schalte pin4pin6pin7pin2 = "0000"ich zum Scannen der nächsten Spalte in den nächsten Zustand um. So stelle ich die Spalten der pin3pin1pin5Reihe nach "001", "010"und "100".

Beim Scannen pin3pin1pin5wie "001"und wenn pin4pin6pin7pin2ist "0100"dann „9“ einfach gedrückt wird . Ich deklariere in VHDL pin4pin6pin7pin2als Eingabe- und pin3pin1pin5als Ausgabeports. Wenn ich drücken 6 und 9 zugleich pin6und pin7sind high. Die erste gedrückte Taste wird gelesen, die zweite wird ignoriert. Wenn ich 3 und 7 gleichzeitig drücke, gewinnt der erste, der einige ms vor dem Sieg gedrückt wurde, und die erste Taste wird gelesen, die zweite Taste wird ignoriert pin2und pin4ist high.

Hier ist der schwierige Teil. Wenn ich gleichzeitig 4 und 6 drücke, erwarte ich pin7es, highaber es wird lowund pin4pin6pin7pin2 = "0000", was ich nicht verstehe, wie und warum. Da "0000"erkannt wird, dass keine Taste gedrückt wurde, springt die Zustandsmaschine von Zustand zu Zustand. Wenn man 4 und 6 gedrückt hält, wenn man 4 mehrmals drückt und verlässt, wird erkannt, dass 6 mehrmals gedrückt wird, was ein großer Fehler ist . Ich würde mich freuen, wenn Sie mir beim Debuggen helfen können!

Dasselbe passiert mit "1" und "2", dasselbe mit "7" und "8" nur für die Schlüssel in derselben Zeile. Da dies ein laufendes Projekt ist, kann ich meinen VHDL-Code nicht online stellen :( Ich würde mich freuen, wenn Sie mir Tipps geben können, um dies zu überwinden!

Geben Sie hier die Bildbeschreibung ein

Unten lade ich meinen Code nicht auf das Board hoch, es wird kein Code ausgeführt. Bei Pin5einmaligem Drücken auf Masse wird durch einmaliges Drücken von 1,2,4,5,7,8, *, 0 die Pin3LED nicht eingeschaltet, aber wenn ich 6 und dann 4 gleichzeitig drücke, leuchtet die Pin3LED und die Pin7LED leuchtet weiterhin Wenn mein Code ausgeführt wird, geschieht dies nicht. Vielleicht habe ich etwas falsch angeschlossen und zum Glück Pin7ist es an, ich weiß nicht ...

Geben Sie hier die Bildbeschreibung ein

Unten finden Sie die Schaltpläne der Tastaturplatine:

Schema

Anarkie
quelle
Wie stellen Sie sicher, dass durch gleichzeitiges Drücken von 4 und 6 die Stifte 3 und 5 nicht kurzgeschlossen werden?
fru1tbat
@ fru1tbat Kannst du kurz etwas näher darauf eingehen? Ohne meinen Code hochzuladen, wenn auf der Karte nichts eingeschaltet ist, verbinde ich Pin5 mit Masse, dann leuchtet Pin5-LED und dann drücke ich "6". Pin7-LED leuchtet später. Ich drücke gleichzeitig "4" und "6", diesmal Pin3 LED leuchtet und Pin7 LED leuchtet noch.
Anarkie
@Tut du meinst ich sollte Pull-up für Zeilen und Pull-up für Spalten verwenden? Ich kann die Schaltung nicht ändern. Auch nicht viel von Ihrem Kommentar verstanden :(
Anarkie
Um vollständiger zu sein, werde ich eine Antwort geben. Es wäre hilfreich, wenn Sie ein Schema bereitstellen könnten, das Widerstände, LEDs, Säulentreiber und alle Wechselrichter oder Transistoren zeigt, die sich möglicherweise in der Schaltung befinden. Sind die 4 Zeilen und 3 Spalten direkt mit einer CPLD oder einem FPGA verbunden?
Tut
@Tut Die Tastatur ist nicht direkt mit dem FPGA verbunden. Dazwischen befindet sich eine weitere Karte, mit der verschiedene Karten an das FPGA angeschlossen werden können. Ich habe die Schaltpläne hinzugefügt.
Anarkie

Antworten:

4

Die kurze Antwort:

Kehren Sie Ihre Logik um. Fahren Sie die Spaltenauswahlzeilen mit Open-Drain- Logik (oder Open-Collector- Logik), wobei die ausgewählte Spalte nach unten gezogen wird und die nicht ausgewählten Spalten schweben. Wenn Sie sich eine Zeile ansehen, wird ein Tastendruck durch eine '0' erkannt. Nicht gedrückte Tasten werden durch eine '1' erkannt.

Nun die Details:

Wie EEIngenuity hervorhebt, führt das Drücken von 2 Tasten in derselben Zeile zu einem Kurzschluss zwischen den entsprechenden Spalten. Dieses (und andere Probleme mit mehreren Tastendrücken) wird normalerweise in einer Tastaturmatrix durch Hinzufügen einer Diode in Reihe mit jedem Schalter überwunden .

Da das Hinzufügen von Dioden für Sie keine Option ist, müssen Sie die Ausgänge Ihrer inaktiven Spaltenauswahl schweben lassen, um zu vermeiden, dass Sie versuchen, sie auf die entgegengesetzte Polarität wie Ihre aktive Spaltenauswahl zu bringen. Dies erfolgt mithilfe der Open-Drain-Logik. Wenn Ihre Spaltenauswahl direkt an eine CPLD oder ein FPGA gebunden ist, sollten Sie dies in Ihrem VHDL-Code erreichen können.

Das Foto in Ihrer Frage zeigt, dass Sie in jeder Spalte und in jeder Zeile einen Pull-up-Widerstand haben. Die Klimmzüge an den Säulen sind unnötig, schaden aber nichts. Die Klimmzüge in jeder Reihe stellen einen hohen Zustand sicher, es sei denn, sie werden vom Open-Drain-Treiber auf der Säule ausgewählt (über einen geschlossenen Schalter).

Ich musste einige Annahmen über Ihre Schaltung treffen, da Sie keinen vollständigen Schaltplan oder Ihren VHDL-Code angegeben haben. Du sagst

Wenn keine Taste gedrückt wird, ist dies die Bedingung pin4pin6pin7pin2 = "0000"

Auf dem von Ihnen bereitgestellten Foto sind jedoch Pull-up-Widerstände dargestellt. Dies bedeutet, dass Sie bereits irgendwo eine logische Inversion haben, möglicherweise in Ihrem VHDL-Code oder (weniger wahrscheinlich) Invertern zwischen Ihren Zeilen und Ihrem logischen Gerät (CPLD oder FPGA).

Bearbeiten:

Gemäß Ihrem Kommentar verwenden Sie in Ihren Beschreibungen eine negative Logik: "0000" zeigt an, dass alle vier Pins hoch sind usw. Dies ist der Fall, vorausgesetzt, die Spaltenauswahl und die Zeilensignale gehen direkt von Anschluss 2 Ihres Schaltplans zum FPGA Befolgen Sie meine Anweisungen oben, indem Sie die Open-Drain-Logik für die Spaltenauswahlausgänge in Ihrem FPGA verwenden.

Ich bin kein VHDL-Experte, aber ich habe dies von Xilinx gefunden :

Leiten Sie den offenen Drain-Puffer mit dem folgenden Code ab:

VHDL:

dout <= 'Z' wenn din = '1' sonst '0';

Beachten Sie auch, dass in Ihrem Schaltplan alle LEDs rückwärts verdrahtet dargestellt sind. Die Anoden gehen zu den Strombegrenzungswiderständen und die Kathoden gehen zu den Signalleitungen. Die LEDs leuchten, wenn die Signalleitungen niedrig sind.

Tut
quelle
Ich bin dabei, die Schaltpläne zu scannen, in denen der Scannertreiber installiert ist
Anarkie
Sie haben Recht, dass pin4pin6pin7pin2 = "0000"kein Tastendruck tatsächlich erfolgt 1111. In meiner Frage 1s sollte 0 sein, 0s sollte 1s sein, ich habe versucht, die Frage ein wenig zu
verschlüsseln
Ich habe die Schaltpläne hinzugefügt.
Anarkie
Vielen Dank für Ihre Erklärungen. Nachdem ich Ihre Antwort gelesen habe, habe ich einige Ideen, aber zuerst, was meinen Sie mit "Spalten schweben", "müssen die Ausgaben schweben", mit schweben meinen Sie: 110, 101, 011? Dies mache ich bereits, tatsächlich in meinem Code, wenn eine Taste gedrückt wird, sollten alle anderen Tasten ignoriert werden. Ich verstehe nur nicht, wie die LED erlischt und Pin7 hoch wird (1), während der Code läuft. Wie auch immer, wenn ich richtig verstanden habe, schlägt Ihre Lösung vor, während ich Pin5 scanne, Ausgangsports "110", die ich haben sollte out <= 'pin3' when din='1' else '0';
Anarkie
1
Schauen Sie sich den Link an, den ich bereitgestellt habe: Open-Drain (oder Open-Collector) . Die aktive Spalte wird ausgewählt, indem 0 V in dieser Spaltenzeile angesteuert werden. Die inaktiven Säulen sollten NICHT mit 3,3 V auf dieser Leitung betrieben werden, sondern müssen schwimmfähig sein (in einen hochohmigen Zustand versetzt werden), wodurch diese Leitungen effektiv vom Stromkreis getrennt werden. Wenn Sie versuchen, sie auf 3,3 V zu bringen, führt der Kurzschluss, der durch gleichzeitiges Drücken von 2 Tasten in derselben Reihe entsteht, zu einem Konflikt zwischen einer, die versucht, niedrig zu fahren, und den anderen, die versuchen, hoch zu fahren.
Tut
2

Da Sie VHDL verwenden und eine asynchrone Eingabe haben, schreibe ich diese Antwort, um sicherzustellen, dass Sie Vorsichtsmaßnahmen getroffen haben. Ich bin mir nicht sicher, ob dies Ihr Problem ist, aber es könnte sehr gut sein.

Siehe eine Frage, die ich vor einiger Zeit gestellt habe: VHDL: Empfangsmodul schlägt beim Zählen von Bits zufällig fehl

Jetzt sagst du das:

Da "0000" als nicht gedrückte Taste erkannt wird, springt die Zustandsmaschine von Zustand zu Zustand. Wenn man 4 und 6 gedrückt hält, wenn man 4 mehrmals drückt und verlässt, wird erkannt, dass 6 mehrmals gedrückt wird, was ein großer Fehler ist.

Welches ist etwas ähnlich zu dem, was ich konfrontiert war. Ich hatte ein Problem, bei dem meine Zustandsmaschine Zustände übersprang, was unmöglich schien.

Wenn Sie die Antworten auf die oben verlinkte Frage lesen, werden Sie feststellen, dass empfohlen wird, der Eingabezeile einen Synchronisierer hinzuzufügen, bevor dieser in Ihre Zustandsmaschine eingespeist wird. Dies wird normalerweise mit zwei D-Flip-Flops in Reihe erreicht:

Geben Sie hier die Bildbeschreibung ein

Wenn Ihre Tasteneingabe nicht mit Ihrer Hardware synchronisiert wird, treten sehr bizarre Probleme auf, die ich bei meinem N64-Projekt festgestellt habe. Das Hinzufügen dieses kleinen Stücks HW war fast wie Magie.

Überprüfen Sie daher zunächst, ob Ihre Eingänge synchronisiert werden.

Nick Williams
quelle
Es scheint nicht schwierig zu sein, den Synchronizer für die Antwort zu implementieren, aber wenn ich den Prozess lese, verstehe ich, dass er async_inmit 3 Taktzyklen verzögert ist, aber sein Wert und alles gleich ist?
Anarkie
Der große Unterschied besteht darin, dass Ihr Signal von asynchron in synchron konvertiert wird. Was in HW manchmal mit asynchronen Signalen (wie Ihren Schaltflächen) passiert, ist, dass sich die Bits in "Metastabilität" befinden, was sehr seltsame Fehler in der HW verursacht. Stellen Sie mit den D-Flip-Flops sicher, dass in Ihrem Design keine Metastabilität auftritt. Ich war auch skeptisch gegenüber der Wirksamkeit, aber es hat mein Problem perfekt gelöst.
Nick Williams
Ich habe es versucht, war einen Versuch wert, hat aber nicht geholfen :(
Anarkie
1

Das ist eine interessante Frage! Der Grund, warum Sie beim Drücken von Taste 4 und Taste 6 einen Tiefpunkt an Pin7 sehen, liegt an Pin3 und Pin5.

Um es weiter zu erklären, werden Pin3 und Pin5 niemals gleichzeitig hoch sein - einer von ihnen wird immer ein Weg zur Erde sein (gemäß Ihrem Design). Wenn Sie also die Tasten 4 und 6 drücken, erstellen Sie einen Erdungspfad für Pin7.

Siehe Bild:

Pin 7 sieht einen Weg zur Erde.  Sie haben einen Kurzschluss.

Miron V.
quelle
Ich habe meiner Frage ein Bild hinzugefügt und Pin7 sieht immer noch hoch aus, wenn beide Tasten gedrückt werden.
Anarkie
OP erklärte, dass er zu keinem Zeitpunkt gleichzeitig Pin 3, 1 oder 5 HIGH anhebt. Er sequenziert die Spalten mit: "001", "010" und "100. Die Pins 3 und 5 sind zu Beginn niemals gleichzeitig HOCH.
Nick Williams
1
Das ist der Punkt, den @EEIngenuity anstrebt - es gibt einen offensichtlichen Pfad zwischen Pin 3 und 5, der niemals den gleichen Wert haben wird. "Wenn Sie also die Tasten 4 und 6 drücken, erstellen Sie einen Pfad zur Erdung für Pin 7. ""
fru1tbat
1
@Anarkie Im Bild ist Pin3 nicht mit GND oder VDD verbunden. Es ist ein schwebender Knoten. Dadurch wird nicht das Kurzschlussszenario erstellt, das Sie in Ihrer ursprünglichen Testversion hatten. Versuchen Sie, Pin 3 mit VDD und Pin 5 mit GND zu verbinden, und wiederholen Sie diesen Test.
Miron V
1
@EEIngenuity Du hast absolut recht !!! Ja, ja, wenn ich Pin3 an VDD anschließe, wird Pin7 niedrig !!! Bitte helfen Sie mir, wie ich dieses Problem lösen und zum Laufen bringen kann :( Ich verwende VHDL und auch ein anderer Kollege, der im selben Projekt in einem anderen Team arbeitet, hat dieses Problem nicht, also hat er es irgendwie gelöst, aber ich mache es nicht
Ich