Quartus II9.0 进行的EDA频率计设计
1、频率计的测量范围为1MHz,量程分10KHz、100KHz和1000KHz三档(最大读数分别为9.99KHz、99.9KHz、999KHz)。
2、当读数大于999时,频率计处于超量程状态。此时显示器发出溢出指示(最高位显示F,其余各位不显示数字),下一次测量时,量程自动增大一档。读数小于000时,频率计处于欠量程状态。下次测量时,量程减小一档。 3、要求实现溢出报警功能。即当频率高于999KHz时,频率计处于超量程状态,产生一报警信号,点亮LED灯,从而实现溢出报警功能。 4、用记忆显示方式,即计数过程中不显示数据,待计数过程结束后,显示计数结果,并将此显示结果保持到下一次计数结束。显示时间应不小于1秒,小数点位置随量程变更自动移位。 2. 系统总体设计 本设计采用的是直接测频率的方法。即测频率法就是在一定的时间间隔内TW内,得到这个周期信号重复变化的次数NX,则被测频率可表示为FX=NX/TW。 频率计的系统设计可以分为计频基准时钟模块、自动换档模块、4位10进制计数模块锁存模块、译码显示模块。 计频基准时钟模块: 以1kHZ为基准,产生三个不同占比的0.5Hz脉冲信号其高电平时间分别为1s、0.1s、0.01s,分别用以测量频率在0~9.99KHz、0~99.9KHz、0~999KHz的频率。 自动换档模块: 先以最低档位测量,溢出时下一次计数自动切换高档位,计数不满“000”下一次自动切换到低档位。计数溢出999khz时,发出警报。 四位10进制计数模块锁存模块: 四位十进制计数,档位基准信号为高电平时,开始计数,低电平时锁存输出计数结果的前三位,计数器清零。当溢出或计数不满时,输出换挡信号。计数刷新频率为0.5Hz。 译码显示模块: 将计数器输出的结果按位译成7段显示数码管对应数字码,根据所选档位信号设置小数点位置。刷新频率为 系统框图(可打印) 3. 系统详细设计 3.1 计频基准时钟模块设计 该模块的电路框图 各输入输出引脚的定义及作用 Clk:为基准时钟信号,选用1kHz时钟信号 F0:根据clk分频出的0.5Hz高电平为1s的计频信号,用以0~9.99kHz档计频。 F1:根据clk分频出的0.5Hz高电平为0.1s的计频信号,用以0~99.9kHz档计频。 F2:根据clk分频出的0.5Hz高电平为0.01s的计频信号,用以0~999kHz档计频。 - library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
- entity dw is port(clk:in std_logic;
- f0:out std_logic;
- f1:out std_logic;
- f2:out std_logic);
- end dw;
- architecture body_dw of dw is
- begin
- process(clk) --clk选用1kHz时钟信号
- variable ct:integer range 0 to 2000;
- begin
- if clk'event and clk='1'then --分频周期为2s的脉冲
- ct:=ct+1;
- if ct=2000 then ct:=0;
- end if;
- if ct<1000 then f0<='1';
- elsif ct<2000 then f0<='0'; --f0为0.5Hz高电平为1s
- end if;
- if ct<100 then f1<='1';
- elsif ct<2000 then f1<='0'; --f1为0.5Hz高电平为0.1s
- end if;
- if ct<10 then f2<='1';
- elsif ct<2000 then f2<='0'; --f2为0.5Hz高电平为0.01s
- end if;
- end if;
- end process;
- end body_dw;
复制代码
(可打印) 仿真波形(可打印) 对波形的分析说明: Ct为整数计数,检测到clk上升沿时则加一计数,f0,f1,f2根据ct计数结果分频输出所需脉冲。 3.2 自动换档模块设计 f0,f1,f2为各档位计频信号 td为换挡信号 f为所选档位输出的测频信号 sel输出档位选择信号,用以小数点位置控制 alarm为999kHz溢出报警 - library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
- entity xz is port(f0:in std_logic;
- f1:in std_logic;
- f2:in std_logic;
- td:in std_logic_vector(1 downto 0);
- f:out std_logic;
- alarm:out std_logic;
- sel:out std_logic_vector(1 downto 0)); --输出档位选择信号
- end xz;
- architecture body_xz of xz is
- begin
- process(td,f0)
- variable dwxz:std_logic_vector(1 downto 0);
- begin
- if f0'event and f0='1' then --计数前以0.5Hz信号的上升沿检测是否有换挡信号
- if td="10" then --换挡信号td为10表示切换到高一档
- if dwxz="10" then alarm<='1'; --如果档位已是最高,则报警
- else dwxz:=dwxz+1;
- alarm<='0'; --正常换挡则消除报警
- end if;
- elsif td="01" then --换挡信号td为01表示切换到低一档
- if dwxz="00" then null;
- else dwxz:=dwxz-1;
- alarm<='0';
- end if;
- else alarm<='0'; --正常计频,消除报警
- end if;
- sel<=dwxz;
- if dwxz=0 then f<=f0;end if;
- if dwxz=1 then f<=f1;end if;
- if dwxz=2 then f<=f2;end if;
- end process;
- end body_xz;
复制代码
开始时量程输出为(档位选择)sel=“00”,即最小档,输出f为f0,当接收到(调档)td=“10”切换高一档,sel变为“10”。 3.3 四位10进制计数锁存模块设计 M输入被测量信号 En输入测量脉冲,高电平时开始计频率,低电平输出锁存结果。 q3,q2,q1为锁存的计频结果。 Td在溢出和欠量程时候输出调档信号。 library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity js is port(m:in std_logic;
en:in std_logic;
q1,q2,q3:out std_logic_vector(3 downto 0);
td:out std_logic_vector(1 downto 0));
end js;
architecture body_js of js is
signal js_td:std_logic_vector(1 downto 0);
signal b3,b2,b1: std_logic_vector(3 downto 0);
begin
process(en,m)
variable w0,w1,w2,w3:std_logic_vector(3 downto 0); --四位十进制计数
begin
if en='1' then --当计频脉冲为1是开始计数
if m'event and m='1' then
if w3="1010" then null;
else w0:=w0+1;
if w0="1010" then
w0:="0000";w1:=w1+1;
if w1="1010" then
w1:="0000";w2:=w2+1;
if w2="1010" then
w2:="0000";w3:=w3+1;
end if ;
end if ;
end if;
end if;
b1<=w1; --计数结果实时缓存至b1,b2,b3
b2<=w2;
b3<=w3;
end if ;
end if ;
if en='0'then
q1<=b1; --en档位脉冲为低电平时b1,b2,b3结果为最终值,保持不变
q2<=b2; --将结果输出至Q1,Q2,Q3
q3<=b3; --当下一次低电平时,刷新计数结果
w0:="0000";
w1:="0000"; --低电平时,计数器清零
w2:="0000";
w3:="0000";
end if;
end process;
process(en) --计数一结束,以下降沿触发判断是否欠量程或则溢出
begin --并输出相应调档信号
if en'event and en='0'then
if b1="0000" and b2="0000" then
if b3="0000" then td<="01";
elsif b3="1010" then td<="10";
elsif b3>"0000"and b3<"1010" then td<="00";
end if;
end if;
end if;
end process;
end body_js;
En脉冲为99.9Hz量程脉冲 m被测脉冲设置为0~5s 50Hz;5~10s 10000Hz;10~13s 100000Hz; 第一个测量脉冲判定结果为欠量程,调档信号TD输出01,调低档位 第三个脉冲检测判定10.0kHz,在量程范围,调档不做输出 第六个脉冲检测判定100kHz,溢出,调档TD输出10,调高档位
3.4 译码模块 Clk为1kHz时钟信号,用以触发赋值语句等 Sel为档位信号 Q1,Q2,Q3为计数器锁存结果输入 LED0,LED1,LED2为三位结果的译码输出
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ym is port(
clk:in std_logic;
sel:in std_logic_vector(1 downto 0);
q1,q2,q3:in std_logic_vector(3 downto 0);
led0,led1,led2:out std_logic_vector(7 downto 0));
end ym;
architecture body_ym of ym is
signal tp:std_logic_vector(3 downto 0);
signal led:std_logic_vector(6 downto 0);
begin
led<="0111111"when tp="0000"else --0
"0000110"when tp="0001"else --1
"1011011"when tp="0010"else --2
"1001111"when tp="0011"else --3
"1100110"when tp="0100"else --4
"1101101"when tp="0101"else --5
"1111101"when tp="0110"else --6
"0000111"when tp="0111"else --7
"1111111"when tp="1000"else --8
"1101111"when tp="1001"else --9
"1110001"when tp="1010"; --F
process(clk,sel)
variable c:std_logic_vector(1 downto 0) ;
begin
if clk'event and clk='1' then
if c="10"then c:="00";
else c:=c+1;
end if;
if q3="1010"then --溢出显示F
led2<="01110001";
led1<="00000000";
led1<="00000000";
else
if sel="10" then --999KHZ档小数点赋值
case c is
when "00"=>tp<=q2;
led0<='1'&led;
when "01"=>tp<=q3;
led1<='0'&led;
when "10"=>tp<=q1;
led2<='0'&led;
when others=>null;
end case;
elsif sel="01" then -- 99.9khz档小数点
case c is
when "00"=>tp<=q2;
led0<='0'&led;
when "01"=>tp<=q3;
led1<='1'&led;
when "10"=>tp<=q1;
led2<='0'&led;
when others=>null;
end case;
elsif sel="00" then --9.99kHz档小数点
case c is
when "00"=>tp<=q2;
led0<='0'&led;
when "01"=>tp<=q3;
led1<='0'&led;
when "10"=>tp<=q1;
led2<='1'&led;
when others=>null;
end case;
end if;
end if;
end if;
end process;
end body_ym;
设置0~2s 输出为1017,溢出,LED2输出F的段码,两外两个消隐。 设置2s后输出217,按照(量程选择)sel=0时,为0~9.99khz,小数点在高位即led2[7]为1。 3.4 显示模块 Clk:动态显示触发信号,1khz每一个点亮一个数码管,三个循环,其频率显然大于人眼可识别。 Led0,led1,led2:为译码输出的数码管显示信号。 Ledag,sel:为动态显示
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity dynamic_display is port(clk:in std_logic;
ledag:out std_logic_vector(7 downto 0);
sel:out std_logic_vector(2 downto 0);
led0,led1,led2:in std_logic_vector(7 downto 0));
end dynamic_display;
architecture body_display of dynamic_display is
begin
process(clk)
variable c:std_logic_vector(1 downto 0) ;
begin
if clk'event and clk='1' then
if c="10"then c:="00";
else c:=c+1;
end if;
end if;
case c is
when"00"=>sel<="001";
ledag<=led0;
when"01"=>sel<="010";
ledag<=led1;
when"10"=>sel<="100";
ledag<=led2;
when others=>null;
end case;
end process;
end body_display;
4. 系统调试 4.1 系统总体仿真 系统总体输入输出引脚的定义及作用 仿真波形(可打印) M在0~6s 设置为1000Hz 读取波形led为1.00kHz
M在6~12s 设置为100khz 读取显示应为100.khz
M在6~12s 设置为1mhz Alarm 溢出报警 显示为F 0
全部资料51hei下载地址: |