Visualización multiplex de siete segmentos Lo suficientemente rápido como para que quede sólido

3

He estado tratando de multiplexar una pantalla de siete dígitos de siete segmentos en mi placa FPGA, pero me he estado ejecutando para no obtenerla lo suficientemente rápido para que se vea sólido al ojo humano.

Puede ver un ejemplo de la velocidad aquí: enlace

¿Cómo se multiplexa lo suficientemente rápido para que se vea sólido al ojo humano?

Estoy usando la placa Basys 2 .

Ahora mismo mi VHDL parece:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity main is
    port(
        clock       : in STD_LOGIC;
        sevenseg    : out STD_LOGIC_VECTOR(6 downto 0);
        anodes  : out STD_LOGIC_VECTOR(3 downto 0);
        switches    : in STD_LOGIC_VECTOR(6 downto 0);
        dp      : in STD_LOGIC
    );
end main;

architecture Behavioral of main is
    signal counter: STD_LOGIC_VECTOR(1 downto 0) := (others => '0');
    signal r_anodes: STD_LOGIC_VECTOR(3 downto 0);
begin

    anodes <= r_anodes;

    -- Given Binary Value print it
    multiplex: process(counter, switches)
    begin
        -- Set anode correctly
        case counter(1 downto 0) is
            when "00" => r_anodes <= "1110"; -- AN 0
            when "01" => r_anodes <= "1101"; -- AN 1
            when "10" => r_anodes <= "1011"; -- AN 2
            when "11" => r_anodes <= "0111"; -- AN 3

            when others => r_anodes <= "1111"; -- nothing
        end case;

        -- Set segments correctly
        case r_anodes is
            when "1110" => 
                if switches(0) = '1' then
                    sevenseg <= "1111001"; -- 1
                else
                    sevenseg <= "1000000"; -- 0
                end if;
            when "1101" => 
                if switches(1) = '1' then
                    sevenseg <= "1111001"; -- 1
                else
                    sevenseg <= "1000000"; -- 0
                end if;
            when "1011" => 
                if switches(2) = '1' then
                    sevenseg <= "1111001"; -- 1
                else
                    sevenseg <= "1000000"; -- 0
                end if;
            when "0111" => 
                if switches(3) = '1' then
                    sevenseg <= "1111001"; -- 1
                else
                    sevenseg <= "1000000"; -- 0
                end if;

            when others => sevenseg <= "1111111"; -- nothing
        end case;

    end process;

    countClock: process(clock, counter)
    begin
        if rising_edge(clock) then
            -- Iterate
            counter <= counter + 1;
        end if;
    end process;


end Behavioral;

Y mi archivo de restricciones se ve como:

NET "sevenseg<0>" LOC = "L14";
NET "sevenseg<1>" LOC = "H12";
NET "sevenseg<2>" LOC = "N14";
NET "sevenseg<3>" LOC = "N11";
NET "sevenseg<4>" LOC = "P12";
NET "sevenseg<5>" LOC = "L13";
NET "sevenseg<6>" LOC = "M12";
NET "dp" LOC = "N13";

NET "anodes<3>" LOC = "K14";
NET "anodes<2>" LOC = "M13";
NET "anodes<1>" LOC = "J12";
NET "anodes<0>" LOC = "F12";

NET "switches<6>" LOC = "E2";
NET "switches<5>" LOC = "F3";
NET "switches<4>" LOC = "G3";
NET "switches<3>" LOC = "B4";
NET "switches<2>" LOC = "K3";
NET "switches<1>" LOC = "L3";
NET "switches<0>" LOC = "P11";

NET "clock" TNM_NET = clock;
TIMESPEC TS_clock = PERIOD "clock" 20 ns HIGH 50%;
    
pregunta MLM

1 respuesta

3

Gracias, Dave Tweed por encontrar mi pequeño error.

Olvidé agregar el "LOC" en el archivo de restricciones.

NET "clock" LOC = "B8";

También tuve algunos problemas de ancho de pulso (segmentos parcialmente activados) con los 50 MHz completos, como también mencionó Dave Tweed. Así que utilicé un prescaler para devolver el tono a 500 Hz.

Dividir un reloj de 50 Mhz por 100,000 (base 10) o 11000011010100000 (binario)

El código final se ve así:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity main is
    port(
        clock       : in STD_LOGIC;
        sevenseg    : out STD_LOGIC_VECTOR(6 downto 0);
        anodes  : out STD_LOGIC_VECTOR(3 downto 0);
        switches    : in STD_LOGIC_VECTOR(6 downto 0);
        dp      : in STD_LOGIC
    );
end main;

architecture Behavioral of main is
    signal prescaler: STD_LOGIC_VECTOR(16 downto 0) := "11000011010100000";
    signal prescaler_counter: STD_LOGIC_VECTOR(16 downto 0) := (others => '0');
    signal counter: STD_LOGIC_VECTOR(1 downto 0) := (others => '0');
    signal r_anodes: STD_LOGIC_VECTOR(3 downto 0);
begin

    anodes <= r_anodes;

    -- Given Binary Value print it
    multiplex: process(counter, switches)
    begin
        -- Set anode correctly
        case counter(1 downto 0) is
            when "00" => r_anodes <= "1110"; -- AN 0
            when "01" => r_anodes <= "1101"; -- AN 1
            when "10" => r_anodes <= "1011"; -- AN 2
            when "11" => r_anodes <= "0111"; -- AN 3

            when others => r_anodes <= "1111"; -- nothing
        end case;

        -- Set segments correctly
        case r_anodes is
            when "1110" => 
                if switches(0) = '1' then
                    sevenseg <= "1111001"; -- 1
                else
                    sevenseg <= "1000000"; -- 0
                end if;
            when "1101" => 
                if switches(1) = '1' then
                    sevenseg <= "1111001"; -- 1
                else
                    sevenseg <= "1000000"; -- 0
                end if;
            when "1011" => 
                if switches(2) = '1' then
                    sevenseg <= "1111001"; -- 1
                else
                    sevenseg <= "1000000"; -- 0
                end if;
            when "0111" => 
                if switches(3) = '1' then
                    sevenseg <= "1111001"; -- 1
                else
                    sevenseg <= "1000000"; -- 0
                end if;

            when others => sevenseg <= "1111111"; -- nothing
        end case;

    end process;

    countClock: process(clock, counter)
    begin
        if rising_edge(clock) then
            prescaler_counter <= prescaler_counter + 1;
            if(prescaler_counter = prescaler) then
                -- Iterate
                counter <= counter + 1;

                prescaler_counter <= (others => '0');
            end if;
        end if;
    end process;


end Behavioral;
    
respondido por el MLM

Lea otras preguntas en las etiquetas