Cuando un diseño utiliza más de un display de siete segmentos es interesante multiplexarlos para ahorrar en conexiones. Si no lo hacemos así, para controlar cuatro displays necesitaríamos 32 conexiones al microcontrolador si es que queremos manejar directamente los displays sin ningún integrado de por medio. Vamos ver cómo funciona este multiplexado y cómo se puede implementar en una FPGA usando VHDL.
Existen dispositivos que empaquetan varios displays que son muy cómodos de usar. En este artículo, como ejemplo usaremos uno de cuatro displays. Sin embargo esta técnica puede usarse con varios displays sueltos. En el siguiente esquema se presenta la manera correcta de hacer las conexiones mediante transistores configurados en emisor común para funcionar como interruptores.

Las entradas D0 a D3 permiten seleccionar qué display queremos activar en cada momento, mientras que las entradas A a G (y DP) permiten seleccionar qué leds se han de encender para mostrar el dígito en dicho display (es decir, son comunes a los cuatro displays). ¿Esto quiere decir que, de los cuatro, sólo podemos mostrar un dígito a la vez? Efectivamente, así es. El truco está en que podemos ir activando un display tras otro de forma cíclica a una velocidad suficiente como para engañar al ojo creando la ilusión de estar viendo los cuatro dígitos al mismo tiempo. Para ello, el ciclo de refresco (el tiempo que trascurre desde que se activa el primer display hasta que se desactiva el último) ha de estar entre 1 milisegundo (incluso menos) y 16 milisegundos para que no se note ningún tipo de parpadeo. Así, en nuestro caso cada display estará activo un cuarto del tiempo completo de refresco (ya que son 4 displays).

Por lo tanto, el circuito que vamos a diseñar tiene que tener un control preciso sobre el tiempo. En el artículo anterior ya vimos como generar una señal de reloj de 1Hz a partir de un reloj de 50MHz usando un contador. En esta ocasión vamos a utilizar la misma técnica para obtener una señal para el refresco de los displays. Usando un contador para dividir los 50MHz del reloj de la placa entre 100.000 obtenemos una frecuencia de 500Hz, es decir, un periodo de 2 milisegundos. El siguiente código VHDL muestra los dígitos 0123 en el display.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity muxdisplay_top is port ( clk50mhz: in STD_LOGIC; display: out STD_LOGIC_VECTOR(6 downto 0); cur_display: out STD_LOGIC_VECTOR(3 downto 0) ); end muxdisplay_top; architecture beh of muxdisplay_top is -- 50Mzh/100000=500Hz constant max_refresh_count: INTEGER := 100000; signal refresh_count: INTEGER range 0 to max_refresh_count; signal refresh_state: STD_LOGIC_VECTOR(1 downto 0) := (others => '0'); signal display_sel: STD_LOGIC_VECTOR(3 downto 0) := (others => '0'); begin cur_display <= display_sel; gen_clock: process(clk50mhz) begin if clk50mhz'event and clk50mhz='1' then -- contador 500Hz (para refresco del display) if refresh_count < max_refresh_count then refresh_count <= refresh_count + 1; else refresh_state <= refresh_state + 1; refresh_count <= 0; end if; end if; end process; show_display: process(refresh_state) begin -- selección del display case refresh_state is when "00" => display_sel <= "1110"; -- display 0 when "01" => display_sel <= "1101"; -- display 1 when "10" => display_sel <= "1011"; -- display 2 when "11" => display_sel <= "0111"; -- display 3 when others => display_sel <= "1111"; end case; -- mostrar digitos case display_sel is when "1110" => display <= "1000000"; -- 0 when "1101" => display <= "1111001"; -- 1 when "1011" => display <= "0100100"; -- 2 when "0111" => display <= "0110000"; -- 3 when others => display <= "1111111"; end case; end process; end beh;
La señal refresh_count hace la función de contador, es decir, que se incrementa en cada ciclo de reloj y cuando llega a 100.000 se resetea y vuelve a comenzar desde 0. Cuando esto ocurre, la señal refresh_state se incrementa. Como es una señal de dos bits, puede tomar uno de los siguientes valores: 00, 01, 10, 11. Dependiendo del valor de esta señal se activará (a nivel bajo) la señal cur_display correspondiente, que se encarga de seleccionar cuál de los cuatro displays ha de activarse. Como ves, se trata de un demultiplexor de 2 a 4. El resto del código es bastante comprensible. Dependiendo del display que esté seleccionado en cada momento, se muestra un dígito u otro activando los leds correspondientes en el bus (o bundle en la jerga de VHDL) de salida llamado display.
En la siguiente imagen os dejo las conexiones que he realizado en pin planner de Quartus para la tarjeta FPGA EP1C3T144 de la que ya hablamos en otro artículo anterior.

Este es nuestro display tras configurar la FPGA con este código VHDL.

Buena explicación, y el código funciona perfecto!!!
Me gustaMe gusta
Hi Alberto
i was looking for he FPGA Board dokumentation, fort the „FPGA_NIOS KIT_Board TodayStart“ from China.
I could find a Schematic, but for the wrong board: https://skydrive.live.com/redir?resid=CB363E5D4717263F!145&authkey=!ALM9biha4hcIStw
But I could not find the correct documentation for my board.
Then I found your website, with exactly the same board as my board.
Your Website: https://www.digilogic.es/multiplexado-display-siete-segmentos/
May be you have the original documentation for this board,
And may be you could send me the documentation, or give you can give me a link to it, this would be perfect.
Best regards
Klaus Loy
Me gustaMe gusta
Hi Klaus,
The I found the info here: https://skydrive.live.com/redir?resid=CB363E5D4717263F!145&authkey=!ALM9biha4hcIStw
Regards.
Me gustaMe gusta