日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于FPGA的频率计

發(fā)布時間:2024/3/12 编程问答 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于FPGA的频率计 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1 簡介

頻率計又稱為頻率計數(shù)器,是一種專門對被測信號頻率進行測量的電子測量儀器。

2 傳統(tǒng)測量法

傳統(tǒng)測量法有兩種:周期測量法頻率測量法

2.1 周期測量法

  • 原理:先測出被測信號的周期 TTT,然后根據(jù)頻率 f=1Tf=\frac{1}{T}f=T1? 求出被測信號的頻率。
  • 實現(xiàn)方法:數(shù)一個被測信號的周期內有多少個基準時鐘,用基準時鐘的總周期數(shù)來代替被測信號的周期 TTT

    誤差:被測信號和基準時鐘存在一定的錯位 △t△tt。但假如被測信號的頻率比較低,脈沖寬度很寬,當基準時鐘頻率很低,與被測時鐘頻率相差較大時,相對誤差比較小。
  • 周期測量法適合低頻信號頻率測量。

    2.2 頻率測量法

  • 原理:在時間 ttt 內對被測信號的脈沖數(shù) NNN 進行計數(shù),然后求出單位時間的脈沖數(shù)即為被測信號的頻率。
  • 實現(xiàn)方法:在基準時鐘的時間 ttt 內,數(shù)有多少個被測信號的脈沖。脈沖數(shù)除以 ttt 即為被測信號的頻率。

    誤差:被測信號和基準時鐘存在一定的錯位。但假如被測信號的頻率比較高,每個脈沖寬度很窄,當采樣寬度足夠寬時,誤差就會比較小。
  • 頻率測量法適合高頻信號頻率測量。


    3 等精度測量法

    3.1 原理:


    圖中,gategategate 信號為門控信號,它的持續(xù)時間 GateGateGate_timetimetime 為整數(shù)倍的被測信號周期。clkclkclk _ fxf_xfx?為被測信號(公式中表示被測信號頻率),clkclkclk _ fsf_sfs?為基準時鐘(公式中表示基準時鐘信號頻率)。

    由:
    被測信號周期個數(shù)×被測信號周期長度被測信號周期個數(shù) × 被測信號周期長度數(shù)×
    =基準時鐘周期個數(shù)×基準時鐘周期長度= 基準時鐘周期個數(shù) × 基準時鐘周期長度=數(shù)×
    =Gate= Gate=Gate_timetimetime
    可以推導出最終被測信號頻率的計算公式

    clkclkclk _ fxfxfx ===clk?fsfs?cnt?\frac{clk-fs}{fs-cnt}·fs?cntclk?fs?? fxfxfx _ cntcntcnt

    誤差:只會差一個基準時鐘周期。只要 GateGateGate_timetimetime 足夠大,相對誤差就可以忽略。

    3.2 代碼實現(xiàn)

    頂層設計模塊:

    module top_cymometer(//system clockinput sys_clk , // 時鐘信號(系統(tǒng)時鐘,50MHz)input sys_rst_n, // 復位信號input clk_fx , // 被測時鐘output [7:0] led0,output [7:0] led1,output [7:0] led2,output [7:0] led3,output [63:0]data_fx );//parameter define parameter CLK_FS = 26'd50000000; // 基準時鐘頻率值gate//生成門控信號 (.clk_fs (sys_clk ), // 基準時鐘信號.rst_n (sys_rst_n), // 復位信號//cymometer interface.clk_fx (clk_fx ), //待測信號.gate(gate ) , //門控信號.gate_fs(gate_fs) // 同步到基準時鐘的門控信號);pexg//邊沿捕獲 (.clk_fs (sys_clk ), // 基準時鐘信號.rst_n (sys_rst_n), // 復位信號.gate(gate ) , //門控信號.gate_fs(gate_fs), // 同步到基準時鐘的門控信號.clk_fx (clk_fx), //待測信號.neg_gate_fs(neg_gate_fs),.neg_gate_fx(neg_gate_fx));cnt (//system clock.clk_fs (sys_clk ), // 基準時鐘信號.rst_n (sys_rst_n), // 復位信號//cymometer interface.clk_fx (clk_fx ), //待測信號.gate(gate ) ,//門控信號.gate_fs(gate_fs) ,// 同步到基準時鐘的門控信號.neg_gate_fs(neg_gate_fs),.neg_gate_fx(neg_gate_fx),.fs_cnt(fs_cnt) , // 門控時間內基準時鐘的計數(shù)值.fx_cnt(fx_cnt) , // 門控時間內被測時鐘的計數(shù)值 .data_fx_temp(data_fx) ); endmodule

    gate模塊:產(chǎn)生周期是待測信號周期整數(shù)倍(代碼中為5000倍)的門信號gate

    module gate (input clk_fs , // 基準時鐘信號input rst_n , // 復位信號//cymometer interfaceinput clk_fx ,//待測信號output reg gate , //門控信號output reg gate_fs // 同步到基準時鐘的門控信號);localparam GATE_TIME = 16'd5_000; // 門控時間設置 reg [15:0] gate_cnt ; // 門控計數(shù)reg gate_fs_r ; // 用于同步gate信號的寄存器//門控信號計數(shù)器,使用被測時鐘計數(shù) always @(posedge clk_fx or negedge rst_n) beginif(!rst_n)gate_cnt <= 16'd0; else if(gate_cnt == GATE_TIME + 5'd20)gate_cnt <= 16'd0;elsegate_cnt <= gate_cnt + 1'b1; end//門控信號,拉高時間為GATE_TIME個實測時鐘周期 always @(posedge clk_fx or negedge rst_n) beginif(!rst_n)gate <= 1'b0;else if(gate_cnt < 4'd10)gate <= 1'b0; else if(gate_cnt < GATE_TIME + 4'd10)gate <= 1'b1;else if(gate_cnt <= GATE_TIME + 5'd20)gate <= 1'b0;else gate <= 1'b0; end//將門控信號同步到基準時鐘下 always @(posedge clk_fs or negedge rst_n) beginif(!rst_n) begingate_fs_r <= 1'b0;gate_fs <= 1'b0;endelse begingate_fs_r <= gate;gate_fs <= gate_fs_r;end end endmodule

    pexg模塊:用來捕獲gate信號和基準時鐘信號的低電平

    module pexg (input clk_fs , // 基準時鐘信號input rst_n , // 復位信號input clk_fx , input gate,input gate_fs , output neg_gate_fs,output neg_gate_fx); reg gate_fs_d0 ; // 用于采集基準時鐘下gate下降沿 reg gate_fs_d1 ; // reg gate_fx_d0 ; // 用于采集被測時鐘下gate下降沿 reg gate_fx_d1 ; // //wire define//邊沿檢測,捕獲信號下降沿 assign neg_gate_fs = gate_fs_d1 & (~gate_fs_d0); assign neg_gate_fx = gate_fx_d1 & (~gate_fx_d0);//打拍采門控信號的下降沿(被測時鐘) always @(posedge clk_fx or negedge rst_n) beginif(!rst_n) begingate_fx_d0 <= 1'b0;gate_fx_d1 <= 1'b0;endelse begingate_fx_d0 <= gate;gate_fx_d1 <= gate_fx_d0;end end//打拍采門控信號的下降沿(基準時鐘) always @(posedge clk_fs or negedge rst_n) beginif(!rst_n) begingate_fs_d0 <= 1'b0;gate_fs_d1 <= 1'b0;endelse begingate_fs_d0 <= gate_fs;gate_fs_d1 <= gate_fs_d0;end end endmodule

    cnt模塊:用來計數(shù),得到 fsfsfs _ cntcntcntfxfxfx _ cntcntcnt

    module cnt#(parameter CLK_FS = 26'd50_000_000,// 基準時鐘頻率parameter MAX = 10'd64) // 定義數(shù)據(jù)位寬 ( //system clockinput clk_fs , // 時鐘信號input rst_n , // 復位信號//cymometer interfaceinput clk_fx , // 待測信號input gate, // 門控信號(與待測時鐘同步)input gate_fs, // 與基準時鐘同步的門控信號input neg_gate_fx,//input neg_gate_fs,//output reg [MAX-1:0] fs_cnt , //門控時間內基準時鐘信號的個數(shù) output reg [MAX-1:0] fx_cnt , // 門控時間內待測信號的個數(shù)output reg [MAX-1:0] data_fx_temp // 待測信號的頻率值 );reg [MAX-1:0] fs_cnt_temp ; // fs_cnt 計數(shù) reg [MAX-1:0] fx_cnt_temp ; // fx_cnt 計數(shù)//門控時間內待測信號的計數(shù),設置的為5000個,這里重新計數(shù),只是用于檢驗信號是否正確 always @(posedge clk_fx or negedge rst_n) beginif(!rst_n) beginfx_cnt_temp <= 32'd0;fx_cnt <= 32'd0;endelse if(gate)beginfx_cnt_temp <= fx_cnt_temp + 1'b1;end else if(neg_gate_fx) beginfx_cnt_temp <= 32'd0;fx_cnt <= fx_cnt_temp;end end//門控時間內基準時鐘的計數(shù) always @(posedge clk_fs or negedge rst_n) beginif(!rst_n) beginfs_cnt_temp <= 32'd0;fs_cnt <= 32'd0;endelse if(gate_fs)beginfs_cnt_temp <= fs_cnt_temp + 1'b1;endelse if(neg_gate_fs) beginfs_cnt_temp <= 32'd0;fs_cnt <= fs_cnt_temp;end end //計算待測信號的頻率值 always @(posedge clk_fs or negedge rst_n) beginif(!rst_n) begindata_fx_temp <= 64'd0;endelse if(gate_fs == 1'b0)data_fx_temp <=CLK_FS*fx_cnt/fs_cnt; endendmodule

    RTL視圖:

    3.4 實際測量

    按照DE0手冊分配管腳
    (注意:Quartus 18.1中沒有DE0設備Cyclone III EP3C16F484,舊版Quartus 9.1中有,于是重新下載9.1版本。。)


    分配管腳:

    分配完成后,重新運行程序,然后將程序加載在開發(fā)板上。

    將電腦、開發(fā)板和信號發(fā)生器連接:

    100Hz:

    500Hz:

    1kHz:




    signaltap結果:

    10kHz:

    1MHz:


    出現(xiàn)了誤差。

    總結

    以上是生活随笔為你收集整理的基于FPGA的频率计的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。