【FPGA频率计】基于FPGA的数字频率计开发,VHDL编程实现

1.软件版本

MAXPLUSII

2.本算法理论知识

频率测量的方法常用的有测频法和测周法两种。

·测频法

       测频法的基本思想是让计数器在闸门信号的控制下计数1秒时间,计数结果是1秒内被测信号的周期数,即被测信号的频率。若被测信号不是矩形脉冲,则应先变换成同频率的矩形脉冲。测频法的原理框图如图1所示。

       图中,秒脉冲作为闸门信号,当其为高电平时,计数器计数;低电平时,计数器停止计数。显然,在同样的闸门信号作用下,被测信号的频率越高,测量误差越小。当被测频率一定时,闸门信号高电平的时间越长,测量误差越小。但是闸门信号周期越长,测量的响应时间也越长。例如,闸门信号高电平时间为1秒,被测信号频率的真值为2Hz,如图2所示。

       可知,无论被测信号的频率是多少,测量时可能产生的最大绝对误差均为±1Hz,即

                   f测-f真=±1Hz

       所以,最大相对误差为:σmax= (f测-f真)/ f真=±1/ f真。由上式可知,在闸门信号相同时,测频法的相对误差与被测信号的频率成反比。因此测频法适合于测量频率较高的信号。

 

·测周法

       当被测信号频率较低时,为保证测量精度,常采用测周法。即先测出被测信号的周期,再换算成频率。测周法的实质是把被测信号作为闸门信号,在它的高电平的时间内,用一个标准频率的信号源作为计数器的时钟脉冲。若计数结果为N,标准信号频率为f1,则被测信号的周期为

               T = T1·N

被测信号的频率为

                  f = 1/T1·N = f1/N

      利用测周法所产生的最大绝对误差,显然也等于±1个标准信号周期。如果被测信号周期的真值为T真= T1·N,则T测= T1·(N±1)

               σmax= (f测-f真)/ f真= T真/T测 – 1=±1/(N±1)

由上式可知,对于一定的被测信号,标准信号的频率越高,则N的值越大,因而相对误差越小。

       数字频率计的关键组成部分包括一个测频控制信号发生器、一个计数器和一个锁存器,另外包含信号整形电路、脉冲发生器、译码驱动电路和显示电路,其原理框图如图1所示。

       工作过程:系统正常工作时,脉冲信号发生器输入1Hz的标准信号,经过测频控制信号发生器的处理,2分频后即可产生一个脉宽为1秒的时钟信号,以此作为计数闸门信号。测量信号时,将被测信号通过信号整形电路,产生同频率的矩形波,输入计数器作为时钟。当计数闸门信号高电平有效时,计数器开始计数,并将计数结果送入锁存器中。设置锁存器的好处是显示的数据稳定,不会由于周期性的清零信号而不断闪烁。最后将锁存的数值由外部的七段译码器译码并在数码管上显示。

3.部分核心代码

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity jjj is
port(clkk:in std_logic;
cnt_en:out std_logic;
rst_ent:out std_logic;
load:out std_logic);
end jjj;
architecture behave of jjj is
signal div2clk:std_logic;
begin
process(clkk)
begin
if(clkk'event and clkk='1')then
div2clk<=not div2clk;
end if;
end process;
process(clkk,div2clk)
begin
if(clkk='0' and div2clk='0')then
rst_ent<='1';
else rst_ent<='0';
end if;
end process;
load<=not div2clk;
cnt_en<=div2clk;
end behave;


library ieee;
use ieee.std_logic_1164.all;
entity jjj1 is
port(lk:in std_logic;
din:in std_logic_vector(31 downto 0);
dout:out std_logic_vector(31 downto 0) );
end jjj1;
architecture beha of jjj1 is
begin
process(lk,din)
begin
if(lk'event and lk='1')then
dout<=din;
end if;
end process;
end beha;


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity jjj2 is
port(fin:in std_logic;
clr:in std_logic;
enabl:in std_logic;
dout :out std_logic_vector(31 downto 0));
end jjj2;
architecture beha of jjj2 is
signal cq:std_logic_vector(31 downto 0);
begin
process(fin,clr,enabl)
begin
if(clr='1')then cq<=(others=>'0');
elsif(fin'event and fin='1') then
if(enabl='1')then cq<=cq+'1';
	if cq(3 downto 0)="1001" then cq(3 downto 0)<="0000";cq(31 downto 4)<=cq(31 downto 4)+1;
	 if cq(7 downto 4)="1001" then cq(7 downto 4)<="0000";cq(31 downto 8)<=cq(31 downto 8)+1;
	  if cq(11 downto 8)="1001" then cq(11 downto 8)<="0000";cq(31 downto 12)<=cq(31 downto 12)+1;
	    if cq(15 downto 12)="1001" then cq(15 downto 12)<="0000";cq(31 downto 16)<=cq(31 downto 16)+1;
	      if cq(19 downto 16)="1001" then cq(19 downto 16)<="0000";cq(31 downto 20)<=cq(31 downto 20)+1;
	        if cq(23 downto 20)="1001" then cq(23 downto 20)<="0000";cq(31 downto 24)<=cq(31 downto 24)+1;
	          if cq(27 downto 24)="1001" then cq(27 downto 24)<="0000";cq(31 downto 28)<=cq(31 downto 28)+1;
				if cq(31 downto 28)="1001" then cq(31 downto 28)<="0000";
				end if;
			  end if;
			end if;
		   end if;
		  end if;
		end if;
	   end if;
	  end if;
end if;
end if;
end process;
dout<=cq;
end beha;


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity eda is
port(clk1hz:in std_logic;
fsin:in std_logic;
dout:out std_logic_vector(31 downto 0));
end eda;
architecture beha of eda is
component jjj
port(clkk:in std_logic;
cnt_en:out std_logic;
rst_ent:out std_logic;
load:out std_logic);
end component; 
component jjj2
port(fin:in std_logic;
clr:in std_logic;
enabl:in std_logic;
dout :out std_logic_vector(31 downto 0));
end component;
component jjj1
port(lk:in std_logic;
din:in std_logic_vector(31 downto 0);
dout:out std_logic_vector(31 downto 0) );
end component;
signal tsten1:std_logic;
signal clr_ent1:std_logic;
signal load1:std_logic;
signal dto1:std_logic_vector(31 downto 0) ;
signal carry_out1:std_logic_vector(6 downto 0);
begin
u1:jjj port map (clkk=>clk1hz,cnt_en=>tsten1,rst_ent=>clr_ent1,load=>load1);
u2:jjj1 port map(lk=>load1,din=>dto1,dout=>dout);
u3:jjj2 port map(fin=>fsin,clr=>clr_ent1,enabl=>tsten1,dout=>dto1);
end beha;

4.操作步骤与仿真结论

 这里表示输入的时钟是系统时钟的100倍,即100hz,那么其仿真结果为:

这里表示输入的时钟是系统时钟的1000倍,即1khz,那么其仿真结果为:

5.参考文献

[01] 章彬宏,EDA应用技术,北京理工大学出版社,2007                  

[02] 杨刚等,现代电子技术——VHDL与数字系统设计,电子工业出版社,2004   

[03] 张亦华等,数字电路EDA入门---VHDL程序实例集,北京邮电大学出版社,2004 A35-03

 

  • 2
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fpga和matlab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值