mirror of
https://github.com/RobotechLille/cdf2018-principal
synced 2024-11-14 12:26:06 +01:00
90 lines
3.5 KiB
VHDL
90 lines
3.5 KiB
VHDL
LIBRARY ieee;
|
|
USE ieee.std_logic_1164.all;
|
|
USE ieee.std_logic_unsigned.all;
|
|
|
|
ENTITY hcSr04 IS
|
|
GENERIC(
|
|
fFpga : INTEGER := 50_000_000 -- frequency of the FPGA clock (Hz)
|
|
);
|
|
PORT(
|
|
clk : IN STD_LOGIC; -- clock of the FPGA
|
|
echo : IN STD_LOGIC; -- echo pin of the hcSr04
|
|
distance : OUT INTEGER RANGE 0 TO 65535; -- Divide by 58 to get the value in cm
|
|
trigger : OUT STD_LOGIC; -- trigger pin of the hcSr04
|
|
start : IN STD_LOGIC; -- Set to '1' everytime a measurement is needed (or keep at '1' for continuous measurement)
|
|
finished : OUT STD_LOGIC -- Driven to '1' everytime a measurement has finished
|
|
);
|
|
END hcSr04;
|
|
|
|
ARCHITECTURE Behavioral OF hcSr04 IS
|
|
-- Generate us clock
|
|
CONSTANT fUs : INTEGER := 1_000_000; -- Frequency of the microsecond clock
|
|
CONSTANT usTicks : INTEGER := fFPGA / fUs; -- Number of FPGA tick that makes a microsecond
|
|
SIGNAL fpgaCounter : INTEGER RANGE 0 TO usTicks - 1; -- Count the microsecond
|
|
SIGNAL usClk : STD_LOGIC; -- Clock that ticks every us
|
|
|
|
-- Trigger
|
|
CONSTANT triggerDuration : INTEGER := 10; -- Number of us that makes up a trigger sequence
|
|
SIGNAL triggerCounter : INTEGER RANGE 0 TO triggerDuration - 1 := 0; -- Progress in the trigger sequence
|
|
SIGNAL theTrigger : STD_LOGIC := '0'; -- Trigger pin but with default value
|
|
|
|
-- Measurement
|
|
CONSTANT measurementDuration : INTEGER := 60_000; -- Number of us that makes up a measurement cycle
|
|
SIGNAL measurementCounter : INTEGER RANGE 0 TO measurementDuration - 1 := 0; -- Progress in the measurement cycle
|
|
|
|
-- Distance
|
|
SIGNAL distanceCounter : INTEGER RANGE 0 TO 65535 := 0; -- Distance measured (in us)
|
|
|
|
-- State machine
|
|
TYPE stateType IS (waiting, triggering, measuring);
|
|
SIGNAL state : stateType;
|
|
|
|
BEGIN
|
|
us : process(clk)
|
|
begin
|
|
if rising_edge(clk) then
|
|
if fpgaCounter = 0 then
|
|
usClk <= '0';
|
|
elsif fpgaCounter = 1 then
|
|
usClk <= '1';
|
|
end if;
|
|
fpgaCounter <= fpgaCounter + 1;
|
|
end if;
|
|
end process;
|
|
|
|
trigger <= theTrigger;
|
|
|
|
measure : process(usClk)
|
|
begin
|
|
if rising_edge(usClk) then
|
|
CASE state IS
|
|
WHEN waiting =>
|
|
finished <= '0';
|
|
IF start = '1' THEN
|
|
theTrigger <= '1';
|
|
triggerCounter <= 0;
|
|
state <= triggering;
|
|
END IF;
|
|
WHEN triggering =>
|
|
triggerCounter <= triggerCounter + 1;
|
|
IF triggerCounter = triggerDuration - 1 THEN
|
|
theTrigger <= '0';
|
|
measurementCounter <= 0;
|
|
distanceCounter <= 0;
|
|
state <= measuring;
|
|
END IF;
|
|
WHEN measuring =>
|
|
IF echo = '1' and distanceCounter < 65535 THEN
|
|
distanceCounter <= distanceCounter + 1;
|
|
END IF;
|
|
measurementCounter <= measurementCounter + 1;
|
|
IF measurementCounter = measurementDuration - 1 THEN
|
|
distance <= distanceCounter;
|
|
finished <= '1';
|
|
state <= waiting;
|
|
END IF;
|
|
END CASE;
|
|
end if;
|
|
end process;
|
|
END Behavioral;
|