Conversor ADC não apresenta valor certo, em 7 de segmento FPGA
-
21-12-2019 - |
Pergunta
Eu estou escrevendo um código VHDL que permite conectar ADC7475 (12 bits com 4 zeros à esquerda(total de 16 bits) para a placa FPGA.O meu objectivo é apresentar o valor de saída digital do ADC em 7 de segmento quando fornecer sinal analógico (Vin pin da ADC).Aqui é o meu programa:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
-----Interface-----
entity interface is port (
clk : in std_logic;
rst : in std_logic;
cs : out std_logic;
sclk : out std_logic;
digital_sig_in : in bit;
digital_sig_out: out integer);
end interface;
architecture Behavior of interface is
signal outclk : std_logic;
signal int_cs : std_logic;
signal counter1 : integer range 0 to 500 :=1;
signal counter2 : integer range 0 to 50 :=0;
signal cnt : integer range 0 to 50 :=0;
signal data_vector : std_logic_vector(15 downto 0) :="0000000000000000";
begin
process(clk, rst) --Clock generation clk=50Mhz -> sclk=50Khz
begin
if (rst='1') then
counter1 <= 0;
outclk <= '0';
elsif (clk = '1' and clk'event) then
counter1 <= counter1 + 1;
if (counter1 = 500) then
counter1 <= 0;
outclk <= not outclk;
end if;
end if;
end process;
sclk <= outclk;
process (outclk, rst) --CS generation
begin
if (rst='1') then
counter2 <= 0;
int_cs <='1';
elsif (outclk = '0' and outclk'event) then
counter2 <= counter2 + 1;
if (counter2 = 15) then
int_cs <= not int_cs;
counter2 <= 0;
cs <= int_cs;
end if;
end if;
end process;
process (outclk, int_cs, rst) --Serial signal assigning
variable i : integer range 15 downto 0 :=0;
variable data_temp : bit_vector(15 downto 0);
begin
if (rst = '1') then
i := 0;
data_temp := "0000000000000000";
elsif (int_cs = '0') then
if (outclk = '0' and outclk'event) then
i := i+1;
data_temp(15 downto 0) := digital_sig_in&data_temp(15 downto 1);
if (i=15) then
data_vector <= to_stdlogicvector(data_temp);
end if;
end if;
end if;
digital_sig_out <= conv_integer(data_vector);
end process;
end Behavior;
-----Segment-----
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity segment is port (
clk, rst: in std_logic;
data_in : in integer;
sel : out std_logic_vector(3 downto 0);
fnd : out std_logic_vector(7 downto 0));
end segment;
architecture Behavior of segment is
signal counter1: integer range 0 to 1500 :=0;
signal counter : integer range 0 to 3 :=0;
signal outclk : std_logic;
signal fnd_1,fnd_2,fnd_3,fnd_4 : std_logic_vector(7 downto 0);
function fnd_seg(num: integer range 0 to 9) return std_logic_vector is
begin
case num is
when 0 => return "11111100";
when 1 => return "01100000";
when 2 => return "11011010";
when 3 => return "11110010";
when 4 => return "01100110";
when 5 => return "10110110";
when 6 => return "10111110";
when 7 => return "11100100";
when 8 => return "11111110";
when 9 => return "11110110";
when others => return "11111100";
end case;
return "00000000";
end;
begin
fnd_1 <= fnd_seg((data_in/1000 ) mod 10);
fnd_2 <= fnd_seg((data_in/100) mod 10);
fnd_3 <= fnd_seg((data_in/10) mod 10);
fnd_4 <= fnd_seg(data_in mod 10);
clk_gen : process(clk, rst)
begin
if (rst='1') then
counter1 <= 0;
outclk <= '0';
elsif (clk = '1' and clk'event) then
if (counter1 >= 1000) then
counter1 <= 0;
outclk <= not outclk;
else
counter1 <= counter1 + 1;
outclk <= '0';
end if;
end if;
end process clk_gen;
fndsel : process(outclk, rst)
begin
if (rst='1') then
sel <= (others => '0');
fnd <= (others => '1');
elsif (outclk = '1' and outclk'event) then
counter <= counter + 1;
case counter is
when 0 => sel <="0111"; fnd <= fnd_1;
when 1 => sel <="1011"; fnd <= fnd_2;
when 2 => sel <="1101"; fnd <= fnd_3;
when others => sel <="1110"; fnd <= fnd_4;
end case;
end if;
end process fndsel;
end Behavior;
-----Top-Level Entity-----
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity adc is port (
--interface--
clk : in std_logic;
rst : in std_logic;
cs : out std_logic;
sclk : out std_logic;
digital_sig_in : in bit;
digital_sig_out: out integer;
--segment--
data_in: in integer;
sel : out std_logic_vector(3 downto 0);
fnd : out std_logic_vector(7 downto 0));
end adc;
architecture Behavior of adc is
signal data_temp: integer;
component interface
port (
clk : in std_logic;
rst : in std_logic;
cs : out std_logic;
sclk : out std_logic;
digital_sig_in : in bit;
digital_sig_out: out integer);
end component;
component segment
port(
clk : in std_logic;
rst : in std_logic;
data_in: in integer;
sel : out std_logic_vector(3 downto 0);
fnd : out std_logic_vector(7 downto 0));
end component;
begin
U0 : interface port map (clk, rst, cs, sclk, digital_sig_in, data_temp);
U1 : segment port map (clk, rst, data_temp, sel, fnd);
end Behavior;
Não há nenhum erro, mas o meu de 7 segmentos não mostrar qualquer valor.Ele pisca em todos os segmentos.Eu tentei testar o meu segmento de entidade separadamente, ele funciona bem.Então eu acho que existe algum problema com a minha "Série do sinal de atribuição" no processo de interface entidade.O relógio do chip e selecione o sinal de saída (sclk e cs) são verificados pelo osciloscópio, eles estão corretos também.
O que é problema com o meu programa?Todas as opiniões são bem-vindos!Obrigado.
Solução
Tenho a certeza que você misturou-se algo com relógios.É de 50 kHz relógio para contar o valor?Se você estiver fazendo SSD contador (por exemplo, de 0 a 99), intermitente pode ser causado pelo fato de que você está atualizando-o muito rápido e o olho não pode pegá-lo para cima.Eu já tive problema semelhante e eu fiz a atualização mais lenta.