找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4200|回复: 1
收起左侧

Quartus II EDA频率计设计

  [复制链接]
ID:747475 发表于 2020-5-9 10:51 | 显示全部楼层 |阅读模式
Quartus II9.0 进行的EDA频率计设计
1.png

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档计频。
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.std_logic_arith.all;
  4. use ieee.std_logic_unsigned.all;
  5. entity dw is port(clk:in std_logic;
  6.                   f0:out std_logic;
  7.                   f1:out std_logic;
  8.                   f2:out std_logic);                 
  9. end dw;
  10. architecture body_dw of dw is
  11. begin
  12. process(clk)                               --clk选用1kHz时钟信号
  13.     variable ct:integer range 0 to 2000;
  14.    begin
  15.       if clk'event and clk='1'then                 --分频周期为2s的脉冲
  16.         ct:=ct+1;
  17.        if ct=2000 then ct:=0;
  18.      end if;
  19.      if ct<1000 then f0<='1';              
  20.      elsif ct<2000 then f0<='0';                --f0为0.5Hz高电平为1s
  21.      end if;
  22.      if ct<100 then f1<='1';
  23.      elsif ct<2000 then f1<='0';                --f1为0.5Hz高电平为0.1s
  24.      end if;
  25.      if ct<10 then f2<='1';
  26.      elsif ct<2000 then f2<='0';                --f2为0.5Hz高电平为0.01s
  27.      end if;      
  28.     end if;                                    
  29.   end process;
  30. end body_dw;
复制代码


(可打印)
  
仿真波形(可打印)
对波形的分析说明:
Ct为整数计数,检测到clk上升沿时则加一计数,f0,f1,f2根据ct计数结果分频输出所需脉冲。
3.2 自动换档模块设计
              f0,f1,f2为各档位计频信号
                      td为换挡信号
                      f为所选档位输出的测频信号
                      sel输出档位选择信号,用以小数点位置控制
                      alarm为999kHz溢出报警
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.std_logic_arith.all;
  4. use ieee.std_logic_unsigned.all;
  5. entity xz is port(f0:in std_logic;
  6.                   f1:in std_logic;
  7.                   f2:in std_logic;
  8.                   td:in std_logic_vector(1 downto 0);
  9.                    f:out std_logic;
  10.                    alarm:out std_logic;
  11.                   sel:out std_logic_vector(1 downto 0));     --输出档位选择信号
  12. end xz;
  13. architecture body_xz of xz is
  14. begin
  15. process(td,f0)
  16. variable dwxz:std_logic_vector(1 downto 0);
  17. begin
  18. if f0'event and f0='1' then           --计数前以0.5Hz信号的上升沿检测是否有换挡信号
  19.   if td="10" then                --换挡信号td为10表示切换到高一档
  20.     if dwxz="10" then alarm<='1';    --如果档位已是最高,则报警
  21.     else dwxz:=dwxz+1;
  22.          alarm<='0';               --正常换挡则消除报警
  23.     end if;
  24. elsif td="01" then               --换挡信号td为01表示切换到低一档
  25.     if dwxz="00" then null;
  26. else dwxz:=dwxz-1;
  27. alarm<='0';
  28.     end if;
  29. else alarm<='0';                      --正常计频,消除报警
  30. end if;
  31. sel<=dwxz;
  32. if dwxz=0 then f<=f0;end if;
  33. if dwxz=1 then f<=f1;end if;
  34. if dwxz=2 then f<=f2;end if;
  35. end process;
  36. 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.png

全部资料51hei下载地址:
频率计.zip (3.3 MB, 下载次数: 85)

评分

参与人数 2黑币 +55 收起 理由
一个土豆 + 5
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:583543 发表于 2020-6-18 11:44 | 显示全部楼层
读数是怎么读的??
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表