Estoy diseñando un teclado en VHDL. Todo funciona bien cuando solo se presiona una tecla. Estoy escaneando cada columna para presionar una tecla en una máquina de estado y cuando no se presiona ninguna tecla, que es la condición en la pin4pin6pin7pin2 = "0000"
que cambio al siguiente estado para escanear la siguiente columna. Por lo tanto, configuré las columnas pin3pin1pin5
secuencialmente en "001"
, "010"
y "100"
.
Mientras escanea pin3pin1pin5
como "001"
y si pin4pin6pin7pin2
es "0100"
entonces simplemente se presiona "9". Declaro en VHDL pin4pin6pin7pin2
como puertos de entrada y pin3pin1pin5
como de salida. Cuando presiono 6 y 9 al mismo tiempo pin6
y pin7
son high
. Se lee la primera tecla pulsada, se ignora la segunda. Cuando presiono 3 y 7 al mismo tiempo, el primero presionado con unos ms antes gana y se lee la primera tecla, la segunda tecla se ignora pin2
y pin4
son high
.
He aquí la parte complicada. Cuando presiono 4 y 6 al mismo tiempo, espero pin7
que sea high
, pero se convierte en low
y pin4pin6pin7pin2 = "0000"
, que no entiendo cómo ni por qué. Debido a que "0000"
se detecta que no se presionó ninguna tecla, la máquina de estado salta de un estado a otro. Mientras se mantiene presionado 4 y 6 si uno presiona y deja 4 varias veces, se detecta como 6 presionado varias veces, lo cual es un gran error . ¡Me encantaría que me ayudaran 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 encantaría que me diera consejos para superar esto!
A continuación, no estoy cargando mi código en el tablero, no se está ejecutando ningún código. Conectando Pin5
a tierra, una sola pulsación en 1,2,4,5,7,8,*,0 no enciende Pin3
el LED, pero si presiono 6 y luego 4 al mismo tiempo , el Pin3
LED está encendido y el Pin7
LED sigue encendido, pero cuando mi código se está ejecutando esto no sucede. A lo mejor conecté algo mal y por suerte Pin7
está encendido, no sé...
A continuación se muestra el esquema de la placa del teclado:
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 baja y las columnas no seleccionadas están flotando. Cuando mira una fila, la pulsación de una tecla se detectará con 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 agregando un diodo en serie con cada interruptor.
Dado que agregar diodos no es una opción para usted, deberá hacer flotar las salidas de sus selecciones de columna inactiva para evitar intentar llevarlas a la polaridad opuesta a la selección de su columna activa. Esto se hace usando la lógica de drenaje abierto. Si sus selecciones de 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 impulsor de drenaje abierto en las selecciones de la columna tire hacia abajo (a través de un interruptor cerrado).
Tuve que hacer algunas suposiciones sobre su circuito ya que no proporcionó 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 las resistencias pull-up. Esto implica que ya tiene una inversión lógica en alguna parte, 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 están altos, etc. Siendo ese el caso, asumiendo que las selecciones de columna 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 :
Infiere el búfer de drenaje abierto usando el siguiente código:
VHDL:
dout <= 'Z' when din='1' else '0';
También tenga en cuenta que en su esquema, todos los LED se muestran cableados al revés. Los ánodos van a las resistencias limitadoras de corriente y los cátodos van a las líneas de señal. Los LED se encienden cuando las líneas de señal se bajan.
pin4pin6pin7pin2 = "0000"
que ninguna pulsación de tecla es en realidad 1111
. En mi pregunta, los 1 deberían ser 0, los 0 deberían ser 1, traté de encriptar un poco la pregunta, lo siento si causó malentendidos...out <= 'pin3' when din='1' else '0';
pin3_internal
probablemente será un puerto de salida, y no es posible leer los puertos de salida en VHDL. Además, ¿qué es "Z"? ¿Una pequeña señal? No entiendo ese when
caso, el normal que conozco es como:output <= in0 WHEN "00",
pin3_out <= 'Z' when pin3_internal = '1' else '0';
si tuviera paréntesis, lo entendería más rápido :) Esto significa cuando Estoy comprobando pin5
que debería flotar pin3
y pin1
, así que creo que debería hacer esto en la misma línea donde estoy configurando pin3pin1pin5 <= "110"
y pin3_internal
aquí pin3_out <= 'Z' when pin3_internal = '1' else '0';
no hay ninguno de los pin2, pin7, pin6, pin4. ¿Dónde debo pin3_internal
trabajar?dout <= 'Z' when din='0' else '1';
. Sé que escribiste mucho, pero ¿podrías elaborar la solución un poco más para mí?Como está utilizando VHDL y tiene una entrada asíncrona, escribo esta respuesta para asegurarme de que tomó precauciones. No estoy seguro de si este es tu problema, pero muy bien podría serlo.
Vea una pregunta que hice hace algún tiempo: VHDL: el módulo de recepción falla aleatoriamente al contar bits
Ahora, dices que:
Debido a que "0000" se detecta como una tecla sin presionar, la máquina de estado salta de un estado a otro. Mientras se mantiene presionado 4 y 6, si uno presiona y deja 4 varias veces, se detecta que 6 se 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 saltaba 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 introduzca en su máquina de estado. Esto generalmente se logra con dos D Flip Flops en serie:
No tener la entrada de su botón sincronizada con su HW causa problemas muy extraños, que he experimentado con mi proyecto N64. Agregar este poco de HW fue casi como magia.
Por lo tanto, verifique primero que sus entradas se estén sincronizando.
async_in
se retrasa con 3 ciclos de reloj pero su valor y todo es igual?¡Esta es una pregunta interesante! La razón por la que ve un nivel bajo en el pin7 cuando presiona la tecla 4 y la tecla 6 es por el pin3 y el pin5.
Para explicar más, pin3 y pin5 nunca estarán altos al mismo tiempo; uno de ellos siempre será un camino a tierra (según su diseño). Por lo tanto, cuando presiona la tecla 4 y la tecla 6, está creando un camino a tierra para pin7.
Ver imagen:
frut1tbat
Anarkie
Anarkie
Gesto de desaprobación
Anarkie
Gesto de desaprobación
Gesto de desaprobación
Anarkie
Gesto de desaprobación