找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4642|回復(fù): 1
收起左側(cè)

Quartus II EDA頻率計設(shè)計

  [復(fù)制鏈接]
ID:747475 發(fā)表于 2020-5-9 10:51 | 顯示全部樓層 |閱讀模式
Quartus II9.0 進行的EDA頻率計設(shè)計
1.png

1、頻率計的測量范圍為1MHz,量程分10KHz、100KHz和1000KHz三檔(最大讀數(shù)分別為9.99KHz、99.9KHz、999KHz)。
2、當(dāng)讀數(shù)大于999時,頻率計處于超量程狀態(tài)。此時顯示器發(fā)出溢出指示(最高位顯示F,其余各位不顯示數(shù)字),下一次測量時,量程自動增大一檔。讀數(shù)小于000時,頻率計處于欠量程狀態(tài)。下次測量時,量程減小一檔。
3、要求實現(xiàn)溢出報警功能。即當(dāng)頻率高于999KHz時,頻率計處于超量程狀態(tài),產(chǎn)生一報警信號,點亮LED燈,從而實現(xiàn)溢出報警功能。
4、用記憶顯示方式,即計數(shù)過程中不顯示數(shù)據(jù),待計數(shù)過程結(jié)束后,顯示計數(shù)結(jié)果,并將此顯示結(jié)果保持到下一次計數(shù)結(jié)束。顯示時間應(yīng)不小于1秒,小數(shù)點位置隨量程變更自動移位。
2. 系統(tǒng)總體設(shè)計
本設(shè)計采用的是直接測頻率的方法。即測頻率法就是在一定的時間間隔內(nèi)TW內(nèi),得到這個周期信號重復(fù)變化的次數(shù)NX,則被測頻率可表示為FX=NX/TW。
頻率計的系統(tǒng)設(shè)計可以分為計頻基準時鐘模塊、自動換檔模塊、4位10進制計數(shù)模塊鎖存模塊、譯碼顯示模塊。
計頻基準時鐘模塊:
以1kHZ為基準,產(chǎn)生三個不同占比的0.5Hz脈沖信號其高電平時間分別為1s、0.1s、0.01s,分別用以測量頻率在0~9.99KHz、0~99.9KHz、0~999KHz的頻率。
自動換檔模塊:
   先以最低檔位測量,溢出時下一次計數(shù)自動切換高檔位,計數(shù)不滿“000”下一次自動切換到低檔位。計數(shù)溢出999khz時,發(fā)出警報。
四位10進制計數(shù)模塊鎖存模塊:
   四位十進制計數(shù),檔位基準信號為高電平時,開始計數(shù),低電平時鎖存輸出計數(shù)結(jié)果的前三位,計數(shù)器清零。當(dāng)溢出或計數(shù)不滿時,輸出換擋信號。計數(shù)刷新頻率為0.5Hz。
譯碼顯示模塊:
將計數(shù)器輸出的結(jié)果按位譯成7段顯示數(shù)碼管對應(yīng)數(shù)字碼,根據(jù)所選檔位信號設(shè)置小數(shù)點位置。刷新頻率為
  
系統(tǒng)框圖(可打。
3. 系統(tǒng)詳細設(shè)計
3.1 計頻基準時鐘模塊設(shè)計
               
該模塊的電路框圖
                            各輸入輸出引腳的定義及作用
Clk:為基準時鐘信號,選用1kHz時鐘信號
F0:根據(jù)clk分頻出的0.5Hz高電平為1s的計頻信號,用以0~9.99kHz檔計頻。
F1:根據(jù)clk分頻出的0.5Hz高電平為0.1s的計頻信號,用以0~99.9kHz檔計頻。
F2:根據(jù)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;
復(fù)制代碼


(可打。
  
仿真波形(可打。
對波形的分析說明:
Ct為整數(shù)計數(shù),檢測到clk上升沿時則加一計數(shù),f0,f1,f2根據(jù)ct計數(shù)結(jié)果分頻輸出所需脈沖。
3.2 自動換檔模塊設(shè)計
              f0,f1,f2為各檔位計頻信號
                      td為換擋信號
                      f為所選檔位輸出的測頻信號
                      sel輸出檔位選擇信號,用以小數(shù)點位置控制
                      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           --計數(shù)前以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;
復(fù)制代碼



開始時量程輸出為(檔位選擇)sel=“00”,即最小檔,輸出f為f0,當(dāng)接收到(調(diào)檔)td=“10”切換高一檔,sel變?yōu)椤?0”。
3.3 四位10進制計數(shù)鎖存模塊設(shè)計
                          
                           M輸入被測量信號
                           En輸入測量脈沖,高電平時開始計頻率,低電平輸出鎖存結(jié)果。
                            q3,q2,q1為鎖存的計頻結(jié)果。
                           Td在溢出和欠量程時候輸出調(diào)檔信號。
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);     --四位十進制計數(shù)
begin
if en='1' then                                    --當(dāng)計頻脈沖為1是開始計數(shù)
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;                   --計數(shù)結(jié)果實時緩存至b1,b2,b3
b2<=w2;
b3<=w3;
       end if ;
    end if ;
     if en='0'then      
q1<=b1;                    --en檔位脈沖為低電平時b1,b2,b3結(jié)果為最終值,保持不變
q2<=b2;                    --將結(jié)果輸出至Q1,Q2,Q3
q3<=b3;                    --當(dāng)下一次低電平時,刷新計數(shù)結(jié)果
       w0:="0000";
       w1:="0000";          --低電平時,計數(shù)器清零
       w2:="0000";
       w3:="0000";
    end if;
end process;
process(en)                    --計數(shù)一結(jié)束,以下降沿觸發(fā)判斷是否欠量程或則溢出
begin                         --并輸出相應(yīng)調(diào)檔信號
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被測脈沖設(shè)置為0~5s 50Hz;5~10s 10000Hz;10~13s 100000Hz;
第一個測量脈沖判定結(jié)果為欠量程,調(diào)檔信號TD輸出01,調(diào)低檔位
第三個脈沖檢測判定10.0kHz,在量程范圍,調(diào)檔不做輸出
第六個脈沖檢測判定100kHz,溢出,調(diào)檔TD輸出10,調(diào)高檔位

3.4 譯碼模塊
                            Clk為1kHz時鐘信號,用以觸發(fā)賦值語句等
                            Sel為檔位信號
                            Q1,Q2,Q3為計數(shù)器鎖存結(jié)果輸入
                            LED0,LED1,LED2為三位結(jié)果的譯碼輸出

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檔小數(shù)點賦值
                 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檔小數(shù)點
                 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檔小數(shù)點
                 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;

設(shè)置0~2s 輸出為1017,溢出,LED2輸出F的段碼,兩外兩個消隱。
設(shè)置2s后輸出217,按照(量程選擇)sel=0時,為0~9.99khz,小數(shù)點在高位即led2[7]為1。
3.4 顯示模塊
                                  Clk:動態(tài)顯示觸發(fā)信號,1khz每一個點亮一個數(shù)碼管,三個循環(huán),其頻率顯然大于人眼可識別。
                                  Led0,led1,led2:為譯碼輸出的數(shù)碼管顯示信號。
                                  Ledag,sel:為動態(tài)顯示



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. 系統(tǒng)調(diào)試
4.1 系統(tǒng)總體仿真
系統(tǒng)總體輸入輸出引腳的定義及作用
   仿真波形(可打印)
M在0~6s 設(shè)置為1000Hz
讀取波形led為1.00kHz

M在6~12s 設(shè)置為100khz
讀取顯示應(yīng)為100.khz


M在6~12s 設(shè)置為1mhz
Alarm 溢出報警
顯示為F 0

51hei.png

全部資料51hei下載地址:
頻率計.zip (3.3 MB, 下載次數(shù): 85)

評分

參與人數(shù) 2黑幣 +55 收起 理由
一個土豆 + 5
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報

ID:583543 發(fā)表于 2020-6-18 11:44 | 顯示全部樓層
讀數(shù)是怎么讀的??
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表