不能 运行 HC - SR04 传感器 (VHDL)

Can't run HC - SR04 Sensor (VHDL)

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

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 配合使用时工作正常。

您可以通过设计改进以下几点:

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

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

由于这些代码行,

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 始终为 0,除非 Echo = '0' and echoing = '1'
  3. 回显总是 0,除非 Echo = '1'
  4. 因为Echo要么是0要么是1,最终定时器不能为正。