数字频率计设计报告.docx
《数字频率计设计报告.docx》由会员分享,可在线阅读,更多相关《数字频率计设计报告.docx(33页珍藏版)》请在冰豆网上搜索。
数字频率计设计报告
现代电子技术综合实验
数字频率计设计实验报告
姓名:
董明明学号:
2801307007
一、系统总体设计
设计要求
1、被测输入信号:
方波
2、测试频率范围为:
10Hz~1MHz扩展1MHz~100MHz
3、量程分为三档:
第一档:
闸门时间为1S时,最大读数为999.999KHz
第二档:
闸门时间为0.1S时,最大读数为9999.99KHz
第三档:
闸门时间为0.01S时,最大读数为99999.9KHz。
4、显示工作方式:
a、用六位BCD七段数码管显示读数。
b、采用记忆显示方法
c、实现对高位无意义零的消隐。
系统工作原理
信号的频率就是信号在单位时间内所产生的脉冲个数,其表达式为f=N/T,其中f为被测信号的频率,N为技术其所累计的脉冲个数,T为产生N个脉冲所需的时间。
技术其所记录的结果,就是被测信号的频率。
如在1s内记录1000个脉冲,则被测信号的频率为1000HZ。
测量频率的基本方法有两种:
计数法和计时法,或称测频法和测周期法。
1、计数法
计数法是将被测信号通过一个定时闸门加到计数器进行计数的方法,如果闸门打开的时间为T,计数器得到的计数值为N1,则被测频率为f=N1/T。
改变时间T,则可改变测量频率范围。
如图所示。
计数法测量原理
设在T期间,计数器的精确计数值应为N,根据计数器的计数特性可知,N1的绝对误差是N1=N+1,N1的相对误差为δN1=(N1-N)/N=1/N。
由N1的相对误差可知,N的数值愈大,相对误差愈小,成反比关系。
因此,在f以确定的条件下,为减少N的相对误差,可通过增大T的方法来降低测量误差。
当T为某确定值时(通常取1s),则有f1=N1,而f=N,故有f1的相对误差:
δf1=(f1-f)/f=1/f
从上式可知f1的相对误差与f成反比关系,即信号频率越高,误差越小;而信号频率越低,则测量误差越大。
因此测频法适合用于对高频信号的测量,频率越高,测量精度也越高。
2、计时法
计时法又称为测周期法,测周期法使用被测信号来控制闸门的开闭,而将标准时基脉冲通过闸门加到计数器,闸门在外信号的一个周期内打开,这样计数器得到的计数值就是标准时基脉冲外信号的周期值,然后求周期值的倒数,就得到所测频率值。
首先把被测信号通过二分频,获得一个高电平时间是一个信号周期T的方波信号;然后用一个一直周期T1的高频方波信号作为计数脉冲,在一个信号周期T的时间内对T1信号进行计数,如图所示。
计时法测量原理
若在T时间内的计数值为N2,则有:
T2=N2*T1f2=1/T2=1/(N2*T1)=f1/N2
N2的绝对误差为N2=N+1。
N2的相对误差为δN2=(N2-N)/N=1/N
T2的相对误差为δT2=(T2-T)/T=(N2*T1-T)/T=f/f1
从T2的相对误差可以看出,周期测量的误差与信号频率成正比,而与高频标准计数信号的频率成反比。
当f1为常数时,被测信号频率越低,误差越小,测量精度也就越高。
根据本设计要求的性能与技术指标,首先需要确定能满足这些指标的频率测量方法。
有上述频率测量原理与方法的讨论可知,计时法适合于对低频信号的测量,而计数法则适合于对较高频信号的测量。
但由于用计时法所获得的信号周期数据,还需要求倒数运算才能得到信号频率,而求倒数运算用中小规模数字集成电路较难实现,因此,计时法不适合本实验要求。
测频法的测量误差与信号频率成反比,信号频率越低,测量误差就越大,信号频率越高,其误差就越小。
但用测频法所获得的测量数据,在闸门时间为一秒时,不需要进行任何换算,计数器所计数据就是信号频率。
因此,本实验所用的频率测量方法是测频法。
单元电路的划分
分频电路
FPGA的石英振荡器,产生频率为48MHz的方波信号。
因此需要分频电路,将48MHz的高频信号,分频为整个系统需要的信号:
1Hz闸门信号和1KHz扫描显示信号
计数器
对外部输入的被测信号,进行计数
锁存器
对计数器的计数结果,进行锁存
门控电路
对计数电路、锁存电路,进行时序控制
扫描显示控制电路
对锁存的结果,进行动态扫描显示
系统框图:
二、单元电路设计
单元电路设计思路
一.分频器
分频器的功能是将提供的48MHz标准信号,产生所需的1Hz闸门控制信号及1KHz扫描时钟信号。
因此通过计数器的计数,来实现分频器的功能
例如:
实现对一个信号的5分频
ifclkin'eventandclkin='1'then
ifcnt=5then
cnt<=1;
clkout<=notclkout;
else
cnt<=cnt+1;
endif;
endif;
源程序见附录
二.计数器
计数器的功能是对外部输入的被测信号,进行计数。
因为系统要求,显示为6为数字,所以需要6位的计数器。
因此采用6个10进制计数器级联的方法
单级计数器
级联后的计数器
级联,分为同步级联和异步级联两种方式
同步级联原理图:
异步级联原理图:
本设计选择的是同步级联
源程序见附录
三.锁存器
锁存器用来实现对6位计数结果,和溢出信号的锁存功能
源程序见附录
四.门控电路
门控电路的作用是对计数电路和锁存电路,进行时序控制
例如:
源程序见附录
五.扫描显示控制电路
扫描显示控制电路的功能是对锁存的结果,进行动态扫描显示。
选用频率1KHz的信号实现对六位已经锁存的计数结果的扫描输出
扫描显示控制电路分为以下几部分构成:
1.计数部分:
通过计数器的计数,来产生动态显示数码管的位选信号
2.小数点控制部分:
控制小数点的显示
3.数据选择部分:
根据计数部分产生的位选信号,来选择一组数据输出显示
4.七段译码部分:
将数据选择器输出的数据,进行译码,形成数码管的段选信号
5.消隐部分
实现高位无意义0的消隐
各个部分间的链接关系如图:
源程序见附录
三、设计实现
顶层设计
通过原件的声明,和原件的例化,来将各个底层实体,在顶层调用
例如:
architecturedigitalfrequency_archofdigitalfrequencyis
componentfenpin
Port(clk:
inSTD_LOGIC;
clkout1:
outSTD_LOGIC;
clkout1k:
outSTD_LOGIC);
endcomponent;
begin
u1:
fenpinportmap(clk24m,clk1,clk1k);
enddigitalfrequency_arch;
管脚分配
NET"overflow"LOC=K14;
NET"clk24m"LOC=T8;
NET"g"LOC=D7;
NET"ledout<0>"LOC=A11;
NET"ledout<1>"LOC=B12;
NET"ledout<2>"LOC=A12;
NET"ledout<3>"LOC=C12;
NET"ledout<4>"LOC=C13;
NET"ledout<5>"LOC=A13;
NET"ledout<6>"LOC=B14;
NET"digitalsignal"LOC=D14;
NET"sel<0>"LOC=F8;
NET"sel<1>"LOC=D8;
NET"sel<2>"LOC=E7;
NET"point"LOC=C11;
下载过程
四、测试结果及结论
测试结果
输入信号为1MHz
数码管显示为999.999KHz
输入信号为10Hz
数码管显示为0.010KHz
输入信号为5000Hz
数码管显示为5.000KHz
输入信号为5555Hz
数码管显示为5.555KHz
输入为98429Hz
数码管显示为98.429KHz
实验结论
当输入信号为1MHz时,显示稍有误差,其余量程范围内的信号均能精确显示,该数字频率计性能良好,实验成功!
附录——源程序
1.分频电路
entityfenpinis
Port(clk:
inSTD_LOGIC;
clkout1:
outSTD_LOGIC;
clkout1k:
outSTD_LOGIC);
endfenpin;
architectureBehavioraloffenpinis
signalfcount1:
integerrange1to500:
=1;
signalfcount1k:
integerrange1to24000:
=1;
signalclk1k:
STD_LOGIC:
='0';
signalclk1:
STD_LOGIC:
='0';
begin
process(clk)
begin
ifclk'eventandclk='1'then
iffcount1k=24000then
fcount1k<=1;
clk1k<=notclk1k;
else
fcount1k<=fcount1k+1;
endif;
endif;
endprocess;
clkout1k<=clk1k;
process(clk1k)
begin
ifclk1k'eventandclk1k='1'then
iffcount1=500then
fcount1<=1;
clk1<=notclk1;
else
fcount1<=fcount1+1;
endif;
endif;
endprocess;
clkout1<=clk1;
endBehavioral;
2.门控电路
entitygatecontrolis
Port(gatein:
inSTD_LOGIC;
gateout:
outSTD_LOGIC;
latch:
outSTD_LOGIC;
reset:
outSTD_LOGIC);
endgatecontrol;
architectureBehavioralofgatecontrolis
signalA:
STD_LOGIC:
='0';
signalB:
STD_LOGIC:
='0';
signalC:
STD_LOGIC:
='0';
begin
process(gatein)
begin
ifgatein'eventandgatein='1'then
A<=notA;
endif;
ifgatein'eventandgatein='0'then
B<=notA;
endif;
endprocess;
process(gatein,A,B)
begin
ifgatein='0'andA='0'andB='1'then
C<='1';
elseC<='0';
endif;
endprocess;
gateout<=A;
latch<=B;
reset<=C;
endBehavioral;
3.计数器
单级计数器
entitycounteris
Port(clk:
inSTD_LOGIC;
reset:
inSTD_LOGIC;
carry_in:
inSTD_LOGIC;
carry_out:
outSTD_LOGIC;
count_out:
outSTD_LOGIC_VECTOR(3downto0));
endcounter;
architectureBehavioralofcounteris
signalcount:
STD_LOGIC_VECTOR(3downto0):
="0000";
begin
process(clk,carry_in)
begin
ifreset='1'then
count<="0000";
elsifclk'eventandclk='1'andcarry_in='1'then
ifcount="1001"then
count<="0000";
else
count<=count+1;
endif;
endif;
endprocess;
count_out<=count;
carry_out<='1'whencarry_in='1'andcount="1001"else'0';
endBehavioral;
级联后计数器
entitycounter6is
Port(Csignal:
inSTD_LOGIC;
clear:
inSTD_LOGIC;
count_en:
inSTD_LOGIC;
out1:
outSTD_LOGIC_VECTOR(3downto0);
out2:
outSTD_LOGIC_VECTOR(3downto0);
out3:
outSTD_LOGIC_VECTOR(3downto0);
out4:
outSTD_LOGIC_VECTOR(3downto0);
out5:
outSTD_LOGIC_VECTOR(3downto0);
out6:
outSTD_LOGIC_VECTOR(3downto0);
over:
outSTD_LOGIC);
endcounter6;
architecturecounter6_archofcounter6is
componentcounter
port(clk:
inSTD_LOGIC;
reset:
inSTD_LOGIC;
carry_in:
inSTD_LOGIC;
carry_out:
outSTD_LOGIC;
count_out:
outSTD_LOGIC_VECTOR(3downto0));
endcomponent;
signaloverflow1:
STD_LOGIC:
='0';
signaloverflow2:
STD_LOGIC:
='0';
signaloverflow3:
STD_LOGIC:
='0';
signaloverflow4:
STD_LOGIC:
='0';
signaloverflow5:
STD_LOGIC:
='0';
signaloverflow6:
STD_LOGIC:
='0';
begin
u1:
counterportmap(Csignal,clear,count_en,overflow1,out1);
u2:
counterportmap(Csignal,clear,overflow1,overflow2,out2);
u3:
counterportmap(Csignal,clear,overflow2,overflow3,out3);
u4:
counterportmap(Csignal,clear,overflow3,overflow4,out4);
u5:
counterportmap(Csignal,clear,overflow4,overflow5,out5);
u6:
counterportmap(Csignal,clear,overflow5,overflow6,out6);
over<=overflow6;
endcounter6_arch;
4.锁存器
entitylatchis
Port(data_in1:
inSTD_LOGIC_VECTOR(3downto0);
data_in2:
inSTD_LOGIC_VECTOR(3downto0);
data_in3:
inSTD_LOGIC_VECTOR(3downto0);
data_in4:
inSTD_LOGIC_VECTOR(3downto0);
data_in5:
inSTD_LOGIC_VECTOR(3downto0);
data_in6:
inSTD_LOGIC_VECTOR(3downto0);
latch_in:
inSTD_LOGIC;
over_in:
inSTD_LOGIC;
over_out:
outSTD_LOGIC;
data_out1:
outSTD_LOGIC_VECTOR(3downto0);
data_out2:
outSTD_LOGIC_VECTOR(3downto0);
data_out3:
outSTD_LOGIC_VECTOR(3downto0);
data_out4:
outSTD_LOGIC_VECTOR(3downto0);
data_out5:
outSTD_LOGIC_VECTOR(3downto0);
data_out6:
outSTD_LOGIC_VECTOR(3downto0));
endlatch;
architectureBehavioraloflatchis
begin
process(latch_in)
begin
iflatch_in'eventandlatch_in='1'then
data_out1<=data_in1;
endif;
endprocess;
process(latch_in)
begin
iflatch_in'eventandlatch_in='1'then
data_out2<=data_in2;
endif;
endprocess;
process(latch_in)
begin
iflatch_in'eventandlatch_in='1'then
data_out3<=data_in3;
endif;
endprocess;
process(latch_in)
begin
iflatch_in'eventandlatch_in='1'then
data_out4<=data_in4;
endif;
endprocess;
process(latch_in)
begin
iflatch_in'eventandlatch_in='1'then
data_out5<=data_in5;
endif;
endprocess;
process(latch_in)
begin
iflatch_in'eventandlatch_in='1'then
data_out6<=data_in6;
endif;
endprocess;
process(latch_in)
begin
iflatch_in'eventandlatch_in='1'then
over_out<=over_in;
endif;
endprocess;
endBehavioral;
5.扫描显示控制电路
entitydisplayis
Port(value0:
inSTD_LOGIC_VECTOR(3downto0);
value1:
inSTD_LOGIC_VECTOR(3downto0);
value2:
inSTD_LOGIC_VECTOR(3downto0);
value3:
inSTD_LOGIC_VECTOR(3downto0);
value4:
inSTD_LOGIC_VECTOR(3downto0);
value5:
inSTD_LOGIC_VECTOR(3downto0);
led:
outSTD_LOGIC_VECTOR(6downto0);
clk1k:
inSTD_LOGIC;
point:
outSTD_LOGIC;
g:
outSTD_LOGIC;
sel:
outSTD_LOGIC_VECTOR(2downto0));
enddisplay;
architectureBehavioralofdisplayis
signalcount:
STD_LOGIC_VECTOR(2downto0):
="000";
signaldataout:
STD_LOGIC_VECTOR(3downto0):
="0000";
signalhide:
STD_LOGIC:
='0';
signalhide_4:
STD_LOGIC:
='0';
signalhide_5:
STD_LOGIC:
='0';
begin
process(clk1k)
begin
ifclk1k'eventandclk1k='1'
then
ifcount="101"then
count<="000";
else
count<=count+1;
endif;
endif;
endprocess;
sel<=count;
g<='0';
process(count,value0,value1,value2,value3,value4,value5)
begin
casecountis
when"000"=>dataout<=value0;
when"001"=>dataout<=value1;
when"010"=>dataout<=value2;
when"011"=>dataout<=value3;
when"100"=>dataout<=value4;
when"101"=>dataout<=value5;
whenothers=>dataout<="0000";
endcase;
endprocess;
process(hide,dataout)
begin
led<="1111111";
ifhide='0'then
casedataoutis
when"0000"=>led<="0000001";
when"0001"=>led<="1001111";
when"0010"=>led<="0010010";
when"0011"=>led<="0000110";
when"0100"=>led<="1001100";
when"0101"=>led<="0100100";
when"0110"=>led<="0100000";
when"0111"=>led<="0001111";
when"1000"=>led<="0000000";
when"1001"=>led<="0000100";
whenothers=>led<="1111111";
endcase;
endif;
endprocess;