问题描述
我有一个问题。我需要使用霍尔传感器和车轮上的磁铁来计算/测量家庭培训师的RPM,硬件需要用VHDL描述,我目前的方法是:
-
如果霍尔传感器检测到脉冲,请重置计数器
-
每个时钟周期递增计数器
-
在下一个脉冲上,存储上一个值,重置并重复。
代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity teller is
port(
hallsens : in std_logic;
counter : out std_logic_vector(15 downto 0);
areset : in std_logic;
clk : in std_logic
);
end entity teller;
architecture rtl of teller is
signal counttemp : std_logic_vector(15 downto 0);
signal timerval2 : std_logic_vector(15 downto 0);
signal lastcount : std_logic_vector(15 downto 0);
begin
process(clk,areset)
begin
if areset = '1' then
counter <= "0000000000000000";
counttemp <= "0000000000000000";
timerval2 <= "0000001111101000";
elsif hallsens = '1' then
counter <= lastcount + "1";
timerval2 <= "0000001111101000";
counttemp <= "0000000000000000";
elsif rising_edge(clk) then
timerval2 <= timerval2 - "1";
if timerval2 = "0000000000000000" then
lastcount <= counttemp;
counttemp <= counttemp + "1";
timerval2 <= "0000001111101000";
end if;
end if;
end process;
end rtl;
但是要从中计算RPM,我必须将计数器除以时钟速度,再乘以60。这占用了FPGA(Altera Cyclone 2)上的很多硬件。
有没有更有效的方法?
TIA
解决方法
我现在没有电脑,但是我将尝试指出我看到的不同内容:
-
不要混合数字库(最好只使用numeric_std)@tricky建议。
-
如果处理数字值,并且包括该函数的库,则可以对信号使用数字类型(整数,无符号,有符号..),这使事情变得清晰并有助于区分数字信号,而无数值含义信号。
-
Hallsens被读取为伪重置,但不在过程的敏感度列表中,这可能会导致Sims与硬件之间的不匹配。无论如何,这不是一个好方法,请坚持使用简单的重置和时钟对。
-
我将检测该过程的计时区域内的霍尔森斯,并在此增加事件计数器。它应该更简单。 我假设您的Hallsens断言时间足够宽,可以被时钟捕获。
-
一旦计时器信号达到零(我假设这根据您的clk频率为您提供了一个已知时间),您可以再次重新加载计时器(如您所愿),输出计数值并重置计数器,重新开始。
-
对于1 / Freq和* 60的数学运算,可以根据频率值使用一些数字技巧,但您可以:
- 乘以频率的倒数而不是除。
- 将其近似为2的幂和。(60 = 64-4)
- 使Freq为60的倍数以简化计算。
Ps:为减少错误的发生,您可以将向量(因为它们是4的倍数)初始化为十六进制格式,例如:signal