凡亿专栏 | FPGA与信号频率测量——周期测频法
FPGA与信号频率测量——周期测频法

1.为什么用周期测频法:

使用直接测频法测量低频信号时,不仅会带来较大的相对误差,而且为兼顾测量需求(闸门宽度要大于待测信号周期)与数据更新周期,需根据待测低频信号的频率范围人为设定相应的闸门宽度,导致程序不够灵活。因此,引入周期测频法对低频信号进行测量。

2.周期测频法思路:

周期测频法仍采用闸门计数的基本方法,但此时是以待测信号为闸门,控制基准时钟进行计数,来得到待测信号一个周期所持续的时间。

网络上的一些资料在使用周期测频法时,仅在待测信号的高电平部分进行计数,再将计数值扩大二倍作为待测信号周期,这种方法仅在待测信号占空比为50%时(如图1)才能得到正确结果。在图2这种待测信号占空比不定的情况下,无法确定高低电平时间之比,需要对待测信号的完整周期进行测量。

在此处,采用双计数器的形式,分别在待测信号高、低电平时进行计数,并在待测信号上升沿处将两个计数结果求和后作为结果输出。

 

511224579abf6f27916935a741c143.jpg

图1.待测信号占空比为50%时


957a829b2137a2c0b3c19f7207fb57.jpg

图2.待测信号占空比不为50%时

3.误差分析:

出于和直接测频法相同的原因,被计数量仍会出现一定的绝对误差。为减小相对误差,需要增大计数结果,这里可以采用提高基准时钟频率的方式。

4.具体实现:

源代码

module f_measurement (clk,rst_p,signal_in,T);

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

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

input signal_in;         /*待测信号,1mHz——1Hz*/

outputreg[35:0] T;     /*T最大值=待测信号最长周期/基准时钟周期*/

 reg[35:0] T_high,T_low,T_high_reg;

 /*测量待测信号高电平宽度*/

always@(posedge clk orposedge rst_p)

begin

  if(rst_p)

    T_high<=36'd0;<>

  else

    begin

       if(signal_in)

           T_high<=t_high+36'd1;<>

         else

           T_high<=36'd0;<>

     end

end

/*寄存高电平宽度数据(在待测信号变为低电平后,高电平计数器会清零,需要将计数结果进行存储,等待待测信号出现上升沿时使用)*/

always@(negedge signal_in orposedge rst_p)

begin

  if(rst_p)

    T_high_reg<=36'd0;<>

  else

    T_high_reg<=t_high;<>

end

/*测量待测信号低电平宽度*/

always@(posedge clk orposedge rst_p)

begin

  if(rst_p)

    T_low<=36'd0;<>

  else

    begin

       if(!signal_in)

           T_low<=t_low+36'd1;<>

         else

           T_low<=36'd0;<>

     end

end

/*待测信号上升沿更新测量结果*/

always@(posedge signal_in orposedge rst_p)

begin

  if(rst_p)

    T<=36'd0;<>

  else

    T<=t_high_reg+t_low;<>

end

 endmodule

仿真激励

`timescale1 ns/1 ps

module f_measurement_vlg_tst();

reg clk;

reg rst_p;

reg signal_in;                                 wire[35:0]  T;

f_measurement i1 (

    .T(T),

    .clk(clk),

    .rst_p(rst_p),

.signal_in(signal_in));

 initial                                            begin                                

rst_p=1;

  clk=0;

  #20.1

  rst_p=0;                 

end 

 initial                                            begin  

  /*0.25Hz,占空比75%的待测信号*/

 signal_in=1;                                      #3000000000

  signal_in=0; 

  #1000000000

  signal_in=1;

end

always                                            begin                                            #10

clk=!clk;                                     

end  

endmodule

可见,此时测量结果为199999999个基准时钟周期,即待测信号周期=199999999*20ns=3.99999998s,与其真实频率0.25Hz基本保持一致,达到了测量效果。(浮点乘除运算不是FPGA所擅长的,此处仅对信号周期进行测量,将结果传递至单片机,通过除法计算频率

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

暂无评论