无法运行HC-SR04传感器(VHDL)

时间:2015-09-16 04:42:23

标签: vhdl sensor fpga

我是一名学生,他正在一个定制设计的电路板上工作,该电路板上装有Spartan-6 FPGA。我的项目是制作一个通过HDMI输出其界面的游戏,并通过传感器接收输入。我的传感器是HC-SR04(http://www.micropik.com/PDF/HCSR04.pdf)。除传感器模块外,所有模块都在运行。我没有收到任何警告或错误。 下面显示了我的模块代码,其中我创建了一个有限状态机来运行从传感器发送/接收数据所需的阶段。 请注意,我有一个比数据表中要求的更多的状态,但这不应该是一个问题,因为它不会触发传感器。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Sensor is
    Port (  clk  :  in      STD_LOGIC; --24 MHz
                Echo     :  in      STD_LOGIC;
        Trig     :  out STD_LOGIC;
        Echo_Time:  out integer
    );
end Sensor;

architecture Behavioral of Sensor is

type state_type is (    Init_state, Trigger_state, Echo_state);


signal  state       :   state_type  := Init_state;
signal  echoing     :   std_logic   := '0';             -- determines if we are echoing or not
signal  echoReceived    :   std_logic   := '0';             -- determines if we are echoing or not
signal  d       :   integer;                                -- the first and highest possible delay, this is 20 ms
signal  en_timer    :   std_logic;                          --active high
signal  rst_timer   :   std_logic;                          --active high


signal cnt_timer    : integer := 0;--was 19,
signal final_timer  : integer := 0;--was 19,

begin

state_machine: process (clk, cnt_timer, echoReceived)
    begin
        if rising_edge(clk) then
            if state = Init_state then
                if cnt_timer = d then
                    state <= Trigger_state;
                    rst_timer <= '1';
                else
                    rst_timer <= '0';
                end if;
            elsif state = Trigger_state then
                if cnt_timer = d then
                    state <= Echo_state;
                    rst_timer <= '1';
                else
                    rst_timer <= '0';
                end if;
            elsif state = Echo_state then
                if echoReceived = '1' then--change this one
                    state <= Init_state;
                    rst_timer <= '1';
                else
                    rst_timer <= '0';
                end if;
            end if;
      end if;
    end process;


timer: process(clk, en_timer,rst_timer)
    begin
        if rising_edge(clk) then
            if en_timer = '1' and rst_timer = '0' then
                cnt_timer <= cnt_timer + 1;
            elsif rst_timer = '1' then
                cnt_timer <= 0;
            end if;
        end if;             
    end process;


state_machine_output: process(state, Echo, echoing,cnt_timer)
    begin

            --internal signals
            en_timer        <= '0';

            --state machine signals
            d               <= 0;
            echoing         <= '0';
            echoReceived            <= '0';
            final_timer     <= 0;
            --external signals
            Trig            <= '0';
        if state = Init_state then

            en_timer        <= '1';
            Trig            <= '0';
            d           <= 48; -- this will delay the system by 2 us
            echoing         <= '0';
            echoReceived            <= '0';
        elsif state = Trigger_state then    

            en_timer        <= '1';
            Trig            <= '1';
            d           <= 240; -- this will delay the system by 10 us
            echoing         <= '0';
            echoReceived    <= '0';
        elsif state = Echo_state then   --think about it later

            if Echo = '1' then
                en_timer    <= '1';
                echoing     <= '1';
            elsif Echo = '0' and echoing = '1' then
                final_timer     <= cnt_timer;
                en_timer        <= '0';
                echoing     <= '0';
                echoReceived    <= '1'; 
            end if;

        else

            --internal signals
            en_timer        <= '0';

            --state machine signals
            d           <= 0;
            echoing         <= '0';
            echoReceived            <= '0';
            final_timer     <= 0;
            --external signals
            Trig            <= '0';

        end if;
    end process;

Echo_Time   <= final_timer;--output data here

end Behavioral;

所以,我的问题是我的逻辑是否正确,因为我只能从Echo_time获得0。

另外,请注意传感器与arduino一起工作正常。

2 个答案:

答案 0 :(得分:0)

您可以通过设计改进一些事项:

  • 检查您的敏感度列表:对于同步过程,它应仅包含时钟(加上异步设置和/或重置(如果有))。
  • 请勿在声明时初始化您的信号。这不适用于所有合成器和/或硬件目标。使用显式重置(即模块的另一个输入)来初始化必须的内容。

一旦你解决了这个问题,你应该在合成并在硬件上运行之前进行模拟:通过模拟进行调试要容易得多。

答案 1 :(得分:0)

由于这些代码行,Echo_time始终为0:

if Echo = '1' then
  en_timer    <= '1';
  echoing     <= '1';
elsif Echo = '0' and echoing = '1' then
  final_timer     <= cnt_timer;
  en_timer        <= '0';
  echoing     <= '0';
  echoReceived    <= '1';
end if;

跟踪输出信号:

  1. Echo_time等于final_timer
  2. 除了final_timer 之外,
  3. Echo = '0' and echoing = '1'始终为0
  4. Echo = '1'
  5. 外,回显始终为0
  6. 因为Echo是0或1,所以最终计时器不能为正。