Appuyer sur les mêmes lignes de touches en même temps

9

Je conçois un clavier en VHDL. Tout fonctionne bien lorsqu'une seule touche est enfoncée. J'analyse chaque colonne pour une pression de touche dans une machine d'état et lorsqu'aucune touche n'est enfoncée, ce qui est la condition que pin4pin6pin7pin2 = "0000"je passe à l'état suivant pour analyser la colonne suivante. J'ai donc défini les colonnes de pin3pin1pin5manière séquentielle sur "001", "010"et "100".

Pendant la numérisation au pin3pin1pin5fur "001"et à pin4pin6pin7pin2mesure, "0100"il suffit d'appuyer sur "9". Je déclare en VHDL pin4pin6pin7pin2comme pin3pin1pin5ports d' entrée et de sortie. Lorsque j'appuie sur 6 et 9 en même temps pin6et le pin7sont high. La première touche enfoncée est lue, la seconde est ignorée. Lorsque j'appuie sur 3 et 7 en même temps, le premier appuyé avec quelques ms avant gagne et la première touche est lue, la deuxième touche est ignorée, pin2et le pin4sont high.

Voici la partie délicate. Quand j'appuie sur 4 et 6 en même temps, je m'attends pin7à l'être highmais ça devient lowet pin4pin6pin7pin2 = "0000", ce que je ne comprends pas comment et pourquoi. Parce qu'il "0000"est détecté comme aucune touche enfoncée, la machine d'état passe d'un état à l'autre. Tout en maintenant 4 et 6 si l'on pousse et laisse 4 plusieurs fois, il est détecté comme 6 pressé plusieurs fois, ce qui est un gros bug . Je serais heureux si vous pouviez m'aider à déboguer cela!

La même chose se produit avec "1" et "2", la même chose avec "7" et "8" uniquement pour les touches de la même ligne. Puisqu'il s'agit d'un projet en cours, je ne peux pas mettre mon code VHDL en ligne :( Je serais heureux si vous pouviez me donner des conseils pour surmonter cela!

entrez la description de l'image ici

Ci-dessous, je ne télécharge pas mon code sur la carte, aucun code n'est en cours d'exécution. Connexion Pin5à la terre, une seule pression sur 1,2,4,5,7,8, *, 0 n'allume pas la Pin3LED mais si je presse 6 et 4 en même temps, la Pin3LED est Pin7allumée et la LED est toujours allumée, mais lorsque mon code s'exécute, cela ne se produit pas. Peut-être que j'ai connecté quelque chose de mal et heureusement Pin7, je ne sais pas ...

entrez la description de l'image ici

Voici les schémas de la carte du clavier:

Schémas

Anarkie
la source
Comment vous assurez-vous qu'en appuyant simultanément sur 4 et 6, vous ne court-circuitez pas les broches 3 et 5 ensemble?
fru1tbat
@ fru1tbat Pouvez-vous élaborer un peu plus? Sans télécharger mon code lorsque la carte n'a rien, je connecte la broche5 au sol, puis la LED de la broche5 est allumée, puis j'appuie sur "6" la broche7 la LED est allumée plus tard j'appuie sur "4" et "6" en même temps cette fois La LED est allumée et la LED pin7 est toujours allumée.
Anarkie
@Tut tu veux dire que je devrais utiliser pull-up pour les lignes et pull-up pour les colonnes? Je ne peux pas modifier le circuit.
Je
Pour être plus complet, je répondrai. Il serait utile de fournir un schéma montrant les résistances, les LED, les pilotes de colonne et les onduleurs ou transistors qui peuvent être dans le circuit. Les 4 lignes et 3 colonnes sont-elles connectées directement à un CPLD ou FPGA?
Tut
@Tut Le clavier n'est pas directement connecté au FPGA, il y a une autre carte entre les deux, pour connecter différentes cartes au FPGA et j'ai ajouté les schémas.
Anarkie

Réponses:

4

La réponse courte:

Inversez votre logique. Conduisez les lignes de sélection de colonne avec open-drain (ou open-collector) logique à où la colonne sélectionnée est tirée vers le bas et les colonnes non sélectionnées flottent. Lorsque vous regardez une ligne, une pression sur une touche est détectée par un «0». Les touches non pressées seront détectées par un «1».

Maintenant, les détails:

Comme le souligne EEIngenuity, lorsque vous appuyez sur 2 boutons dans la même ligne, il en résulte un court-circuit entre leurs colonnes correspondantes. Ce problème (et d'autres problèmes impliquant plusieurs pressions de touches) est généralement résolu dans une matrice de clavier en ajoutant une diode en série avec chaque commutateur.

Étant donné que l'ajout de diodes n'est pas une option pour vous, vous devrez faire flotter les sorties de vos sélections de colonne inactives pour éviter d'essayer de les conduire à la polarité opposée à votre sélection de colonne active. Cela se fait en utilisant une logique à drain ouvert. Si vos sélections de colonne sont directement liées à un CPLD ou FPGA, vous devriez être en mesure de le faire dans votre code VHDL.

La photo dans votre question montre que vous avez une résistance de rappel sur chaque colonne et chaque ligne. Les tractions sur les colonnes sont inutiles, mais ne feront rien de mal. Les tractions sur chaque rangée assureront un état élevé à moins qu'elles ne soient tirées vers le bas par le conducteur à drain ouvert sur les colonnes sélectionnées (via un interrupteur fermé).

J'ai dû faire quelques hypothèses sur votre circuit car vous n'avez pas fourni un schéma complet ou votre code VHDL. Vous dites

lorsqu'aucune touche n'est enfoncée, ce qui est la condition pin4pin6pin7pin2 = "0000"

pourtant, sur la photo que vous fournissez, des résistances de rappel sont montrées. Cela implique que vous avez déjà une inversion logique quelque part, peut-être dans votre code VHDL ou (moins probablement) des onduleurs entre vos lignes et votre périphérique logique (CPLD ou FPGA).

Éditer:

Selon votre commentaire, vous utilisez une logique négative dans vos descriptions: "0000" indique que les quatre broches sont hautes, etc. suivez mes instructions ci-dessus en utilisant une logique à drain ouvert pour les sorties de sélection de colonne dans votre FPGA.

Je ne suis pas un expert VHDL, mais j'ai trouvé cela chez Xilinx :

Déduisez le tampon de drain ouvert en utilisant le code suivant:

VHDL:

dout <= 'Z' lorsque din = '1' sinon '0';

Notez également dans votre schéma que toutes les LED sont montrées câblées à l'envers. Les anodes vont aux résistances de limitation de courant et les cathodes aux lignes de signaux. Les LED s'allument lorsque les lignes de signal sont baissées.

Tut
la source
Je suis sur le point de scanner les schémas d'installation du pilote du scanner
Anarkie
Vous avez raison sur le fait pin4pin6pin7pin2 = "0000"qu'aucune touche n'est en fait 1111. Dans ma question, 1s devrait être 0, 0 devrait être 1, j'ai essayé de
crypter
J'ai ajouté les schémas.
Anarkie
merci beaucoup pour vos explications, après avoir lu votre réponse j'ai quelques idées mais d'abord que voulez-vous dire par "les colonnes flottent", "besoin de flotter les sorties", par float vous voulez dire: 110, 101, 011? C'est ce que je fais déjà, en fait dans mon code lorsqu'une touche est enfoncée, toutes les autres touches doivent être ignorées. Quoi qu'il en soit, si j'ai bien compris, votre solution suggère-t-elle lors de la numérisation de la broche 5, des ports de sortie "110", j'aurais dû out <= 'pin3' when din='1' else '0';
Anarkie
1
Regardez le lien que j'ai fourni: open-drain (ou open-collector) . La colonne active est sélectionnée en entraînant 0V sur cette ligne de colonne. Les colonnes inactives ne doivent PAS être entraînées avec 3,3 V sur cette ligne, mais doivent être flottantes (mises dans un état de haute impédance), ce qui déconnecte efficacement ces lignes du circuit. Si vous essayez de les amener à 3,3 V, le court-circuit créé en appuyant sur 2 boutons dans la même rangée en même temps, provoquera un conflit entre l'un essayant de conduire bas et les autres essayant de monter haut.
Tut
2

Puisque vous utilisez VHDL et que vous avez une entrée asynchrone, j'écris cette réponse pour vous assurer d'avoir pris une précaution. Je ne sais pas si c'est votre problème, mais cela pourrait très bien l'être.

Voir une question que j'ai posée il y a quelque temps: VHDL: le module de réception échoue de manière aléatoire lors du comptage des bits

Maintenant, vous dites que:

Parce que "0000" est détecté comme aucune touche enfoncée, la machine d'état passe d'un état à l'autre. Tout en maintenant 4 et 6 si l'on pousse et sort 4 plusieurs fois, il est détecté comme 6 pressé plusieurs fois, ce qui est un gros bug.

Ce qui est un peu similaire à ce à quoi je faisais face. J'ai eu un problème où ma machine d'état sautait des états, ce qui semblait impossible.

Si vous lisez les réponses à la question liée ci-dessus, vous verrez qu'il est recommandé d'ajouter un synchroniseur à la ligne d'entrée avant qu'il ne soit introduit dans votre machine d'état. Ceci est généralement accompli avec deux tongs D en série:

entrez la description de l'image ici

Ne pas synchroniser l'entrée de votre bouton avec votre matériel provoque des problèmes très bizarres, que j'ai rencontrés avec mon projet N64. Ajouter ce petit morceau de HW était presque comme par magie.

Veuillez donc d'abord vérifier que vos entrées sont synchronisées.

Nick Williams
la source
Pour implémenter le synchroniseur sur la réponse ne semble pas être difficile mais quand je lis le processus, ce que je comprends, c'est qu'il async_inest retardé de 3 cycles d'horloge mais sa valeur et tout est le même?
Anarkie
La grande différence est que votre signal sera converti d'asynchrone en synchrone. Ce qui se passe dans HW parfois avec des signaux asynchrones (comme vos boutons), c'est que les bits sont en "méta-stabilité", cela provoque des erreurs très étranges dans le HW. L'utilisation des tongs D garantit que la méta-stabilité ne se produit pas dans votre conception. J'étais également sceptique quant à l'efficacité de cela, mais cela a parfaitement résolu mon problème.
Nick Williams
Je l'ai essayé, valait la peine d'essayer mais n'a pas aidé :(
Anarkie
1

C'est une question intéressante! La raison pour laquelle vous voyez un minimum sur la broche 7 lorsque vous appuyez sur les touches 4 et 6 est due aux broches 3 et 5.

Pour expliquer davantage, les broches 3 et 5 ne seront jamais élevées en même temps - l'une d'entre elles sera toujours un chemin vers la terre (selon votre conception). Ainsi, lorsque vous appuyez sur les touches 4 et 6, vous créez un chemin vers la terre pour la broche 7.

Voir l'image:

La broche 7 voit un chemin vers la terre.  Vous avez un court-circuit.

Miron V
la source
J'ai ajouté une image à ma question et la broche 7 semble toujours haute lorsque les deux touches sont enfoncées.
Anarkie
OP a expliqué qu'il ne relevait pas la broche 3, 1 ou 5 HIGH en même temps à aucun moment. Il séquence les colonnes avec: "001", "010" et "100. Les broches 3 et 5 ne sont jamais HAUT simultanément pour commencer.
Nick Williams
1
C'est le point que @EEIngenuity essaie de faire - il y a un chemin apparent entre les broches 3 et 5, qui n'aura jamais la même valeur ", ainsi, lorsque vous appuyez sur les touches 4 et 6, vous créez un chemin vers la terre pour la broche 7. "
fru1tbat
1
@Anarkie Dans l'image, Pin3 n'est pas connecté à GND ou VDD. C'est un nœud flottant. Cela ne crée pas le scénario de court-circuit que vous avez dans votre essai d'origine. Essayez de connecter la broche 3 au VDD et la broche5 au GND et répétez ce test.
Miron V
1
@EEIngenuity Vous avez absolument raison !!! Oui, oui lorsque je connecte la broche3 au VDD, la broche7 devient faible !!! Alors, s'il vous plaît, aidez-moi comment puis-je surmonter ce problème et le faire fonctionner :( J'utilise VHDL et aussi un autre collègue qui est dans le même projet dans une équipe différente, ne fait pas face à ce problème alors il l'a résolu d'une manière ou d'une autre mais je ne le fais pas sais pas, même clavier, même tableau!
Anarkie