BASIC4MCU | 질문게시판 | vhdl 소스코드 라인트레이서 질문
페이지 정보
작성자 woni 작성일2018-06-01 15:50 조회10,455회 댓글1건본문
제가 리모콘 버튼을 누르면 라인트레이서가 전진하고
버튼을 떄면 그 전진한 거리를 기억하여 제자리로 후진하게 만들고
다시 그 전후진한 거리를 기억하여 전후진을 반복하는 소스코드를 짜고있습니다.
아래 코드중 틀린 부분을 설명과 어떻게 바꿔야하는지 질문입니다.
-- IRobLab 3000
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity rf_robot2 is
Port ( rstb : in std_logic;
clk_4m : in std_logic;
restore : in std_logic;
rf_data : in std_logic_vector(2 downto 0);
mtl : out std_logic_vector(3 downto 0);
mtr : out std_logic_vector(3 downto 0));
end rf_robot2;
architecture Behavioral of rf_robot2 is
signal forward : std_logic;
signal mtl_speed : std_logic_vector(1 downto 0);
signal mtr_speed : std_logic_vector(1 downto 0);
signal speed_l : integer range 0 to 250000;
signal speed_r : integer range 0 to 250000;
signal motor_lcnt : integer range 0 to 250000;
signal phase_lclk : std_logic;
signal phase_clk : std_logic;
signal restore1 : std_logic;
signal motor_rcnt : integer range 0 to 250000;
signal mcnt : integer range 0 to 250000;
signal phase_rclk : std_logic;
signal phase_lcnt : std_logic_vector(1 downto 0);
signal phase_lout : std_logic_vector(3 downto 0);
signal phase_rcnt : std_logic_vector(1 downto 0);
signal phase_rout : std_logic_vector(3 downto 0);
signal cnt : integer range 0 to 250000;begin
process(rf_data)
begin
forward <= rf_data(2);
case rf_data is
when "100" => -- forward
mtl_speed <= "11";
mtr_speed <= "11";
when "000" => -- reverse
mtl_speed <= "11";
mtr_speed <= "11";
when "110" => -- turn right
mtl_speed <= "11";
mtr_speed <= "00";
when "101" => -- turn left
mtl_speed <= "00";
mtr_speed <= "11";
when "010" => -- reverse turn right
mtl_speed <= "00";
mtr_speed <= "11";
when "001" => -- turn left
mtl_speed <= "11";
mtr_speed <= "00";
when others =>
mtl_speed <= "00";
mtr_speed <= "00";
end case;
end process;
process(mtl_speed,phase_clk,cnt,restore1)
begin
if(cnt=0 and restore1 ='1') then
speed_l <=0;
elsif rising_edge(phase_clk) then
case mtl_speed is
when "00" =>
speed_l <= 0;
when "01" =>
speed_l <= 124999;
when "10" =>
speed_l <= 62500;
when "11" =>
speed_l <= 50000;
when others =>
speed_l <= 50000;
end case;
end if;
end process;
process(mtr_speed,phase_clk,cnt,restore1)
begin
if(cnt=0 and restore1 ='1') then
speed_r <=0;
elsif rising_edge(phase_clk) then
case mtr_speed is
when "00" =>
speed_r <= 0;
when "01" =>
speed_r <= 124999;
when "10" =>
speed_r <= 62500;
when "11" =>
speed_r <= 50000;
when others =>
speed_r <= 50000;
end case;
end if;
end process;process(rstb,clk_4m)
begin
if rstb = '0' then
phase_clk <= '0';
mcnt <=0;
elsif rising_edge(clk_4m) then
if mcnt >= 50000 then
phase_clk <= not phase_clk;
mcnt <=0;
else
mcnt <=mcnt+1;
end if;
end if;
end process;process(rstb, speed_l, clk_4m, motor_lcnt)
begin
if rstb = '0' or speed_l = 0 then
motor_lcnt <= 0;
phase_lclk <= '0';
elsif rising_edge(clk_4m) then
if motor_lcnt >= speed_l then
motor_lcnt <= 0;
phase_lclk <= not phase_lclk;
else
motor_lcnt <= motor_lcnt + 1;
end if;
end if;
end process;process(rstb, speed_r, clk_4m, motor_rcnt)
begin
if rstb = '0' or speed_r = 0 then
motor_rcnt <= 0;
phase_rclk <= '0';
elsif rising_edge(clk_4m) then
if motor_rcnt >= speed_r then
motor_rcnt <= 0;
phase_rclk <= not phase_rclk;
else
motor_rcnt <= motor_rcnt + 1;
end if;
end if;
end process;process(rstb, phase_lclk, phase_lcnt)
begin
if rstb = '0' then
phase_lcnt <= (others => '0');
elsif rising_edge(phase_lclk) then
phase_lcnt <= phase_lcnt + 1;
end if;
end process;process(rstb, phase_lcnt)
begin
if rstb = '0' then
phase_lout <= (others => '0');
else
case (phase_lcnt) is
when "00" => phase_lout <= "1000";
when "01" => phase_lout <= "0100";
when "10" => phase_lout <= "0010";
when "11" => phase_lout <= "0001";
when others => phase_lout <= "0000";
end case;
end if;
end process;process(rstb, phase_rclk, phase_rcnt)
begin
if rstb = '0' then
phase_rcnt <= (others => '0');
elsif rising_edge(phase_rclk) then
phase_rcnt <= phase_rcnt + 1;
if(restore1 = '0') then
cnt <= cnt +1;
elsif (cnt/=0) then
cnt <=cnt-1;
end if;
end if;
end process;process(rstb, phase_rcnt)
begin
if rstb = '0' then
phase_rout <= (others => '0');
else
case (phase_rcnt) is
when "00" => phase_rout <= "1000";
when "01" => phase_rout <= "0100";
when "10" => phase_rout <= "0010";
when "11" => phase_rout <= "0001";
when others => phase_rout <= "0000";
end case;
end if;
end process;process(restore, phase_clk)
begin
if rising_edge(phase_clk) then
restore1 <= restore;
end if;
end process;
mtl(0) <= phase_lout(0) when restore1 ='0' else phase_lout(3);
mtl(1) <= phase_lout(1) when restore1 ='0' else phase_lout(2);
mtl(2) <= phase_lout(2) when restore1 ='0' else phase_lout(1);
mtl(3) <= phase_lout(3) when restore1 ='0' else phase_lout(0);
mtr(0) <= phase_rout(3) when restore1 ='0' else phase_rout(0);
mtr(1) <= phase_rout(2) when restore1 ='0' else phase_rout(1);
mtr(2) <= phase_rout(1) when restore1 ='0' else phase_rout(2);
mtr(3) <= phase_rout(0) when restore1 ='0' else phase_rout(3);
end Behavioral;
댓글 1
조회수 10,455master님의 댓글
master 작성일
VHDL은 제가 사용해보지 않아서 모릅니다.
http://cafe.naver.com/lazydigital
이 카페 임베디드홀릭님이 친절하시니 여기서 질문글로 작성해보세요