El
propósito es conectar un teclado matricial 4x4 (TM4) al puerto PMOD JA de la
tarjeta Nexys 4. Cada vez que se presione una tecla, su valor se mostrara en el
display de siete segmentos (D7S) numero 0, el ultimo visto desde la derecha del
conjunto de displays.
Para la realización de este ejercicio, se Divide por etapas:
Paso 1 Diagrama De Estados
Paso 2 definicion de teclado
como se ve en la figura, el teclado
cuenta con 7 pines de control. por ejemplo cuando aprietas la tecla numero 1 se
conectan los pines 2 y 3, para la tecla 5 se conectan los pines 7 y 1.
En la
imagen se puede ver un teclado matricial de 4 filas por 3 columnas con un total
de 12 teclas (4×3), consta de 7 pines, 4 pines para las filas y 3 pines para
las columnas, este se caracteriza porque a cada tecla le corresponde 2 pines,
un pin de una fila y un pin de una columna, para su uso con la FPGA solo serán
necesarios la utilización de 7 pines de este.
Se puede
ver el orden de las filas y las columnas para este modelo, siendo necesario
siempre verificarlos mediante la hoja de datos del teclado que se tenga, en
este caso por ejemplo a la tecla 1 le corresponde el pin 1 por estar en la fila
1 y el pin 5 por estar en la columna 1, a la tecla 8 por ejemplo le
corresponde el pin 3 por estar en la fila 3 y el pin 6 por estar en la columna
2, la misma idea es para las demás teclas en cuanto a la correspondencia de
pines por tecla.
Internamente el teclado matricial de
4×3 se lo puede ver como en la imagen, en ella se ve por ejemplo para las
filas en negro, que a la fila 1 le corresponden las teclas 1, 2, 3, y
están conectados al pin 1 del teclado, lo mismo para las otras filas; en cuanto
a las columnas en azul, por ejemplo a la columna 2 le corresponden las
teclas 2, 4, 8, 0 que están conectadas al pin 6, lo mismo para las otras
columnas.
El display es una forma de representar números en equipos electrónicos. Está compuesto de siete segmentos que se pueden encender o apagar individualmente. Cada segmento tiene la forma de una pequeña línea.
A
cada uno de los segmentos que forman el display se les denomina a, b, c, d, e,
f y g y están ensamblados de forma que se permita activar cada segmento por
separado consiguiendo formar cualquier dígito numérico. A continuación se
muestran algunos ejemplos:
- Si se activan o encienden todos los segmentos se forma el número “8”.
- Si se activan sólo los segmentos: “a, b, c, d, e, f,” se forma el número “0”.
- Si se activan sólo los segmentos: “a, b, g, e, d,” se forma el número “2”.
- Si se activan sólo los segmentos: “b, c, f, g,” se forma el número “4”.
Paso 4 definición de Hardware Pmods
CONECTORES PMOD
La NEXYS 4 cuenta con 4
conectores PMOD que ofrecen la posibilidad de adicionar hardware a la tarjeta
para realizar diseños todavía mas complicados. Cada conector ofrece 8 señales
de datos, dos conexiones a GND y dos a 3.3V. En la siguiente tabla se muestra a
que pines del FPGA están conectados cada señal de los PMOD
Para la realización de este ejercicio, los pmod a utilizar en la FPGA son los "JA" :
Para
el taller del teclado se necesita reflejar la tecla oprimida en un display de 7
segmentos. Como la tarjeta fpga nexys 4 posee 8 displays, usaremos tan solo 1,
en este caso el "n6", este se introduce en el código en un vector de
8 bits, en el cual cada bit va a representar un display entonces ponemos en
"0" el display que vayamos a utilizar.
Paso 5 código en Software Vivado, Programación "VHDL"
- Programación en .vhd
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity division is
port (
ledfila, ledcol : out unsigned(3 downto 0);
clk : in std_logic;
reset : in std_logic;
fila : in unsigned(3 downto 0);
col : out unsigned(2 downto 0);
display : out std_logic_vector(7 downto 0);
seg7 : out std_logic_vector(6 downto 0)
);
end division;
architecture division of division is
type estado is (reposo, inicio, cuenta, rotacion, deteccionFilaCol, deteccionTecla, mostrar);
signal estadoActual, estadoSiguiente : estado;
signal scol : unsigned(2 downto 0);
signal scol4 : unsigned(3 downto 0);
signal nfila : unsigned(3 downto 0);
signal tecla : unsigned(3 downto 0);
signal multi : unsigned(7 downto 0);
signal contador : unsigned(23 downto 0);
constant U0L : unsigned(23 downto 0) := to_unsigned(0,24);
constant U0 : unsigned(3 downto 0) := to_unsigned(0,4);
constant U11: unsigned (3 downto 0) := to_unsigned (11,4);
constant U1 : unsigned(3 downto 0) := to_unsigned(1,4);
constant U2 : unsigned(3 downto 0) := to_unsigned(2,4);
constant U3 : unsigned(3 downto 0) := to_unsigned(3,4);
constant U4 : unsigned(3 downto 0) := to_unsigned(4,4);
constant U5 : unsigned(3 downto 0) := to_unsigned(5,4);
constant U6 : unsigned(3 downto 0) := to_unsigned(6,4);
constant U7 : unsigned(3 downto 0) := to_unsigned(7,4);
constant U8 : unsigned(3 downto 0) := to_unsigned(8,4);
constant U9 : unsigned(3 downto 0) := to_unsigned(9,4);
constant U12: unsigned(3 downto 0) := to_unsigned (12,4);
constant U10: unsigned (3 downto 0) := to_unsigned (10,4);
begin
ledfila <= fila;
ledcol <= '1' & scol;
display <= "11111110";
col <= scol;
multi <= U3*nfila;
-- camino de datos (datapath)
process(clk, estadoActual,tecla,scol,fila)
begin
if (clk'event and clk = '1') then
case estadoActual is
when reposo =>
scol <= "111";
contador <= U0L;
when inicio =>
scol <= "011";
when cuenta =>
contador <= contador+1;
when rotacion =>
scol <= scol(1 downto 0) & scol(2);
contador <= U0L;
when deteccionFilaCol =>
case fila is
when "0111" => nfila <= U0;
when "1011" => nfila <= U1;
when "1101" => nfila <= U2;
when "1110" => nfila <= U3;
when others => nfila <= U10;
end case;
case scol is
when "011" => scol4 <= U0;
when "101" => scol4 <= U1;
when "110" => scol4 <= U2;
when others => scol4 <= U0;
end case;
when deteccionTecla =>
if fila(3)='0' then
tecla <= U0;
else
tecla <= scol4 + U1 + multi(3 downto 0);
end if;
when mostrar =>
case tecla is
when U11 => seg7 <= "1111001"; -- 1 working
when U8 => seg7 <= "0011001"; -- 4 working
when U5 => seg7 <= "0111000"; -- 7 working
when U12 => seg7 <= "0110000"; -- 3
when U7 => seg7 <= "0010010"; -- 5 working
when U4 => seg7 <= "0000000"; -- 8 working
When U10 => seg7 <= "0100100"; -- 2 working
--When U3 => seg7 <= "1110000"; -- no se
when U9 => seg7 <= "0000010"; -- 6 working
when U6 => seg7 <= "0011000"; -- 9 working
when others => seg7 <= "1000000"; -- *, #
end case;
end case;
end if;
end process;
-- registro de estado
process(clk, reset)
begin
if (reset = '1') then
estadoActual <= reposo;
elsif (clk'event and clk = '1') then
estadoActual <= estadoSiguiente;
end if;
end process;
process (estadoActual,fila,contador) is
begin
case estadoActual is
when reposo => estadoSiguiente <= inicio;
when inicio => estadoSiguiente <= cuenta;
when cuenta =>
if contador = "111111111111111111111111" then
estadoSiguiente <= rotacion;
else
estadoSiguiente <= cuenta;
end if;
when rotacion =>
if (fila = "1111") then
estadoSiguiente <= cuenta;
else
estadoSiguiente <= deteccionFilaCol;
end if;
when deteccionFilaCol =>
estadoSiguiente <= deteccionTecla;
when deteccionTecla =>
estadoSiguiente <= mostrar;
when mostrar =>
estadoSiguiente <= inicio;
end case;
end process;
end division;
- Programación en .xdc (constrains)
set_property IOSTANDARD LVCMOS33 [get_ports clk]
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]
# Mapear RESET a BTND
set_property LOC V10 [get_ports reset]
set_property IOSTANDARD LVCMOS33 [get_ports reset]
set_property PACKAGE_PIN B13 [get_ports {col[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[0]}]
set_property PACKAGE_PIN F14 [get_ports {col[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[1]}]
set_property PACKAGE_PIN D17 [get_ports {col[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[2]}]
set_property PACKAGE_PIN G13 [get_ports {fila[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fila[0]}]
set_property PACKAGE_PIN C17 [get_ports {fila[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fila[1]}]
set_property PACKAGE_PIN D18 [get_ports {fila[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fila[2]}]
set_property PACKAGE_PIN E18 [get_ports {fila[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fila[3]}]
set_property PACKAGE_PIN L3 [get_ports {seg7[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[0]}]
set_property PACKAGE_PIN N1 [get_ports {seg7[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[1]}]
set_property PACKAGE_PIN L5 [get_ports {seg7[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[2]}]
#set_property SEVERITY {warning} [get_drc_checks NSTD-1]
#set_property SEVERITY {warning} [get_drc_checks UCIO-1]
set_property PACKAGE_PIN L4 [get_ports {seg7[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[3]}]
set_property PACKAGE_PIN K3 [get_ports {seg7[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[4]}]
set_property PACKAGE_PIN M2 [get_ports {seg7[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[5]}]
set_property PACKAGE_PIN L6 [get_ports {seg7[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[6]}]
set_property PACKAGE_PIN N6 [get_ports {display[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {display[0]}]
set_property PACKAGE_PIN M6 [get_ports {display[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {display[1]}]
set_property PACKAGE_PIN M3 [get_ports {display[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {display[2]}]
set_property PACKAGE_PIN N5 [get_ports {display[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {display[3]}]
set_property PACKAGE_PIN N2 [get_ports {display[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {display[4]}]
set_property PACKAGE_PIN N4 [get_ports {display[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {display[5]}]
set_property PACKAGE_PIN L1 [get_ports {display[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {display[6]}]
set_property PACKAGE_PIN M1 [get_ports {display[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {display[7]}]
set_property PACKAGE_PIN T8 [get_ports {ledcol[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledcol[0]}]
set_property PACKAGE_PIN V9 [get_ports {ledcol[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledcol[1]}]
set_property PACKAGE_PIN R8 [get_ports {ledcol[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledcol[2]}]
set_property PACKAGE_PIN T6 [get_ports {ledcol[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledcol[3]}]
set_property PACKAGE_PIN P2 [get_ports {ledfila[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledfila[0]}]
set_property PACKAGE_PIN R2 [get_ports {ledfila[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledfila[1]}]
set_property PACKAGE_PIN U1 [get_ports {ledfila[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledfila[2]}]
set_property PACKAGE_PIN P5 [get_ports {ledfila[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledfila[3]}]
Paso 6 funcionamiento en la FPGA
1. http://mrelbernitutoriales.com/teclado/
2. https://programacionsiemens.com/display-de-7-segmentos-step-7/
DESCARGAS: https://mega.nz/#!CZVGhKCY!vP5DViGqmQFIODJtvkXr_XhPGExSpHHd-t3wBqiZW5w
No hay comentarios:
Publicar un comentario