Hola para todos los amantes de la electronica digital.
Estoy realizando un proyecto de medicion cuyos resultados se visualizan en los display de 7 segmentos. La tarjeta que estoy usando es un Altera DE10-lite con conexiones de arduino, el sensor es un HC-SR05 de 5 pines VCC, Echo, Trig, Out(no lo uso), GND. El IDE es Quartus Prime V17.0.0 y suso el Modelsim para la simulacion. Bien dicho esto paso a indicar mis componetes.
El proyecto consta de 6 componentes, disculpen de antemano si leen algunos textos en otro idioma, es por que estoy desarrollandolo en otro idioma.
1. entity vhdl2_ingenjorsjobb : Componente que instancia a los otros componentes.
2. component trigger_cont : Es el que envia los 10ms al sensor para iniciar el echo
3. component echo_cont : Cuenta la cantidad de pulsos que demora el echo en ir y regresar.
4. component distans_raknaren : hace el calculo de la distancia.
5. component bcd_converter : convierte de binario a BCD, para visusalizarlos en el display de 7 segmentos.
6. component sju_seg_displayer : de BCD a binario para el display de 7 segmentos.
Codigo:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--use ieee.std_logic_unsigned.all;
entity vhdl2_ingenjorsjobb is
Port
(
clock_50 : in std_logic;
reset_n : in std_logic;
echo : in std_logic;
trigger : out std_logic;
hundratal : out std_logic_vector(6 downto 0);
tiotal : out std_logic_vector(6 downto 0);
ental : out std_logic_vector(6 downto 0)
);
end vhdl2_ingenjorsjobb;
architecture rtl of vhdl2_ingenjorsjobb is
component trigger_cont
port
(
clock_50 : in std_logic;
reset_n : in std_logic;
trigger : out std_logic
);
end component;
component echo_cont
port
(
clock_50 : in std_logic;
reset_n : in std_logic;
reset_echo : in std_logic;
enable_echo : in std_logic; -- kommer från top_nivå
klocks_echo : out std_logic_vector(19 downto 0)
);
end component;
component distans_raknaren
port
(
enable_echo : in std_logic;
klocks_echo : in std_logic_vector(19 downto 0);
distans : out std_logic_vector(8 downto 0)
);
end component;
component bcd_converter
port
(
distans : in std_logic_vector(8 downto 0);
hundratal: out std_logic_vector(3 downto 0);
tiotal : out std_logic_vector(3 downto 0);
ental : out std_logic_vector(3 downto 0)
);
end component;
component sju_seg_displayer
port
(
tal_in : in std_logic_vector(3 downto 0); -- Indata
hex_out: out std_logic_vector(6 downto 0) -- 7-segment display
);
end component;
signal tmp_trigger_out : std_logic;
signal tmp_klocks_echo : std_logic_vector(19 downto 0);
signal tmp_distans_bits : std_logic_vector(8 downto 0);
signal tmp_hundratal : std_logic_vector(3 downto 0);
signal tmp_tiotal : std_logic_vector(3 downto 0);
signal tmp_ental : std_logic_vector(3 downto 0);
begin
trigger <= tmp_trigger_out;
b1v_inst_trigger_cont : trigger_cont
port map(clock_50 => clock_50,
reset_n => reset_n,
trigger => tmp_trigger_out);
b1v_inst_echo_cont : echo_cont
port map(clock_50 => clock_50,
reset_n => reset_n,
reset_echo => tmp_trigger_out,
enable_echo => echo,
klocks_echo => tmp_klocks_echo);
b1v_inst_distans_raknaren : distans_raknaren
port map(enable_echo => echo,
klocks_echo => tmp_klocks_echo,
distans => tmp_distans_bits);
b1v_inst_bcd_converter : bcd_converter
port map(distans => tmp_distans_bits,
hundratal=> tmp_hundratal,
tiotal => tmp_tiotal,
ental => tmp_ental);
b2v_inst_sju_seg_displayer_1 : sju_seg_displayer
port map(tal_in => tmp_hundratal,
hex_out => hundratal);
b2v_inst_sju_seg_displayer_2 : sju_seg_displayer
port map(tal_in => tmp_tiotal,
hex_out => tiotal);
b2v_inst_sju_seg_displayer_3 : sju_seg_displayer
port map(tal_in => tmp_ental,
hex_out => ental);
end rtl;
==========
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity trigger_cont is
generic (nro_count: positive :=20); --24);
Port
(
clock_50 : in std_logic;
reset_n : in std_logic;
trigger : out std_logic
);
end trigger_cont;
architecture rtl of trigger_cont is
signal sg_count: std_logic_vector(nro_count-1 downto 0) := (others =>'1'); -- ska räknar till 12500000 = "101111101011110000100000"
signal Reset_t1,Reset_n_in : std_logic := '0';
--constant sg_nclks: std_logic_vector(nro_count-1 downto 0) := "101111101011110000100000"; -- 12500000ms
constant sg_nclks: integer := 750000; --12500000; -- Rang av antal klocks som fungerar för att
-- mäta hela distans av ultraljudsensor,
-- det är (12500000*20ns)/1000000=250ms = 4,5meter
begin
reset_process:process(clock_50, reset_n)
variable Reset_t2: std_logic;
begin
if rising_edge(clock_50) then -- -- flank går upp '1'
Reset_t1 <= Reset_n;
Reset_t2 := Reset_t1;
Reset_n_in <= Reset_t2;
end if;
end process reset_process;
trigger_process: process (clock_50, reset_n_in)
begin
if reset_n_in = '0' then
sg_count <= (others => '0');
elsif rising_edge(clock_50) then
if (sg_count < sg_nclks-1) then
sg_count <= sg_count + 1;
else
sg_count <= (others => '0');
end if;
end if;
end process trigger_process;
trigger <= '1' when (sg_count < 500) else '0'; -- skicka en puls av 10ms till sensor tigger
-- 500*20ns = 10000ns/1000=10ms (500 = 0..499)
end rtl;
=========
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity echo_cont is
generic (nro_count: positive := 20);
Port
(
clock_50 : in std_logic;
reset_n : in std_logic;
reset_echo : in std_logic;
enable_echo : in std_logic; -- kommer från top_nivå
klocks_echo : out std_logic_vector(nro_count-1 downto 0) -- med 10bits kan räknar till 512 tal
); -- men ska räknar till 450(cm) bara
end echo_cont;
architecture rtl of echo_cont is
signal sg_count: std_logic_vector(nro_count-1 downto 0); -- 23..0 = 24bits
signal Reset_t1,Reset_n_in : std_logic := '0';
begin
reset_process:process(clock_50, reset_n)
variable Reset_t2: std_logic;
begin
if rising_edge(clock_50) then -- -- flank går upp '1'
Reset_t1 <= Reset_n;
Reset_t2 := Reset_t1;
Reset_n_in <= Reset_t2;
end if;
end process reset_process;
echo: process (Reset_n_in, clock_50, enable_echo, reset_echo )
begin
if Reset_n_in = '0' or reset_echo = '1' then -- reset_echo det aktiverar sig
sg_count <= (others => '0'); -- genom komponent trigger_cont: trigger
elsif rising_edge(clock_50) then
if enable_echo = '1' then -- det enable_echo det kommer att aktiverar sig
sg_count <= sg_count + 1; -- från topnivå file, om echo är '1' det börjar räknar
end if; -- hur många klocks det finns på en period av 20ns
end if;
end process echo;
klocks_echo <= sg_count; -- antal klocks som varade ett echo
end rtl;
========
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity distans_raknaren is
port
(
enable_echo : in std_logic;
klocks_echo : in std_logic_vector(19 downto 0);
distans : out std_logic_vector (8 downto 0)
);
end distans_raknaren;
architecture rtl of distans_raknaren is
begin
distans_raknaren: process(enable_echo)
variable tmp_distans : integer;
begin
if falling_edge(enable_echo) then -- "echo" är negativ flank="0" slutade att räknar pulsklockan av mätaren
tmp_distans := ((to_integer(unsigned(klocks_echo))*20)/1000)/58; --- raknar distans i centimeter
-- if tmp_distans > 30 then ---450 then -- Om resultatet når det maximala värdet
-- distans <= "000011110"; --- visar 30 ----"111000010"; -- då avståndet det kommer att blir = 450cm
--
--
-- else
distans <= std_logic_vector(to_unsigned(tmp_distans, 9));
end if;
-- end if;
end process distans_raknaren;
end rtl;
========
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity bcd_converter is
port
(
distans : in std_logic_vector(8 downto 0);
hundratal: out std_logic_vector(3 downto 0);
tiotal : out std_logic_vector(3 downto 0);
ental : out std_logic_vector(3 downto 0)
);
end bcd_converter;
architecture rtl of bcd_converter is
begin
bcd_converter: process(distans)
variable i : integer := 0;
variable bcd : std_logic_vector(20 downto 0); -- innehåller bcd och binär det är 21 bits
begin -- 0000 0000 0000 101001010 = 330
bcd := (others => '0');
bcd(8 downto 0) := distans;
-- skapar en loop av 9 upprepning(0...8) eftersom binär ingången är av 9bits
for i in 0 to 8 loop
bcd(19 downto 0) := bcd(18 downto 0) & '0'; -- flyttar en digit till vänster
if(i < 8 and bcd(12 downto 9) > "0100") then -- om digit bcd är > "0100"(4)
bcd(12 downto 9) := bcd(12 downto 9) + "0011"; -- adderar 3 till bcd och det blir nytt bcd värde
end if;
if(i < 8 and bcd(16 downto 13) > "0100") then
bcd(16 downto 13) := bcd(16 downto 13) + "0011";
end if;
if(i < 8 and bcd(20 downto 17) > "0100") then
bcd(20 downto 17) := bcd(20 downto 17) + "0011";
end if;
end loop;
-- utgången
------- SI DESABILITO ESTOS COMENTARIOS MUESTRA SIEMPRE EN EL DISPLAY "E E E" EN LOS ------- TRES SEGMENTOS, ESTO ES EN EL CASO EN EL CASO DE QUE LA DISTANCIA SEA MAYOR A ------- 30CM, PERO SI LOS COMENTO MUESTRA EL VALOR "0 5 9" ES DECIR EL NUMERO 59. ESTO ------- LO HICE PARA SABER QUE VALOR ME MUESTRA SI NO LE PONGO NUNGUNA CONDICION.
-- if(distans > "00011110") then -- om distans är över 30cm visar på 7-display segment
--
-- hundratal <= "1110"; --- visar E
-- tiotal <= "1110"; --- visar E
-- ental <= "1110"; --- visar E
--
-- else
hundratal <= bcd(20 downto 17);
tiotal <= bcd(16 downto 13);
ental <= bcd(12 downto 9);
-- end if;
end process bcd_converter;
end rtl;
=================
library ieee;
use ieee.std_logic_1164.all;
entity sju_seg_displayer is
port
(
tal_in : in std_logic_vector(3 downto 0); -- Indata
hex_out: out std_logic_vector(6 downto 0) -- 7-segment display
);
end sju_seg_displayer;
architecture sju_seg_displayer_arch of sju_seg_displayer is
constant VISANOLL: std_logic_vector(6 downto 0) := "1000000"; -- 0x40
constant VISAETT: std_logic_vector(6 downto 0) := "1111001"; -- 0x79
constant VISATVA: std_logic_vector(6 downto 0) := "0100100"; -- 0x24
constant VISATRE: std_logic_vector(6 downto 0) := "0110000"; -- 0x30
constant VISAFYRA: std_logic_vector(6 downto 0) := "0011001"; -- 0x19
constant VISAFEM: std_logic_vector(6 downto 0) := "0010010"; -- 0x12
constant VISASEX: std_logic_vector(6 downto 0) := "0000010"; -- 0x02
constant VISASJU: std_logic_vector(6 downto 0) := "1111000"; -- 0x38
constant VISAATTA: std_logic_vector(6 downto 0) := "0000000"; -- 0x00
constant VISANIO: std_logic_vector(6 downto 0) := "0011000"; -- 0x18
constant VISAA: std_logic_vector(6 downto 0) := "0001000"; -- 0x08
constant VISAB: std_logic_vector(6 downto 0) := "0000011"; -- 0x03
constant VISAC: std_logic_vector(6 downto 0) := "1000110"; -- 0x46
constant VISAD: std_logic_vector(6 downto 0) := "0100001"; -- 0x21
constant VISAE: std_logic_vector(6 downto 0) := "0000110"; -- 0x06
constant VISAF: std_logic_vector(6 downto 0) := "0000111"; -- 0x07
-- En etta släcker segmentet en nolla tänder det
begin
with tal_in(3 downto 0) select
hex_out <= VISANOLL when "0000",
VISAETT when "0001",
VISATVA when "0010",
VISATRE when "0011",
VISAFYRA when "0100",
VISAFEM when "0101",
VISASEX when "0110",
VISASJU when "0111",
VISAATTA when "1000",
VISANIO when "1001",
VISAA when "1010",
VISAB when "1011",
VISAC when "1100",
VISAD when "1101",
VISAE when "1110",
VISAF when others;
end sju_seg_displayer_arch;
========================
BANCO DE PRUEBAS (solo lo que interesa)
==============
constant sys_clk_period : TIME := 50 ns;
clock_50 <= NOT clock_50 after 10 ns; --50 MHz -- varje 20 ns byta värde
sensor_test : PROCESS
BEGIN
reset_n <= '0';
wait for 3*sys_clk_period;
reset_n <= '1'; -- switchs-reset upp
wait for 6*sys_clk_period;
echo <= '0';
wait for (sys_clk_period/2)*100000;
echo <= '1';
wait for (sys_clk_period/2)*29000; -- DURACION DE ECHO
echo <= '0';
wait for (sys_clk_period/2)*1600000;
WAIT;
END PROCESS sensor_test;
====================
EL PROBLEMA....
==============
El asunto es que en la simulacion todo me sale correctamente pero cuando lo llevo a lo fisico me solo me muestra en los display "E E E" o "059" segun la condicon que habilite o desabilite en el componente "bcd_converter" como explique en lineas anteriores