08_基于FPGA的测頻计的设计

08_基于FPGA的测頻计的设计

实验原理

所谓"频率",就是周期性信号在单位时间()内变化的次数。若在一定的时间间隔T内计数,计得某周期性信号的重复变化次数为N,则该信号的频率可表达为:

f = N / T

所以测量频率就要分别知道NT的值,由此,测量频率的方法一般有三种:测频方法、测周方法和等精度测量。

测频方法:这种方法即已知时基信号(频率或周期确定)做门控信号,T为已知量,然后在门控信号有效的时间段内进行输入脉冲的计数,原理图如下图所示:

测频方法原理图

首先,被测信号①(以正弦波为例)经过放大整形后转变成方波脉冲②,其重复频率等于被测信号频率。把方波脉冲②加到闸门的输入端。由一个高稳定的石英振荡器和一系列数字分频器组成了时基信号发生器,它输出时间基准(或频率基准)信号③去控制门控电路形成门控信号④,门控信号的作用时间T是非常准确的(由石英振荡器决定)。门控信号控制闸门的开与闭,只有在闸门开通的时间内,方波脉冲②才能通过闸门成为被计数的脉冲⑤由计数器计数。闸门开通的时间称为闸门时间,其长度等于门控信号作用时间T。比如,时间基准信号的重复周期为1S,加到闸门的门控信号作用时间T亦准确地等于1S,即闸门的开通时间——"闸门时间"为1S。在这一段时间内,若计数器计得N=100000个数,根据公式f = N / T,那么被测频率就是100000Hz。如果计数式频率计的显示器单位为"KHz",则显示100.000KHz,即小数点定位在第三位。不难设想,若将闸门时间设为T=0.1S,则计数值为10000,这时,显示器的小数点只要根据闸门时间T的改变也随之自动往右移动一位(自动定位),那么,显示的结果为100.00Khz。在计数式数字频率计中,通过选择不同的闸门时间,可以改变频率计的测量范围和测量精度。

测周方法:

被测信号(频率或周期待测)做门控信号,T为未知量,做门控信号T,然后在门控信号有效的时间段内对时基信号脉冲计数,原理图如下图所示:

计数器测周的基本原理刚好与测频相反,即由被测信号控制主门开门,而用时标脉冲进行计数,所以实质上也是一种比较测量方法。

等精度测量法:

等精度测量法的核心思想是通过闸门信号与被测信号同步,将闸门时间τ控制为被测信号周期长度的整数倍。测量时,先打开预置闸门,当检测到被测信号脉冲沿到达时,标准信号时钟开始计数。预置闸门关闭时,标准信号并不立即停止计数,而是等检测到被测信号脉冲沿到达时才停止,完成被测信号整数个周期的测量。测量的实际闸门时间可能会与预置闸门时间不完全相同,但最大差值不会超过被测信号的一个周期。

在等精度测量法中,相对误差与被测信号本身的频率特性无关,即对整个测量域而言,测量精度相等,因而称之为"等精度测量"。标准信号的计数值越大则测量相对误差越小,即提高门限时间τ和标准信号频率可以提高测量精度。在精度不变的情况下,提高标准信号频率可以缩短门限时间,提高测量速度。

设计的原理框图:

 

硬件原理图

外扩引脚原理图:选择两个IO口,一个作为时钟输出(测试源),另一个作为时钟输入

IO设置为:

 

实验代码

/********************************版权声明**************************************

** 大西瓜团队

**

**----------------------------文件信息--------------------------

** 文件名称: text_f.v

** 创建日期:

** 功能描述:数字频率计

** 硬件平台:大西瓜第三代开发板,http://daxiguafpga.taobao.com

** 版权声明:本代码属个人知识产权,本代码仅供交流学习.

**---------------------------修改文件的相关信息----------------

** 修改人:

** 修改日期:    

** 修改内容:

*******************************************************************************/

module text_f(sysclk,inclk,seg_duan,seg_wei,outclk);

input sysclk,inclk;//系统时钟

output [7:0] seg_duan,seg_wei;//输入时钟

output outclk;

wire sysclk,inclk;//系统时钟

reg [7:0] seg_duan,seg_wei;//输入时钟

 

reg [24:0] clk_counter;//时钟计数

reg clk_div;//分频后的时钟

 

reg [7:0] data;

reg [3:0] counter1,counter2,counter3,counter4,counter5,counter6,counter7,counter8;

reg [3:0] count1,count2,count3,count4,count5,count6,count7,count8;

 

reg [14:0] counter;

reg test_clk;

assign outclk=test_clk;

/***********************产生测试时钟**************************************/

always @(posedge sysclk)

begin

if(counter==15'b110_0001_1010_1000)

begin

test_clk<=~test_clk;//500HZ

counter<=15'b0;

end

else

counter<=counter+1'b1;

end

/**********************产生1HZ的时钟************************************/

always @(posedge sysclk)

begin

if(clk_counter==25'b1_0111_1101_0111_1000_0100_0000)

begin

clk_div<=~clk_div;

clk_counter<=25'b0;

end

else

clk_counter<=clk_counter+1'b1;

end

/*********************测试待测信号***********************************/

always @(posedge inclk)

begin

if(clk_div)

begin

if(counter1==4'b1001)

begin

counter1<=4'b0;

counter2<=counter2+1'b1;

if(counter2==4'b1001)

begin

counter2<=4'b0;

counter3<=counter3+1'b1;

if(counter3==4'b1001)

begin

counter3<=4'b0;

counter4<=counter4+1'b1;

if(counter4==4'b1001)

begin

counter4<=4'b0;

counter5<=counter5+1'b1;

if(counter5==4'b1001)

begin

counter5<=4'b0;

counter6<=counter6+1'b1;

if(counter6==4'b1001)

begin

counter6<=4'b0;

counter7<=counter7+1'b1;

if(counter7==4'b1001)

begin

counter7<=4'b0;

counter8<=counter8+1'b1;

if(counter8==4'b1001)

begin

counter8<=4'b0;

end

end

end

end

end

end

end

end

else

counter1<=counter1+1'b1;

end

else

/*******************测试结果寄存********************************/

begin

if(counter1!=4'b0000|counter2!=4'b0000!=4'b0000|counter3!=4'b0000|counter4!=4'b0000|

counter5!=4'b0000|counter6!=4'b0000|counter7!=4'b0000|counter8!=4'b0000)

begin

count1<=counter1;

count2<=counter2;

count3<=counter3;

count4<=counter4;

count5<=counter5;

count6<=counter6;

count7<=counter7;

count8<=counter8;

 

counter1<=4'b0000;

counter2<=4'b0000;

counter3<=4'b0000;

counter4<=4'b0000;

counter5<=4'b0000;

counter6<=4'b0000;

counter7<=4'b0000;

counter8<=4'b0000;

end

end

end

/*****************测试结果数码管显示*************************/

always @(clk_counter , count1 , count2 , count3 , count4 , count5 , count6 , count7 , count8,data)

begin

case(clk_counter[15:13])//数码管位扫描

3'b000:begin seg_wei<=8'b1111_1110;data<=count1;end

3'b001:begin seg_wei<=8'b1111_1101;data<=count2;end

3'b010:begin seg_wei<=8'b1111_1011;data<=count3;end

3'b011:begin seg_wei<=8'b1111_0111;data<=count4;end

3'b100:begin seg_wei<=8'b1110_1111;data<=count5;end

3'b101:begin seg_wei<=8'b1101_1111;data<=count6;end

3'b110:begin seg_wei<=8'b1011_1111;data<=count7;end

3'b111:begin seg_wei<=8'b0111_1111;data<=count8;end

default:begin seg_wei<=8'bx;data<=4'bx;end

endcase

 

case(data[3:0])//数码管显示

4'b0000:begin seg_duan<=8'b1100_0000;end//0

4'b0001:begin seg_duan<=8'b1111_1001;end//1

4'b0010:begin seg_duan<=8'b1010_0100;end//2

4'b0011:begin seg_duan<=8'b1011_0000;end//3

4'b0100:begin seg_duan<=8'b1001_1001;end//4

4'b0101:begin seg_duan<=8'b1001_0010;end//5

4'b0110:begin seg_duan<=8'b1000_0010;end//6

4'b0111:begin seg_duan<=8'b1111_1000;end//7

4'b1000:begin seg_duan<=8'b1000_0000;end//8

4'b1001:begin seg_duan<=8'b1001_0000;end//9

default:seg_duan<=8'bx;

endcase

end

 

endmodule

 

实验操作

实验效果

 

 

 

大西瓜FPGA-->https://daxiguafpga.taobao.com

配套开发板:https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-24211932856.3.489d7241aCjspB&id=633897209972

博客资料、代码、图片、文字等属大西瓜FPGA所有,切勿用于商业! 若引用资料、代码、图片、文字等等请注明出处,谢谢!

   

每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号"科乎"。

posted @ 2022-02-20 17:16  logic3  阅读(205)  评论(0编辑  收藏  举报