Controlador de pantalla dual VHDL de 7 segmentos para Pmod SSD:fácil integración con FPGA
En este artículo, presentaré un módulo VHDL que puede mostrar un número de dos dígitos en el Pmod SSD:pantalla de siete segmentos de Digilent. La pantalla dual de 7 segmentos es compatible con la interfaz Pmod, lo que significa que puede usarla sin necesidad de soldadura. Encaja en el conector Pmod, que es estándar en muchas placas de desarrollo FPGA.
Para probar la implementación de VHDL, estoy usando Lattice iCEstick, una placa de desarrollo FPGA de bajo costo con un conector Pmod. Además del iCEstick, necesita un cable divisor Pmod de 2 × 6 pines a doble de 6 pines para convertir del conector Pmod paralelo en el iCEstick a la versión en serie del enchufe que espera la pantalla de 7 segmentos. Finalmente, recomiendo adquirir un cable de extensión USB tipo A porque no es práctico conectar el iCEstick directamente al puerto USB de la computadora.
Cómo funcionan las pantallas de 7 segmentos
Hay muchos displays de 7 segmentos diferentes en el mercado. La cantidad de dígitos varía entre ellos, al igual que la interfaz física y la distribución de pines. Una solución genérica que cubra todas las posibles pantallas de 7 segmentos que pueda encontrar probablemente no sería muy fácil de usar. Sin embargo, puede utilizar el código presentado en este artículo como base y modificarlo para adaptarlo a sus necesidades.
La imagen de arriba es de la hoja de datos del módulo Digilent Pmod. Muestra cómo la pantalla de 7 segmentos se conecta a los pines Pmod. Estos pines son directamente accesibles al FPGA en el iCEstick.
Siete de los pines controlan un segmento cada uno en la pantalla. Al aplicar un valor lógico alto en dicho pin, el segmento correspondiente se iluminará en la pantalla. Pero hay dos dígitos en esta pantalla y solo podemos controlar uno a la vez. El pin P4/C del conector J2 selecciona uno u otro dígito. Cuando el voltaje lógico en este pin es '0' , el dígito derecho se ilumina, si es '1' , el dígito izquierdo se activa.
El punto decimal "DP" no está conectado y no se puede acceder a él.
La entidad
El siguiente código muestra la entidad de nuestro módulo VHDL seg7. La entidad tiene un puerto genérico con una constante llamada clk_cnt_bits . Define la longitud de un contador interno que controla la frecuencia de actualización de la pantalla, la frecuencia de alternancia entre los dígitos izquierdo y derecho.
La frecuencia exacta no es esencial. Seleccione una longitud de contador que se encuentre en el rango de 50 a un par de cientos de Hercios. La fórmula que determina la frecuencia de actualización es refresh_hz =2clk_cnt_bits / clk_hz .
entity seg7 is generic ( -- refresh_hz = (2 ** clk_cnt_bits) / clk_hz clk_cnt_bits : integer ); port ( clk : in std_logic; rst : in std_logic; value : in integer range 0 to 99; segments : out std_logic_vector(6 downto 0); digit_sel : out std_logic ); end seg7;
Además del reloj y el reinicio, la entidad tiene una señal de entrada:el valor a mostrar en la pantalla de 7 segmentos. El value La señal es un tipo de número entero restringido al rango de 0 a 99 porque estos son los únicos valores numéricos que es posible mostrar usando solo dos dígitos.
Las señales de salida son los siete segmentos como un vector y la señal del selector de dígitos para elegir el dígito izquierdo o derecho para iluminar.
Representando un decimal codificado en binario
Para representar los dígitos que se muestran en la pantalla utilizaremos el formato conocido como decimal codificado en binario (BCD). Si bien una representación binaria es la forma más eficiente de almacenar el número decimal, tenemos problemas al intentar dividirlo en los dígitos izquierdo y derecho para mostrarlo en la pantalla. No podemos distinguir entre los dígitos decimales simplemente cortando el vector utilizado para almacenar el número.
subtype digit_type is integer range 0 to 9; type digits_type is array (1 downto 0) of digit_type; signal digit : digit_type; signal digits : digits_type;
Como se muestra en el código anterior, declaramos un subtipo de número entero en el rango de 0 a 9 para describir el valor que puede representarse con un dígito decimal. Luego, declaramos un nuevo tipo de matriz que puede contener dos de esos valores BCD. El digit La señal contiene el número que se muestra actualmente en el lado izquierdo o derecho de la pantalla. Por otro lado, el digits La señal contiene los caracteres decimales individuales para los dos dígitos, tal como aparecerán ante una persona que vea la pantalla.
Convertir decimal a BCD
La entrada a este módulo, value , es un número entero en el rango de 0 a 99, una representación binaria del número. Necesitamos convertir este único número entero en dos números enteros en el rango de 0 a 9, los BCD.
El algoritmo estándar para esto es Double Dabble, también conocido como shift-and-add-3. algoritmo. Si bien esto está bien de usar, optaré por una solución más corta en nuestro caso porque solo tenemos dos dígitos para separar.
digits(1) <= value / 10; digits(0) <= value - ((value / 10) * 10);
Al usar la división de enteros como se muestra en el código anterior, podemos aislar el dígito decimal más significativo y asignarlo al digits(1). señal. Para obtener el dígito menos significativo, podemos restar el dígito más significativo del value señal, dejándonos solo con el número para asignar al digits(0) señal.
Contando ciclos de reloj
Retrasar el tiempo en FPGA es simplemente una cuestión de contar ciclos de reloj. El período de reloj es el único intervalo de tiempo predecible en el que puede confiar en su código VHDL. El siguiente código muestra el clk_count señal, que estamos usando para contar ciclos de reloj. El clk_cnt_bits genérico determina cuántos bits reservar para esta señal sin firmar.
signal clk_cnt : unsigned(clk_cnt_bits - 1 downto 0);
La frecuencia de actualización exacta de la pantalla tiene menos importancia, por eso he optado por un tipo sin firmar aquí. Nos permite utilizar el comportamiento de autoenvoltura de la señal sin firmar. Todo lo que tenemos que hacer es incrementar el contador en cada flanco ascendente del reloj. El siguiente código muestra el proceso sincrónico con reinicio que se encarga de esto.
COUNT_PROC : process(clk) begin if rising_edge(clk) then if rst = '1' then clk_cnt <= (others => '0'); else clk_cnt <= clk_cnt + 1; end if; end if; end process;
Alternar entre dígitos
Ahora que tenemos el contador libre funcionando, podemos usar el bit más significativo (MSB) de la señal del contador sin signo para cambiar entre los dos dígitos. El MSB alterna entre '0' y '1' con un ciclo de trabajo del 50%. La primera línea del código siguiente establece el digit_sel señal basada en el valor del MSB. La segunda línea implementa un multiplexor con el MSB utilizado como selector. Reenviará el valor del dígito activo desde el digits matriz al digit señal.
digit_sel <= clk_cnt(clk_cnt'high); digit <= digits(0) when clk_cnt(clk_cnt'high) = '0' else digits(1);
Codificador BCD a 7 segmentos
El último paso del módulo seg7 es traducir el BCD almacenado en el digit señal a una representación visual en la pantalla de 7 segmentos. El siguiente código muestra un proceso que logra esto mediante el uso de una declaración de caso.
La posición en el vector de cada bit literal corresponde a un segmento en la pantalla. El índice 0 es igual al segmento A, el índice 1 es B, y así sucesivamente, hasta llegar al índice 6, que controla el segmento G. Las asignaciones de segmentos a índices vectoriales se derivan de la hoja de datos de la pantalla de 7 segmentos de Digilent.
ENCODER_PROC : process(digit) begin case digit is when 0 => segments <= "0111111"; when 1 => segments <= "0000110"; when 2 => segments <= "1011011"; when 3 => segments <= "1001111"; when 4 => segments <= "1100110"; when 5 => segments <= "1101101"; when 6 => segments <= "1111101"; when 7 => segments <= "0000111"; when 8 => segments <= "1111111"; when 9 => segments <= "1101111"; end case; end process;
La salida
El módulo VHDL seg7 mostrará en la pantalla todo lo que usted asigne al value señal de entrada. En el banco de pruebas, incrementamos el value señal una vez por segundo. Luego, simulamos un poco más de 100 segundos para que podamos observar el punto de envoltura del value. contador.
La forma de onda de arriba es de ModelSim. Muestra la primera parte de la simulación, donde el valor ha contado del 0 al 15. Podemos ver que los números en el digits La matriz también está contando. Los (0) estamos contando cada vez que el value la señal cambia, mientras que las decenas (1) incremento cada décimo número.
Puede descargar el proyecto ModelSim, incluido el banco de pruebas, utilizando el siguiente formulario.
Si implementa el módulo seg7 como módulo superior en la FPGA, lo más probable es que la pantalla muestre un “00” estable. Eso es porque '0' es el valor predeterminado más común dado a señales no inicializadas en FPGA. Cuando el value la señal se establece en ceros, la pantalla mostrará precisamente eso.
Para recorrer todos los números de entrada posibles, creé un módulo VHDL contenedor que incrementa el value señal diez veces por segundo. Luego creé una instancia del módulo seg7 en el contenedor antes de implementar el diseño en Lattice iCEstick. El siguiente vídeo Gif en bucle muestra cómo se ve el diseño implementado en la pantalla de 7 segmentos.
Compra del SSD Pmod:pantalla de siete segmentos
La pantalla de 7 segmentos utilizada en esta publicación de blog proviene de Digilent. Puede comprar el módulo Pmod en la tienda web de Digilent o puede obtenerlo de uno de los muchos revendedores. En la lista a continuación, he vinculado la página del producto para exhibirlo en algunas tiendas de electrónica en línea que venden el artículo.
- Digilent
- Digi-Key
- Ratón
- RS Electronics (Reino Unido)
(Vaya a la página principal de RS Electronics para seleccionar el sitio correspondiente a su país) - Farnell (Reino Unido)
(Vaya a la página principal de Farnell para seleccionar el sitio para su país)
Tenga en cuenta que si desea utilizar la pantalla Digilent de 7 segmentos con el Lattice iCEstick , o cualquier otra placa de desarrollo FPGA que tenga un conector Pmod de 6×2 pines, también necesitará un cable divisor. El cable está disponible en Digilent , Digi-key , Ratón y RS Electrónica .
Además, todos los componentes están disponibles a través de varios vendedores en Amazon y eBay.
Curso VHDL utilizando la pantalla de 7 segmentos Digilent
Lancé un nuevo curso de VHDL y FPGA para principiantes absolutos. En el curso, utilizo la pantalla de 7 segmentos de Digilent y la placa de desarrollo FPGA Lattice iCEstick para enseñar VHDL. ¡Haga clic en el enlace a continuación para leer más sobre el curso!
Vía rápida de FPGA y VHDL:
Práctica para principiantes absolutos
¿Está familiarizado con la programación pero es nuevo en VHDL?
¿Necesita una breve introducción a este tema desconocido?
¿Tu agenda está llena y no te queda tiempo para estudiar?
¡Comprenda los conceptos básicos del desarrollo de FPGA usando VHDL en unas pocas noches! Este curso es para profesionales de TI y estudiantes que necesitan un rápido resumen del tema. Con este curso y la placa de desarrollo Lattice iCEstick de bajo costo, estarás desarrollando hardware real en cuestión de horas.
Haga clic aquí para leer más e inscribirse:
FPGA y VHDL Fast-Track:práctica para principiantes absolutos
VHDL
- Cómo generar números aleatorios en VHDL
- Cómo usar Loop y Exit en VHDL
- Generar ejemplo de inhibidor de extractos
- Cómo usar sentencias condicionales en VHDL:If-Then-Elsif-Else
- Cómo usar un For-Loop en VHDL
- Banco de pruebas interactivo usando Tcl
- Firmado vs. Sin firmar en VHDL
- Curso FPGA – Todo lo que necesitas saber sobre el Curso Dot Matrix VHDL
- Una introducción a los FPGA y la lógica programable
- Archivo de estímulo leído en el banco de pruebas usando TEXTIO
- Cómo usar un procedimiento en VHDL