1.频率计
频率计又称为频率计数器,是一种专门对被测信号频率进行测量的电子测量仪器。频率计主要由四个部分构成:时基(T)电路、输入电路、计数显示电路以及控制电路。
2.测量方法与基本原理
FPGA 主要完成测量待测信号频率,对输入信号个数和标准信号个数进行计数等工作;或采用测周法测量输入信号脉宽, 对输入待测信号的高电平时间进行计数 。
1.等精度测频
等精度测量法就是人为设定一段时间 ,由被测信号的上升沿来控制闸门的开启和关闭 ,测量精度与被测信号频率无关 ,因而可以保证在整个测量频段内的测量精 度保持不变 。
图示为等精度测量原理时序图, 等精度测频法 同时使用两个计数器分别对待测信号频率 f x 和频标信号频率 f m 在设定的精确门内进行计数, 精确门与预置 门门限时间相同 , f x 的上升沿触发精确门。用两个计数 器在精确门内对 f x 和 f m 分别计数 ,若两个计数器的计数值分别为 M 和 N , 则: 待测信号的频率为: f x =Mf m/N
2.测周法
在一个被测信号的周期内,测量基准时钟的个数,得到被测信号的周期,再将其转化为频率。
3.实验程序
1.RTL:
2.代码
1.计数器:
module CNT
#(parameter CLK_FS = 26'd50_000_000,// 基准时钟频率
parameter MAX = 10'd64) // 定义数据位宽
( //system clock
input clk_fs , // 时钟信号
input rst_n , // 复位信号
//cymometer interface
input clk_fx , // 待测信号
input gate, // 门控信号(与待测时钟同步)
input gate_fs, // 与基准时钟同步的门控信号
input neg_gate_fx,//
input neg_gate_fs,//
output reg [MAX-1:0] fs_cnt , //门控时间内基准时钟信号的个数
output reg [MAX-1:0] fx_cnt , // 门控时间内待测信号的个数
output reg [MAX-1:0] data_fx_temp // 待测信号的频率值
);
reg [MAX-1:0] fs_cnt_temp ; // fs_cnt 计数
reg [MAX-1:0] fx_cnt_temp ; // fx_cnt 计数
//门控时间内待测信号的计数,设置的为5000个,这里重新计数,只是用于检验信号是否正确
always @(posedge clk_fx or negedge rst_n) begin
if(!rst_n) begin
fx_cnt_temp <= 32'd0;
fx_cnt <= 32'd0;
end
else if(gate)begin
fx_cnt_temp <= fx_cnt_temp + 1'b1;
end
else if(neg_gate_fx) begin
fx_cnt_temp <= 32'd0;
fx_cnt <= fx_cnt_temp;
end
end
//门控时间内基准时钟的计数
always @(posedge clk_fs or negedge rst_n) begin
if(!rst_n) begin
fs_cnt_temp <= 32'd0;
fs_cnt <= 32'd0;
end
else if(gate_fs)
begin
fs_cnt_temp <= fs_cnt_temp + 1'b1;
end
else if(neg_gate_fs) begin
fs_cnt_temp <= 32'd0;
fs_cnt <= fs_cnt_temp;
end
end
//计算待测信号的频率值
always @(posedge clk_fs or negedge rst_n) begin
if(!rst_n) begin
data_fx_temp <= 64'd0;
end
else if(gate_fs == 1'b0)
data_fx_temp <=CLK_FS*fx_cnt/fs_cnt;
end
endmodule
2.门控 :
module gate
(
input clk_fs , // 基准时钟信号
input rst_n , // 复位信号
//cymometer interface
input clk_fx ,//待测信号
output reg gate , //门控信号
output reg gate_fs // 同步到基准时钟的门控信号
);
localparam GATE_TIME = 16'd5_000; // 门控时间设置
reg [15:0] gate_cnt ; // 门控计数
reg gate_fs_r ; // 用于同步gate信号的寄存器
//门控信号计数器,使用被测时钟计数
always @(posedge clk_fx or negedge rst_n) begin
if(!rst_n)
gate_cnt <= 16'd0;
else if(gate_cnt == GATE_TIME + 5'd20)
gate_cnt <= 16'd0;
else
gate_cnt <= gate_cnt + 1'b1;
end
//门控信号,拉高时间为GATE_TIME个实测时钟周期
always @(posedge clk_fx or negedge rst_n) begin
if(!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) begin
if(!rst_n) begin
gate_fs_r <= 1'b0;
gate_fs <= 1'b0;
end
else begin
gate_fs_r <= gate;
gate_fs <= gate_fs_r;
end
end
endmodule
3.边沿检测:
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) begin
if(!rst_n) begin
gate_fx_d0 <= 1'b0;
gate_fx_d1 <= 1'b0;
end
else begin
gate_fx_d0 <= gate;
gate_fx_d1 <= gate_fx_d0;
end
end
//打拍采门控信号的下降沿(基准时钟)
always @(posedge clk_fs or negedge rst_n) begin
if(!rst_n) begin
gate_fs_d0 <= 1'b0;
gate_fs_d1 <= 1'b0;
end
else begin
gate_fs_d0 <= gate_fs;
gate_fs_d1 <= gate_fs_d0;
end
end
endmodule
4.顶层:
按照DE0手册分配管脚 :