Le convertisseur ADC n'affiche pas la valeur correcte sur 7 FPGA de segment
-
21-12-2019 - |
Question
im écrit un code VHDL qui permet de connecter ADC7475 (12 bits avec 4 zéros de premier plan (total 16 bits)) au tableau FPGA.Ma cible affiche la valeur de sortie numérique de l'ADC sur 7 segment lors de la fourniture de signal analogique (PIN VIN de ADC).Voici mon programme:
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;
Il n'y a pas d'erreur mais mon 7 segment ne montre aucune valeur.Il clignote sur tout le segment.J'ai essayé de tester mon entité de segment séparément, cela fonctionne bien.Donc, je suppose qu'il y a un problème avec mon processus "Signal Serial Attribution" dans l'entité d'interface.L'horloge et la puce Sélectionnez le signal (SCLK et CS) sont vérifiés par oscilloscope, ils sont également corrects.
Quel est le problème avec mon programme?Toutes les opinions sont appréciées!Merci.
La solution
Je suis sûr que vous avez mélangé quelque chose avec des horloges.Est-ce que 50 kHz est fait pour compter la valeur?Si vous créez un compteur SSD (par exemple, de 0 à 99), il est préférable de clignoter par le fait que vous mettez la mise à jour trop rapide et que votre œil ne peut pas l'attraper.J'ai eu un problème similaire et je viens de la mettre à jour plus lentement.