Problemas con el controlador de pantalla de 7 segmentos

Tengo este código para conducir una pantalla de siete segmentos para hexadecimal. Según tengo entendido, es lógicamente correcto, pero cuando intento ejecutarlo en mi placa Nexsys 3, nunca obtengo el resultado correcto, parece que los segmentos casi se ejecutan juntos cuando lo ejecuto (es decir, aparece lo mismo en todos o algunos de ellos y todo el segmento siempre están iluminados al menos parcialmente, mientras que los segmentos correspondientes a la pantalla correcta solo tienen una mayor intensidad).

a continuación está mi código

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_unsigned.ALL;

    -- Uncomment the following library declaration if using
    -- arithmetic functions with Signed or Unsigned values
    use IEEE.NUMERIC_STD.ALL;

    -- Uncomment the following library declaration if instantiating
    -- any Xilinx primitives in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;

    entity SSD_driver is
         Port ( hex0 : in  STD_LOGIC_VECTOR (3 downto 0);
                  hex1 : in  STD_LOGIC_VECTOR (3 downto 0);
                  hex2 : in  STD_LOGIC_VECTOR (3 downto 0);
                  hex3 : in  STD_LOGIC_VECTOR (3 downto 0);
                  clock : in  STD_LOGIC;
                  reset : in  STD_LOGIC;
                  SEG : out  STD_LOGIC_VECTOR (7 downto 0);
                  AN : out  STD_LOGIC_VECTOR (3 downto 0));
    end SSD_driver;

    architecture Behavioral of SSD_driver is
    signal count : std_logic_vector(15 downto 0):=(others=>'0');
    signal mux_sel: std_logic_vector(1 downto 0):=(others=>'0');
    signal mux_out: std_logic_vector(3 downto 0):=(others=>'0');
    signal dec_out: std_logic_vector(3 downto 0):=(others=>'0');
    signal OC: std_logic_vector(3 downto 0):=(others=>'0');
    signal SS_cathode:STD_LOGIC_VECTOR(7 downto 0):=(others=>'0');

    begin
    counter:    process(clock,reset)
                    begin
                        if reset = '1' then
                            count<=(others=>'0');
                        else
                            if rising_edge(clock) then
                                count<=count+1;
                            end if;
                        end if;
                end process counter;
    mux_sel<=count(15 downto 14);

    with mux_sel select
        mux_out<=hex0 when "00",
                    hex1 when "01",
                    hex2 when "10",
                    hex3 when "11",
                    "0000" when others;

    with mux_sel select
        dec_out<="0001" when "00",
                    "0010" when "01",
                    "0100" when "10",
                    "1000" when "11",
                    "0000" when others;


    with mux_out select
        SS_cathode(7 downto 0) <=   x"C0" when "0000", -- 0
                                            x"F9" when "0001", -- 1
                                            x"A4" when "0010", -- 2
                                            x"B0" when "0011", -- 3
                                            x"99" when "0100", -- 4
                                            x"92" when "0101", -- 5
                                            x"82" when "0110", -- 6
                                            x"F8" when "0111", -- 7
                                            x"80" when "1000", -- 8
                                            x"90" when "1001", -- 9
                                            x"88" when "1010", -- a
                                            x"83" when "1011", -- b
                                            x"C6" when "1100", -- c
                                            x"A1" when "1101", -- d
                                            x"86" when "1110", -- e
                                            x"8E" when others; -- f

    SEG<=SS_cathode;
    AN<=not(dec_out);

    end Behavioral;

Cualquier ayuda sería apreciada, gracias de antemano!

¿Qué tan rápida es la frecuencia de actualización? ¿Podría ser que te estás refrescando tan rápido que es solo un borrón para el ojo humano?
actualmente se está actualizando tan rápido como el reloj, así que alrededor de 100 MHz. Supongo que es un poco demasiado rápido ahora que lo pienso.
¿Estás contando y mostrando?
@ScottCarlson Probablemente esté excediendo el tiempo de conmutación del transistor. Entonces, la pantalla anterior todavía está encendida cuando pasa a la siguiente.
hmm ok, lo intentaré, hice una búsqueda rápida en google y descubrí que la velocidad óptima para la mayoría de las placas es de alrededor de 60 hz a 1 khz, así que lo intentaré y te lo haré saber, ¡gracias!
Si de hecho está usando transistores para encender los segmentos, Gleison Sorto también dio un punto válido.
Me encontré con un problema similar con los retrasos de los transistores. Modifiqué mi enfoque, así que solo conduje los ánodos la mitad del tiempo. Uso lo siguiente para cada segmento por turno: {Activar valor de datos y Activar un segmento; mantener el valor de los datos y apagar todos los segmentos;} ';' separa los ciclos del reloj.
Entonces, ¿encontraste cuál era el problema?
Lo hice, iggy, tenías razón al sugerir investigar la frecuencia de actualización, eso solucionó el problema. ¡Gracias por la ayuda! Lo cambié a 100hz y no tengo problemas.

Respuestas (1)

Obviamente, resolvió su problema a través de los comentarios, pero para aquellos que encuentren esta pregunta en el futuro, la respuesta se encuentra en la hoja de datos de Nexys. En resumen, sí, los dígitos de visualización de 7 segmentos están multiplexados y, como tales, hay un tiempo de configuración y espera cuando se interactúa con esos transistores de ánodo/cátodo comunes.

En este caso, sin embargo, debe cambiar entre ellos lo suficientemente lento para que nuestros ojos humanos vean la luz, pero lo suficientemente rápido para que no haya parpadeo. Piense en PWM: si está cambiando entre dígitos demasiado rápido, la luz será tenue.

La hoja de datos de Digilent para la placa Nexys responde exactamente a esta pregunta. Consulte la sección 9.1 que habla sobre la interfaz con la pantalla de siete segmentos. En particular...

Cada dígito se ilumina solo una cuarta parte del tiempo, pero debido a que el ojo no puede percibir el oscurecimiento de un dígito antes de que se ilumine nuevamente, el dígito aparece continuamente iluminado. Si la tasa de actualización o "refresco" se reduce a alrededor de 45 hercios, la mayoría de las personas comenzarán a ver que la pantalla parpadea.

Para que cada uno de los cuatro dígitos aparezca brillante y continuamente iluminado, los cuatro dígitos deben activarse una vez cada 1 a 16 ms, para una frecuencia de actualización de 1 KHz a 60 Hz. Por ejemplo, en un esquema de actualización de 60 Hz, toda la pantalla se actualizaría una vez cada 16 ms, y cada dígito se iluminaría durante ¼ del ciclo de actualización, o 4 ms. El controlador debe impulsar los cátodos con el patrón correcto cuando se impulsa la señal de ánodo correspondiente. Para ilustrar el proceso, si se afirma AN0 mientras se afirman CB y CC, aparecerá un "1" en la posición de dígito 1. Luego, si se afirma AN1 mientras se afirman CA, CB y CC, aparecerá un "7". se mostrará en la posición de dígito 2. Si AN0 y CB, CC se activan durante 4 ms, y luego A1 y CA, CB, CC se activan durante 4 ms en una sucesión sin fin, la pantalla mostrará "17". en los dos primeros dígitos. Se proporciona un diagrama de tiempo de ejemplo para un controlador de cuatro dígitos.

Diagrama de tiempo de siete segmentos.  Misma fuente, abajo

Fuente: "Manual de referencia de la placa FPGA Nexys 3". Digilent Incorporated. 11 de abril de 2016. pág. 19. PDF.

Ahí vas.