凡亿专栏 | FPGA与信号频率测量——等精度测频法
FPGA与信号频率测量——等精度测频法

1.为什么用等精度测频法:

      在使用直接测频法时,相对误差会随着待测信号的频率下降而上升,因此该法仅适用于高频信号测量;在使用周期测频法时,相对误差会随着待测信号的频率上升而上升,因此该法仅适用于低频信号测量。为同时满足对高、低频信号的测量需求,产生了等精度测频法,这一方法的相对误差与待测信号频率无关。

2.等精度测频法思路:


      图1.等精度测频法时序图

    等精度测频法仍采用闸门计数的基本方法,闸门信号分为预置闸门和实际闸门两种。预置闸门信号由系统时钟计数产生,宽度是人为设定的;实际闸门信号由预置闸门信号经待测信号采样后得到,与待测信号保持同步且宽度是待测信号的整数倍(这是实现等精度的关键),是真正控制测频计数器的闸门信号。

    在实际闸门信号的控制下,两个计数器分别对待测信号fx和基准时钟fs进行计数,得到计数结果Nx和Ns。由于计数时间是一致的,故得到的计数结果与被计数信号的频率成正比,可根据如下公式计算出待测信号频率:


3.误差分析:

     实际闸门信号与待测信号保持同步,且宽度为待测信号的整数倍,这一特点消除了待测信号计数器的计数偏差,但由于实际闸门信号与基准时钟的关系仍不确定,基准时钟计数器仍可能出现1个单位的计数偏差,故相对误差计算如下(以下Ns指的是基准时钟计数器无计数偏差时的结果):


             图2.相对误差计算

 

    可见,相对误差仅与Ns有关,而Ns=实际闸门宽度t*基准时钟频率fs,是一个与待测信号频率无关的固定值;由此实现了对不同频率待测信号的等精度测量,且闸门宽度越大,基准时钟频率越高,误差越小。(实际闸门宽度t和预置闸门宽度并不严格相等,但二者相差不超过一个待测信号周期,因此通常按二者相等处理。)

 

4.具体实现:

源代码

module f_measurement (clk,rst_p,signal_in,f_signal,f_clk);

input clk;                    /*板载时钟50M*/

input rst_p;                 /*高电平复位信号*/

input signal_in;              /*待测信号*/

outputreg[25:0] f_clk;      /*基准时钟计数结果*/

outputreg[25:0] f_signal;   /*待测信号计数结果*/

 

reg[25:0] div_cnt;          /*分频计数量*/

reg en_advance;               /*预置闸门信号*/

reg en;                       /*实际闸门信号*/

reg[25:0] f_signal_cnt,f_clk_cnt;

 

/*分频产生周期为2s的预置闸门信号*/

always@(posedge clk orposedge rst_p)

begin

     if(rst_p)

       begin

           div_cnt<=26'd0;<>

           en_advance<=0;<>

       end

     else

       begin

           if(div_cnt==26'd49999999)

             begin

                 div_cnt<=0;<>

                 en_advance<=!en_advance;<>

             end    

           else

             begin

               div_cnt<=div_cnt+1;<>

                 en_advance<=en_advance;<>

               end

       end

end

 

/*用待测信号对预置闸门信号进行采样,得到实际闸门信号*/

always@(posedge signal_in orposedge rst_p)

begin

  if(rst_p)

    en<=0;<>

  else

    en<=en_advance;<>

end

 

/*测量实际闸门信号高电平时间内待测信号上升沿的个数*/

always@(posedge signal_in orposedge rst_p)

begin

  if(rst_p)

    f_signal_cnt<=27'd0;<>

  else

    begin

        if(en)

            f_signal_cnt<=f_signal_cnt+27'd1;<>

          else

            f_signal_cnt<=27'd0;<>

      end

end

/*测量实际闸门信号高电平时间内基准时钟上升沿的个数*/

always@(posedge clk orposedge rst_p)

begin

  if(rst_p)

    f_clk_cnt<=27'd0;<>

  else

    begin

        if(en)

            f_clk_cnt<=f_clk_cnt+27'd1;<>

          else

            f_clk_cnt<=27'd0;<>

      end

end

/*在实际闸门信号下降沿处更新测量数据*/

always@(negedge en orposedge rst_p)

begin

  if(rst_p)

    begin

      f_signal<=27'd0;<>

          f_clk<=27'd0;<>

    end

  else

    begin

        f_signal<=f_signal_cnt;<>

          f_clk<=f_clk_cnt;<>

      end

end

endmodule

仿真激励

`timescale1 ns/1 ps

module f_measurement_vlg_tst();

reg clk;

reg rst_p;

reg signal_in;                                            

wire[25:0]  f_clk;

wire[25:0]  f_signal;

                      

f_measurement i1 (

     .clk(clk),

     .f_clk(f_clk),

     .f_signal(f_signal),

     .rst_p(rst_p),

  .signal_in(signal_in)

);

initial                                            

begin                                           

  rst_p=1;

  clk=0;

  signal_in=0;

  #20.1

  rst_p=0;                   

end                                             

always                                          

begin                                            

#10

clk=!clk;                                     

end     

always                                         

begin                                           

#200

signal_in=!signal_in;/*2.5MHz的待测信号*/                                    

end

endmodule


可计算得,待测信号频率=50M*2500000/50000000=2.5MHz,与设定值一致。

 

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表凡亿课堂立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。
相关阅读
进入分区查看更多精彩内容>
精彩评论

暂无评论