Presionando las mismas filas de teclas al mismo tiempo

9

Estoy diseñando un teclado en VHDL. Todo funciona bien cuando se presiona una sola tecla. Estoy escaneando cada columna para presionar una tecla en una máquina de estado y cuando no se presiona ninguna tecla, esa es la condición pin4pin6pin7pin2 = "0000"que cambio al siguiente estado para escanear la siguiente columna. Por lo tanto, establezco las columnas pin3pin1pin5secuencialmente en "001", "010"y "100".

Mientras escanea pin3pin1pin5como "001"y si pin4pin6pin7pin2es "0100", simplemente se presiona "9". Declaro en VHDL pin4pin6pin7pin2como pin3pin1pin5puertos de entrada y salida. Cuando presiono 6 y 9 al mismo tiempo pin6y pin7son high. Se lee la primera tecla presionada, se ignora la segunda. Cuando presiono 3 y 7 al mismo tiempo, el primero presiona con unos pocos ms antes de que gane y la primera tecla se lee, la segunda tecla se ignora, pin2y pin4son high.

He aquí la parte complicada. Cuando presiono 4 y 6 al mismo tiempo, espero pin7que sea, highpero se convierte en lowy pin4pin6pin7pin2 = "0000", lo que no entiendo cómo y por qué. Como "0000"se detecta como una tecla sin presionar, la máquina de estado salta de estado a estado. Mientras mantiene presionado 4 y 6 si uno empuja y deja 4 varias veces, se detecta que 6 presionó varias veces, lo cual es un gran error . ¡Me alegraría si me pueden ayudar a depurar esto!

Lo mismo sucede con "1" y "2", lo mismo con "7" y "8" solo para las teclas en la misma fila. Dado que este es un proyecto en curso, no puedo poner mi código VHDL en línea :( ¡Me gustaría que me dieras consejos para superar esto!

ingrese la descripción de la imagen aquí

A continuación, no estoy cargando mi código en el tablero, no se está ejecutando ningún código. Conectando Pin5a tierra, una sola pulsación en 1,2,4,5,7,8, *, 0 no enciende el Pin3LED, pero si estoy presionando 6 y luego 4 al mismo tiempo, el Pin3LED está encendido y el Pin7LED sigue encendido, pero cuando mi código se está ejecutando, esto no sucede. Tal vez conecté algo mal y por suerte Pin7está encendido, no sé ...

ingrese la descripción de la imagen aquí

A continuación se muestran los esquemas de la placa del teclado:

Esquemas

Anarkie
fuente
¿Cómo se asegura de que presionar 4 y 6 al mismo tiempo no corto los pines 3 y 5 juntos?
fru1tbat
@ fru1tbat ¿Puedes elaborar un poco más? Sin cargar mi código cuando la placa no tiene nada encendido, conecto el pin5 a la tierra, luego el LED pin5 está encendido y luego presiono "6" pin7 LED está ENCENDIDO más tarde presiono "4" y "6" al mismo tiempo esta vez pin3 El LED está encendido y el pin7 LED sigue encendido.
Anarkie
@¿Pero quieres decir que debería usar pull-up para filas y pull-up para columnas? No puedo modificar el circuito. Tampoco entendí mucho de tu comentario :(
Anarkie
Para ser más completo, proporcionaré una respuesta. Sería útil si pudiera proporcionar un esquema que muestre resistencias, LED, controladores de columna y cualquier inversor o transistor que pueda estar en el circuito. ¿Las 4 filas y 3 columnas están conectadas directamente a un CPLD o FPGA?
Tut
@Tut El teclado no está conectado directamente al FPGA, hay otra placa en el medio, para conectar varias placas al FPGA y agregué los esquemas.
Anarkie

Respuestas:

4

La respuesta corta:

Invierte tu lógica. Conduzca las líneas de selección de columna con lógica de drenaje abierto (o colector abierto) donde la columna seleccionada se tira hacia abajo y las columnas no seleccionadas están flotando. Cuando miras una fila, una 'tecla' será detectada por un '0'. Las teclas no presionadas serán detectadas por un '1'.

Ahora los detalles:

Como señala EEIngenuity, cuando presiona 2 botones en la misma fila, se produce un cortocircuito entre sus columnas correspondientes. Este (y otros problemas que involucran múltiples pulsaciones de teclas) generalmente se resuelven en una matriz de teclado al agregar un diodo en serie con cada interruptor.

Dado que agregar diodos no es una opción para usted, deberá flotar las salidas de sus selecciones de columnas inactivas para evitar tratar de conducirlas a la polaridad opuesta a su selección de columna activa. Esto se hace utilizando la lógica de drenaje abierto. Si las selecciones de su columna están vinculadas directamente a un CPLD o FPGA, debería poder lograr esto en su código VHDL.

La foto en su pregunta muestra que tiene una resistencia pull-up en cada columna y cada fila. Los pull-ups en las columnas son innecesarios, pero no dañarán nada. Los pull-ups en cada fila asegurarán una condición alta a menos que el controlador de drenaje abierto en la columna seleccione (a través de un interruptor cerrado).

He tenido que hacer algunas suposiciones sobre su circuito ya que no ha proporcionado un esquema completo o su código VHDL. Tu dices

cuando no se presiona ninguna tecla, que es la condición pin4pin6pin7pin2 = "0000"

Sin embargo, a partir de la foto que proporciona, se muestran resistencias pull-up. Esto implica que ya tiene una inversión lógica en algún lugar, posiblemente en su código VHDL o (menos probable) inversores entre sus filas y su dispositivo lógico (CPLD o FPGA).

Editar:

Según su comentario, está utilizando lógica negativa en sus descripciones: "0000" indica que los cuatro pines son altos, etc. En ese caso, suponiendo que la columna selecciona y las señales de fila van directamente desde el conector 2 en su esquema al FPGA, solo siga mis instrucciones anteriores utilizando la lógica de drenaje abierto para las salidas de selección de columna en su FPGA.

No soy un experto en VHDL, pero encontré esto de Xilinx :

Inferir el búfer de drenaje abierto utilizando el siguiente código:

VHDL:

dout <= 'Z' cuando din = '1' más '0';

También tenga en cuenta en su esquema, todos los LED se muestran cableados al revés. Los ánodos van a las resistencias limitantes de corriente y los cátodos van a las líneas de señal. Los LED se iluminan cuando las líneas de señal se ponen bajas.

Gesto de desaprobación
fuente
Estoy a punto de escanear los esquemas que instalan el controlador del escáner
Anarkie
Tienes razón acerca de que pin4pin6pin7pin2 = "0000"no hay ninguna pulsación de tecla en realidad 1111. En mi pregunta 1s debería 0, 0s debería ser 1s, intenté encriptar la pregunta un poco, lo siento si causó malentendidos ...
Anarkie
Agregué los esquemas.
Anarkie
muchas gracias por sus explicaciones, después de leer su respuesta, tengo algunas ideas, pero primero, ¿qué quiere decir con "las columnas están flotando", "necesita flotar las salidas", por flotar quiere decir: 110, 101, 011? Esto ya lo estoy haciendo, en realidad en mi código cuando se presiona una tecla, todas las demás teclas deben ignorarse. Simplemente no entiendo cómo se apaga el LED y el pin7 se vuelve alto (1), mientras se ejecuta el código. De todos modos, si entendí correcto, su solución sugiere que mientras estoy escaneando el pin5, los puertos de salida "110", debería haberlo hecho out <= 'pin3' when din='1' else '0';
Anarkie
1
Mire el enlace que proporcioné: open-drain (o open-collector) . La columna activa se selecciona conduciendo 0V en esa línea de columna. Las columnas inactivas NO deben manejarse con 3.3V en esa línea, sino que deben flotar (ponerlas en un estado de alta impedancia) que desconecte efectivamente esas líneas del circuito. Si intenta conducirlos a 3.3V, el cortocircuito creado al presionar 2 botones en la misma fila al mismo tiempo, causará una disputa entre uno que trata de conducir bajo y los otros que intentan conducir alto.
Tut
2

Como está utilizando VHDL y tiene una entrada asincrónica, estoy escribiendo esta respuesta para asegurarme de que haya tomado precauciones. No estoy seguro de si este es tu problema, pero podría muy bien serlo.

Vea una pregunta que hice hace algún tiempo: VHDL: el módulo de recepción falla aleatoriamente al contar bits

Ahora dices eso:

Debido a que "0000" se detecta como una tecla sin presionar, la máquina de estado salta de estado a estado. Mientras mantiene presionado 4 y 6 si uno empuja y deja 4 varias veces, se detecta que 6 presionó varias veces, lo cual es un gran error.

Lo cual es algo similar a lo que estaba enfrentando. Tuve un problema en el que mi máquina de estado omitiría estados, lo que parecía imposible.

Si lee las respuestas a la pregunta vinculada anteriormente, verá que se recomienda agregar un sincronizador a la línea de entrada antes de que se alimente a su máquina de estado. Esto generalmente se logra con dos chanclas D en serie:

ingrese la descripción de la imagen aquí

No tener la entrada de su botón sincronizada con su HW causa problemas muy extraños, lo que he experimentado con mi proyecto N64. Agregar este poco de HW fue casi como magia.

Por lo tanto, compruebe primero que sus entradas se estén sincronizando.

Nick Williams
fuente
Implementar el Sincronizador en la respuesta no parece ser difícil, pero cuando leo el proceso, lo que entiendo es que async_inse retrasa con 3 ciclos de reloj pero su valor y todo es lo mismo.
Anarkie
La gran diferencia es que su señal se convertirá de asíncrona a síncrona. Lo que sucede en HW a veces con señales asíncronas (como sus botones) es que los bits están en "metaestabilidad", esto causa errores muy extraños en el HW. El uso de D Flip Flops asegura que la metaestabilidad no ocurra en su diseño. También era escéptico sobre la efectividad de esto, pero resolvió mi problema perfectamente.
Nick Williams
Lo intenté, valió la pena intentarlo pero no ayudó :(
Anarkie
1

¡Esta es una pregunta interesante! La razón por la que está viendo un nivel bajo en pin7 cuando presiona key4 y key6 es debido a pin3 y pin5.

Para explicarlo más, pin3 y pin5 nunca serán altos al mismo tiempo, uno de ellos siempre será un camino a tierra (de acuerdo con su diseño). Por lo tanto, cuando presiona la tecla 4 y la tecla 6, está creando una ruta a tierra para el pin7.

Ver imagen:

El pin 7 ve un camino hacia el suelo.  Tienes un corto circuito.

Miron V
fuente
Agregué una imagen a mi pregunta y el pin7 parece alto aún cuando se presionan ambas teclas.
Anarkie
OP explicó que no levanta el pin 3, 1 o 5 ALTO al mismo tiempo en ningún momento. Él secuencia las columnas con: "001", "010" y "100. Los pines 3 y 5 nunca son ALTOS simultáneamente para empezar.
Nick Williams
1
Ese es el punto que @EEIngenuity está tratando de establecer: hay una ruta aparente entre los pines 3 y 5, que nunca tendrá el mismo valor ", por lo tanto, cuando presiona la tecla 4 y la tecla 6, está creando una ruta a tierra para el pin7. "
fru1tbat
1
@Anarkie En la imagen, Pin3 no está conectado a GND o VDD. Es un nodo flotante. Esto no crea el escenario de cortocircuito que tiene en su prueba original. Intente conectar el pin 3 a VDD y el Pin5 a GND y repita esta prueba.
Miron V
1
@EEIngenuity ¡Tienes toda la razón! ¡Sí, sí, cuando conecto el pin3 a VDD, el pin7 se vuelve bajo! Así que, por favor, ayúdenme, ¿cómo puedo superar este problema y hacerlo funcionar?: (Estoy usando VHDL y también otro colega que está en el mismo proyecto en un equipo diferente, no se enfrenta a este problema, así que de alguna manera lo resolvió, pero no lo hago) sé cómo, teclado misma, mismo tablero!
Anarkie