1
0
Fork 0
mirror of https://github.com/RobotechLille/cdf2018-principal synced 2024-11-04 23:56:04 +01:00
cdf2018-principal/fpga/hcSr04.vhd
2018-02-07 17:57:01 +01:00

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;