Premendo le stesse righe di tasti contemporaneamente


9

Sto progettando una tastiera in VHDL. Tutto funziona bene quando viene premuto un solo tasto. Sto eseguendo la scansione di ogni colonna per la pressione di un tasto in una macchina a stati e quando non viene premuto alcun tasto, che è la condizione pin4pin6pin7pin2 = "0000"che passo allo stato successivo per la scansione della colonna successiva. Quindi ho impostato le colonne in pin3pin1pin5sequenza su "001", "010"e "100".

Durante la scansione pin3pin1pin5come "001"e se pin4pin6pin7pin2viene "0100"quindi semplicemente premuto "9". Dichiaro in VHDL pin4pin6pin7pin2come pin3pin1pin5porte di input e output. Quando premo 6 e 9 contemporaneamente pin6e lo pin7sono high. Viene letto il primo tasto premuto, il secondo viene ignorato. Quando premo 3 e 7 contemporaneamente, il primo premuto con pochi ms prima vince e il primo tasto viene letto, il secondo tasto viene ignorato pin2e lo pin4sono high.

Ecco la parte difficile. Quando premo 4 e 6 contemporaneamente, mi aspetto pin7di esserlo highma diventa lowe pin4pin6pin7pin2 = "0000", cosa che non capisco come e perché. Poiché "0000"viene rilevato come nessun tasto premuto, la macchina a stati passa da uno stato all'altro. Tenendo premuto 4 e 6 se uno spinge e lascia 4 più volte, viene rilevato come 6 premuto più volte, il che è un grosso errore . Sarei felice se mi aiutassi a eseguire il debug di questo!

La stessa cosa accade con "1" e "2", lo stesso con "7" e "8" solo per i tasti sulla stessa riga. Dato che questo è un progetto in corso, non riesco a mettere online il mio codice VHDL :( Sarei felice di darmi dei consigli per superarlo!

inserisci qui la descrizione dell'immagine

Di seguito, non sto caricando il mio codice sulla scheda, nessun codice è in esecuzione. Collegamento Pin5a terra, una singola pressione su 1,2,4,5,7,8, *, 0 non accende il Pin3LED ma se sto premendo 6 e quindi 4 contemporaneamente il Pin3LED è acceso e il Pin7LED è ancora acceso, ma quando il mio codice è in esecuzione questo non accade. Forse ho collegato qualcosa di sbagliato e per fortuna Pin7è acceso, non lo so ...

inserisci qui la descrizione dell'immagine

Di seguito sono riportati gli schemi della tastiera:

Schematico


In che modo stai assicurando che premendo 4 e 6 contemporaneamente non si colleghino i pin 3 e 5 insieme?
fru1tbat,

@ fru1tbat Puoi approfondire un po 'di più? Senza caricare il mio codice quando la scheda non ha niente acceso, collego il pin5 a terra, quindi il LED pin5 è acceso, quindi premo "6" il LED pin7 è acceso in seguito, premo contemporaneamente "4" e "6" pin3 Il LED è acceso e il LED pin7 è ancora acceso.
Anarkie,

@Tu intendi che dovrei usare pull-up per le righe e pull up per le colonne? Non riesco a modificare il circuito. Inoltre non ho capito molto dal tuo commento :(
Anarkie l'

Per essere più completo, fornirò una risposta. Sarebbe utile se fosse possibile fornire uno schema che mostra resistori, LED, driver di colonna e qualsiasi inverter o transistor che potrebbe essere nel circuito. Le 4 file e le 3 colonne sono collegate direttamente a un CPLD o FPGA?
Tut

@Tut La tastiera non è direttamente collegata all'FPGA, nel mezzo c'è un'altra scheda, per collegare varie schede all'FPGA e ho aggiunto gli schemi.
Anarkie,

Risposte:


4

La breve risposta:

Inverti la tua logica. Guidare le linee di selezione della colonna con la logica open-drain (o open-collector) in cui la colonna selezionata è abbassata e le colonne non selezionate sono mobili. Quando si guarda una riga, la pressione di un tasto verrà rilevata da uno '0'. I tasti non premuti verranno rilevati da un '1'.

Ora i dettagli:

Come sottolinea EEIngenuity, quando si premono 2 pulsanti nella stessa riga, si ottiene un cortocircuito tra le loro colonne corrispondenti. Questo (e altri problemi che coinvolgono la pressione di più tasti) vengono generalmente superati in una matrice di tastiera aggiungendo un diodo in serie con ciascun interruttore.

Poiché l'aggiunta di diodi non è un'opzione per te, dovrai spostare le uscite delle selezioni di colonne inattive per evitare di provare a guidarle nella polarità opposta mentre selezioni la colonna attiva. Questo viene fatto usando la logica open-drain. Se le selezioni delle colonne sono collegate direttamente a un CPLD o FPGA, dovresti essere in grado di farlo nel tuo codice VHDL.

La foto nella tua domanda mostra che hai una resistenza pull-up su ogni colonna e ogni riga. I pull-up sulle colonne non sono necessari, ma non danneggiano nulla. I pull-up su ciascuna fila assicureranno una condizione elevata a meno che non venga tirato in basso dal driver open-drain sulla colonna selezionata (tramite un interruttore chiuso).

Ho dovuto fare alcune ipotesi sul tuo circuito poiché non hai fornito uno schema completo o il tuo codice VHDL. Tu dici

quando non viene premuto alcun tasto, che è la condizione pin4pin6pin7pin2 = "0000"

tuttavia dalla foto fornita, vengono mostrate le resistenze di pull-up. Ciò implica che hai già un'inversione logica da qualche parte, possibilmente nel tuo codice VHDL o (meno probabile) inverter tra le tue file e il tuo dispositivo logico (CPLD o FPGA).

Modificare:

Secondo il tuo commento, stai usando una logica negativa nelle tue descrizioni: "0000" indica che tutti e quattro i pin sono alti, ecc. Stando così le cose, supponendo che la colonna selezioni e i segnali di riga passino direttamente dal connettore 2 del tuo schema al FPGA, solo segui le mie indicazioni sopra usando la logica open-drain per le uscite di selezione colonna nel tuo FPGA.

Non sono un esperto di VHDL, ma ho trovato questo da Xilinx :

Inferire il buffer di drain aperto utilizzando il seguente codice:

VHDL:

dout <= 'Z' quando din = '1' else '0';

Nota anche nello schema, tutti i LED sono mostrati cablati all'indietro. Gli anodi vanno ai resistori limitatori di corrente e i catodi vanno alle linee del segnale. I LED si accendono quando le linee del segnale sono abbassate.


Sto per scansionare gli schemi che installano il driver dello scanner
Anarkie,

Hai ragione sul fatto che pin4pin6pin7pin2 = "0000"nessuna pressione dei tasti è in realtà 1111. Nella mia domanda 1s dovrebbe 0, 0s dovrebbe essere 1s, ho provato a
criptare

Ho aggiunto gli schemi.
Anarkie,

grazie mille per le tue spiegazioni, dopo aver letto la tua risposta ho alcune idee ma prima cosa intendi con "colonne fluttuanti", "hai bisogno di far fluttuare gli output", per float intendi: 110, 101, 011? Lo sto già facendo, in realtà nel mio codice quando viene premuto un tasto, tutti gli altri tasti dovrebbero essere ignorati. Non capisco come il LED si spenga e il pin7 diventa alto (1), mentre il codice è in esecuzione. Comunque se ho capito bene è la tua soluzione che suggerisce mentre sto eseguendo la scansione del pin5, porte di uscita "110", dovrei avere out <= 'pin3' when din='1' else '0';
Anarkie

1
Guarda il link che ho fornito: open-drain (o open-collector) . La colonna attiva viene selezionata guidando 0 V su quella linea di colonna. Le colonne inattive NON devono essere pilotate con 3,3 V su quella linea, ma devono essere flottate (messe in uno stato ad alta impedenza) che scollega efficacemente quelle linee dal circuito. Se si tenta di guidarli a 3,3 V, il cortocircuito creato premendo contemporaneamente 2 pulsanti nella stessa riga, causerà una contesa tra uno che cerca di abbassare e gli altri che cercano di guidare alto.
Tut

2

Dato che stai usando VHDL e hai un input asincrono, sto scrivendo questa risposta per assicurarti di prendere una precauzione. Non sono sicuro che questo sia il tuo problema, ma potrebbe benissimo esserlo.

Vedi una domanda che ho posto qualche tempo fa: VHDL: il modulo di ricezione fallisce casualmente quando si contano i bit

Ora dici che:

Poiché "0000" viene rilevato come nessun tasto premuto, la macchina a stati passa da uno stato all'altro. Tenendo premuto 4 e 6 se uno spinge e lascia 4 più volte, viene rilevato come 6 premuto più volte, il che è un grosso errore.

Che è in qualche modo simile a quello che stavo affrontando. Ho avuto un problema in cui la mia macchina statale avrebbe saltato gli stati, che sembrava impossibile.

Se leggi le risposte alla domanda collegata sopra, vedrai che si consiglia di aggiungere un sincronizzatore alla riga di input prima che venga inserito nella tua macchina a stati. Ciò si ottiene in genere con due infradito D in serie:

inserisci qui la descrizione dell'immagine

Non avere l'input del pulsante sincronizzato con il tuo HW provoca problemi molto bizzarri, che ho riscontrato con il mio progetto N64. Aggiungere questo pezzetto di HW era quasi come per magia.

Quindi controlla prima che i tuoi input siano sincronizzati.


L'implementazione del Synchronizer sulla risposta non sembra essere difficile ma quando leggo il processo, quello che capisco è che async_inè ritardato di 3 cicli di clock ma il suo valore e tutto è uguale?
Anarkie,

La grande differenza è che il tuo segnale verrà convertito da asincrono a sincrono. Ciò che accade in HW a volte con segnali asincroni (come i pulsanti) è che i bit sono in "meta-stabilità", questo provoca errori molto strani in HW. L'uso delle infradito D assicura che non si verifichino meta-stabilità nel progetto. Ero anche scettico sull'efficacia di questo, ma ha risolto perfettamente il mio problema.
Nick Williams,

L'ho provato, valeva la pena provare ma non ha aiutato :(
Anarkie l'

1

Questa è una domanda interessante! Il motivo per cui si sta riscontrando un pin7 in esaurimento quando si premono i tasti 4 e 6 è a causa di pin3 e pin5.

Per spiegare ulteriormente, pin3 e pin5 non saranno mai alti allo stesso tempo - uno di loro sarà sempre un percorso verso terra (secondo il tuo progetto). Pertanto, quando si preme il tasto 4 e il tasto 6, si crea un percorso verso terra per pin7.

Vedi l'immagine:

Il pin 7 vede un percorso verso terra.  Hai un corto circuito.


Ho aggiunto un'immagine alla mia domanda e pin7 sembra ancora alto quando vengono premuti entrambi i tasti.
Anarkie,

OP ha spiegato che non alza il pin 3, 1 o 5 HIGH contemporaneamente in nessun momento. Segue le colonne con: "001", "010" e "100. I pin 3 e 5 non sono mai HIGH contemporaneamente per cominciare.
Nick Williams,

1
Questo è il punto che @EEIngenuity sta cercando di chiarire: esiste un percorso apparente tra i pin 3 e 5, che non avrà mai lo stesso valore ", quindi, quando si preme il tasto 4 e il tasto 6, si crea un percorso verso terra per il pin7. "
fru1tbat,

1
@Anarkie Nell'immagine Pin3 non è collegato a GND o VDD. È un nodo mobile. Questo non crea lo scenario di corto circuito che hai nella tua versione di prova originale. Prova a collegare il pin 3 a VDD e Pin5 a GND e ripeti questo test.
Miron V,

1
@EEIngenuity Hai assolutamente ragione !!! Sì, sì quando collego pin3 a VDD, pin7 diventa basso !!! Quindi per favore aiutami come posso superare questo problema e farlo funzionare :( Sto usando VHDL e anche un altro collega che è nello stesso progetto in un team diverso, non affronta questo problema, in qualche modo lo ha risolto ma io Sai, stessa tastiera, stessa scheda!
Anarkie,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.