华中科技大学电子课程设计频率计.docx
《华中科技大学电子课程设计频率计.docx》由会员分享,可在线阅读,更多相关《华中科技大学电子课程设计频率计.docx(25页珍藏版)》请在冰点文库上搜索。
![华中科技大学电子课程设计频率计.docx](https://file1.bingdoc.com/fileroot1/2023-6/15/e47edcbc-e17b-45c1-adb9-9dece494cfbd/e47edcbc-e17b-45c1-adb9-9dece494cfbd1.gif)
华中科技大学电子课程设计频率计
2015-2016学年度第二学期
电子技术基础课程设计
--数字频率计设计
院系:
自动化学院
专业:
自动化
班级:
姓名:
学号:
指导教师:
一、设计目的与要求
设计一个数字频率计,其技术要求如下:
(1)测量频率范围:
1Hz~100kHz。
(2)准确度∆fx/fx≤±2%。
(3)测量信号:
方波,峰峰值为3V~5V。
(4)使用数码管显示测量的信号频率(测量低频信号时可以只显示测量信号的周期)。
二、需求分析及创意
频率计的主要功能是准确测量出待测频率的频率、周期、脉宽及占空比。
在电子技术中,频率是最基本的参数之一,并且与许多电参量的测量方案、测量结果都有十分密切的关系,因此频率的测量就显得更为重要。
测量频率的方法有多种,其中电子计数器测量频率具有精度高、使用方便、测量迅速,以及便于实现测量过程自动化等优点,是频率测量的重要手段之一。
电子计数器测频有两种方式:
一是直接测频法(高频),即在一定闸门时间内测量被测信号的脉冲个数;二是间接测频法,如周期测频法(低频)。
直接测频法适用于高频信号的频率测量,间接测频法适用于低频信号的频率测量。
本设计中分别以图形设计方法为主和VHDL语言为主的两种形式进行设计。
在这次设计过程中,我们设计了两套测量频率计的方案。
下面分别阐述。
第一种方案,主要是通过一个计数器,在1秒时间内,当有待测信号上升沿产生时,开始计数。
最后送到显示模块显示。
而占空比,则是通过分别计算高电平时间和低电平时间,从而得到占空比数值。
应该说这种方法,更接近于测频法的思想。
通过实验的检测,发现与实验仪器(信号发生器)的最大误差只有±10,所以,在测量频率不是特别大的范围内,这种设计方案,笔者认为应该可以接受。
而第二种方案,则是对于不同大小的频率,通过测频法和测周法,进行选择输出频率值大小。
三、系统方案及技术路线
低频信号的测量(测周期法1HZ—10KHZ):
所谓频率就是在单位时间(1s)内周期信号的变化次数。
若在一定时间间隔T内测得周期信号的重复变化次数为N,则其频率为f=N/T,据此,同样对于低于10KHZ的信号,我们采用测周期法,时标为50MHZ,其误差远远小于0.001,故可达到指标要求
测周法原理:
假设基准时钟信号的周期为Ts(频率为fs),被测信号的周期我Tw,用被测信号控制测量计数器进行计数,当被测信号一个周期结束后,让计数器停止计数,若计数器数值为Nx,被测信号的周期为
Tw=Nx*Ts
其频率为fx=fs*Nx
这种测频方法实际上是通过测量被测信号周期后,再经过换算得到被测信号频率的,它适合于被测信号原低于基准时钟信号频率的场合。
用这种方法测量时,测试精度与计数器中记录的Nx有关,由于被测信号一个周期的时间长度不一定正好为基准时钟信号周期的整数倍,因此计数器的计数值会产生±1个值的误差。
高频信号的测量(测频法10KHZ—10MHZ):
由于我们很难得到准确的1hz频率,故在这里我们采用等精度测量法,这样就可以不必考虑1s信号的精确度的影响。
闸门时间不是固定值,而是被测信号周期的整数倍,即与被测信号同步.因此排除了对被测信号计数所产生的1个周期误差,并且达到了在整个测试频段的等精度测量.
在测量过程中,有两个计数器分别对标准信号和被测信号同时计数.首先给出闸门开启信号(预置闸门上升沿),此时计数器并不开始计数.而是等到被测信号的上升沿到来时,计数器才真正开始计数.然后预置闸门关闭信号(下降沿到时),计数器并不立即停止计数,而是等到被测信号的上升沿到来时才开始结束计数,完成一次测量过程.
设在一次实际闸门时间t中计数器对被测信号的计数值为Nx,对标准信号的计数值为Ns,标准信号的频率为fs,则被测信号的频率为fx=Nx/Nsfs。
由推断(此处省略)得测量频率的相对误差£=1/tfs
由上式可看出测量频率的相对误差与被测信号频率的大小无关,仅与闸门时间和标准信号频率有关.闸门时间越长,标准频率越高测频的相对误差就越小.标准频率可由稳定性好,精度高的高频率晶振产生,在保证测量精度不变的前提下,提高标准信号频率,可使闸门时间缩短,即提高测试速度.可实现
四、设计原理
1、基本原理
频率测量的基本原理是计算每秒钟内待测信号的脉冲个数。
这就要求sysclk能产生一个1s脉宽的周期信号,并对频率计的每一个计数器cntp的使能端进行同步控制。
当clK_cnt高电平时允许计数,并保持其所计的数。
在停止计数期间,首先需要一个锁存信号将计数器在前1s的计数值锁存进锁存器reg中,并由外部的7段译码器译出并稳定显示。
原理图如图1-1
基准信号
图1-1
2、模块原理
根据数字频率计的基本原理,本文设计方案的基本思想是分为五个模块来实现其功能,即整个数字频率计系统分为分频模块、控制模块、计数模块、译码模块和量程自动切换模块等几个单元,并且分别用VerilogHDL对其进行编程,实现了闸门控制信号、计数电路、锁存电路、显示电路等。
五、设计内容
1、分频模块
由于晶体振荡器提供的为50MHz的时钟,而在整个频率计里将用到周期为2s,半个周期为1s的闸门信号,所以我们在此模块先分频产生0.5Hz的分频信号。
always@(posedgesysclk)
begin
if(cnt==50_000_000)
begin
clk_cnt<=~clk_cnt;
cnt<=0;
end
else
begin
cnt<=cnt+1'b1;
end
end
由程序中的clk_cnt<=~clk_cnt;cnt<=0;得知会产生我们想要的周期为2s的clk_int信号。
仿真结果如图1-2.
图1-2
2、方波发生器模块
always@(posedgesysclk)
begin
if(cnt1==500)
begin
clk_out<=~clk_out;
cnt1<=0;
end
else
begin
cnt1<=cnt1+1'b1;
end
end
由于在寝室做测试时缺少了信号发生器,所以添加了一个方波发生的模块。
如上面程序中所示,当出cnt1=500时,可以产生50000HZ的方波,通过改变出cnt1的数值调出不同频率的方波从clk_out输出到clkin,进行方波频率计数。
3、五位十进制计数器模块
5位十进制计数器模块包含5位十进制的计数器,用来对施加到时钟脉冲输入端的待测信号产生的脉冲进行计数,十进制计数器具有清零控制和进位扩展输出的功能。
always@(posedgeclkin)
begin
if(clk_cnt)
begin
if(cntp1=='b1001)
begin
cntp1<='b0000;
cntp2<=cntp2+1;
if(cntp2=='b1001)
begin
cntp2<='b0000;
cntp3<=cntp3+1;
if(cntp3=='b1001)
begin
cntp3<='b0000;
cntp4<=cntp4+1;
if(cntp4=='b1001)
begin
cntp4<='b0000;
cntp5<=cntp5+1;
if(cntp5=='b1001)
begin
cntp5<='b0000;
end
end
end
end
end
else
begin
cntp1<=cntp1+1;
end
end
本程序采用的是以累加的方法结合巧妙地if语句进行四重循环,实现四位十进制不同的高低级别,实现计数。
一位十进制原理图仿真如图1-3。
图1-3
五位十进制原理图仿真如图1-4。
图1-4
4、锁存模块
如果计数器输出直接与译码器相连接,那么在计数过程中输出端则随输入脉冲数的增加而不断跳变,那么显示数码管则也会不断闪烁跳变,让人不能看到稳定的输出,设锁存器后,则不再跳变,便可清晰读出计数结果。
其生成的功能模块如图所示:
if(cntp1!
='b0000|cntp2!
='b0000|cntp3!
='b0000|cntp4!
='b0000|cntp5!
='b0000)
begin
cntq1<=cntp1;
cntq2<=cntp2;
cntq3<=cntp3;
cntq4<=cntp4;
cntq5<=cntp5;
cntp1<='b0000;
cntp2<='b0000;
cntp3<='b0000;
cntp4<='b0000;
cntp5<='b0000;
end//
5、清零复位模块
采用一个开关作为rst复位信号,当rst置0时,5个cntq寄存器赋0,从而5个数码管显示0,同时5个计数单元cntp也清零,为下次阀门信号时计数做准备。
if(cntp1!
='b0000|cntp2!
='b0000|cntp3!
='b0000|cntp4!
='b0000|cntp5!
='b0000)
begin
cntq1<=cntp1;
cntq2<=cntp2;
cntq3<=cntp3;
cntq4<=cntp4;
cntq5<=cntp5;
cntp1<='b0000;
cntp2<='b0000;
cntp3<='b0000;
cntp4<='b0000;
cntp5<='b0000;
end//
6、译码显示模块
选择另一个开关作为量程选择信号rst1,当rst1=0时,将cntq1,cntq2,cntq3,cntq4的值分别赋给seg1,seg2,seg3,seg3,seg4这4个7位共阳极数码管显示的信号(即显示5位数频率的后4位),当rst1=1时,将cntq5的值赋给seg1,再把seg2,seg3,seg4分别置为’0‘所对应的显示码。
还有一种显示方式是吧cntq5的值直接赋给led[3:
0],直接用4个二极管显示(用二进制表示)。
begin
if(rst1)
begin
case(cntq1[3:
0])
4'b0000:
beginseg1[6:
0]=7'b0000001;end
4'b0001:
seg1[6:
0]=7'b1001111;
4'b0010:
seg1[6:
0]=7'b0010010;
4'b0011:
seg1[6:
0]=7'b0000110;
4'b0100:
seg1[6:
0]=7'b1001100;
4'b0101:
seg1[6:
0]=7'b0100100;
4'b0110:
seg1[6:
0]=7'b1100000;
4'b0111:
seg1[6:
0]=7'b0001111;
4'b1000:
seg1[6:
0]=7'b0000000;
4'b1001:
seg1[6:
0]=7'b0000100;
default:
seg1[6:
0]='bX;
endcase
case(cntq2[3:
0])
4'b0000:
beginseg2[6:
0]=7'b0000001;end
4'b0001:
seg2[6:
0]=7'b1001111;
4'b0010:
seg2[6:
0]=7'b0010010;
4'b0011:
seg2[6:
0]=7'b0000110;
4'b0100:
seg2[6:
0]=7'b1001100;
4'b0101:
seg2[6:
0]=7'b0100100;
4'b0110:
seg2[6:
0]=7'b1100000;
4'b0111:
seg2[6:
0]=7'b0001111;
4'b1000:
seg2[6:
0]=7'b0000000;
4'b1001:
seg2[6:
0]=7'b0000100;
default:
seg2[6:
0]='bX;
endcase
case(cntq3[3:
0])
4'b0000:
beginseg3[6:
0]=7'b0000001;end
4'b0001:
seg3[6:
0]=7'b1001111;
4'b0010:
seg3[6:
0]=7'b0010010;
4'b0011:
seg3[6:
0]=7'b0000110;
4'b0100:
seg3[6:
0]=7'b1001100;
4'b0101:
seg3[6:
0]=7'b0100100;
4'b0110:
seg3[6:
0]=7'b1100000;
4'b0111:
seg3[6:
0]=7'b0001111;
4'b1000:
seg3[6:
0]=7'b0000000;
4'b1001:
seg3[6:
0]=7'b0000100;
default:
seg3[6:
0]='bX;
endcase
case(cntq4[3:
0])
4'b0000:
beginseg4[6:
0]=7'b0000001;end
4'b0001:
seg4[6:
0]=7'b1001111;
4'b0010:
seg4[6:
0]=7'b0010010;
4'b0011:
seg4[6:
0]=7'b0000110;
4'b0100:
seg4[6:
0]=7'b1001100;
4'b0101:
seg4[6:
0]=7'b0100100;
4'b0110:
seg4[6:
0]=7'b1100000;
4'b0111:
seg4[6:
0]=7'b0001111;
4'b1000:
seg4[6:
0]=7'b0000000;
4'b1001:
seg4[6:
0]=7'b0000100;
default:
seg4[6:
0]='bX;
endcase
/*case(cntq5[3:
0])
4'b0000:
beginled[3:
0]=4'b0000;end
4'b0001:
led[3:
0]=4'b0001;
4'b0010:
led[3:
0]=4'b0010;
4'b0011:
led[3:
0]=4'b0011;
4'b0100:
led[3:
0]=4'b0100;
4'b0101:
led[3:
0]=4'b0101;
4'b0110:
led[3:
0]=4'b0110;
4'b0111:
led[3:
0]=4'b0111;
4'b1000:
led[3:
0]=4'b1000;
4'b1001:
led[3:
0]=4'b1001;
default:
led[3:
0]='bX;
endcase*/
end
else
begin
seg4[6:
0]=7'b0000001;
seg2[6:
0]=7'b0000001;
seg3[6:
0]=7'b0000001;
case(cntq5[3:
0])
4'b0000:
beginseg1[6:
0]=7'b0000001;end
4'b0001:
seg1[6:
0]=7'b1001111;
4'b0010:
seg1[6:
0]=7'b0010010;
4'b0011:
seg1[6:
0]=7'b0000110;
4'b0100:
seg1[6:
0]=7'b1001100;
4'b0101:
seg1[6:
0]=7'b0100100;
4'b0110:
seg1[6:
0]=7'b1100000;
4'b0111:
seg1[6:
0]=7'b0001111;
4'b1000:
seg1[6:
0]=7'b0000000;
4'b1001:
seg1[6:
0]=7'b0000100;
default:
seg1[6:
0]='bX;
endcase
end
6、编译仿真
最后的程序的编译仿真结果如图1-5。
图1-5
六、输入输出设计
如图所示各引脚分配
七、系统实测
从I/O接口分别有两个输入波形和输出波形接口。
拨动开关switch0为复位开关,下拨后,再下一个输入波形上升沿到来时,将会刷新数码管至0。
拨动开关switch1为量程显示开关,上拨时数码管显示低4位数值,下拨时显示第五位最高位数值。
八、实验总结
1、心得体会
拿到课设题目后我首先去网上查找了一些关于频率计的原理,然后又去找来了我们学校的参考书veriloghdl与数字asic这部书,了解了测频法和测周法两种基本的实验原理,然后选择了逻辑较为简单的测频法。
即在阀门信号1s高电平内计数被测信号的脉冲个数并且锁存下来送到数码显示管显示。
接着开始复习了一些基础的verilog语法,由于大二数电中只是简单介绍了相关语句,所以这一过程也进行地比较艰辛。
主要采用了always相关语句进行逻辑描述。
然后利用大二的一些实验课件,熟悉了quartus2的使用方法,如何仿真,调试等等,也熟悉了de0板子的各个模块功能和引脚分配。
在显示模块,也花了一些心思,开始想用动态译码的方法让数码管轮流显示,发现de0板子并不支持动态译码,于是又改为静态译码,一次性把数值送到4位数码管。
碰到比较麻烦的问题是,题目要求100kHZ的显示,这就要求5位数码管了,但是de0只有4位数码管。
于是想了3种解决方法:
(1)采用一个量程转换开关,开始显示低四位,拨动后显示最高一位;
(2)用4位led灯来二进制地显示最高位,数码管显示低4位;(3)用10个led灯分别代表0~9数字来显示最高位,数码管显示低4位。
最后采取的第一种最直观的方法来进行显示。
在程序基本调试完成仿真后,去了实验室进行实测后,还有一些小问题,可是实验室又不再开门,寝室里又缺少信号发生器,很头疼,幸运的是在老师建议下,我又做了一个利用内部时钟进行方波输出的模块,就可以自由进行测试了。
最后几天又继续完善了相关模块,添加了复位清零的功能。
在最后验收的过程中我又发现,在信号发生器采用函数输出时,方波测试会不稳定,甚至出现2倍频率的情况。
而采用同步输出后测试良好,频率稳定,当频率为4772误差在±10hz内浮动,即误差为±0.2%
通过本次课程设计,我重新巩固了自己学的数电和verilog等电子相关知识,并且在实践中更好的进行了掌握。
加强了自己动手,查找资料,思考和解决问题的能力。
我也懂得了理论与实际相结合,在设计的过程中遇到问题可以说的上是困难重重,这毕竟是第一次在de0板子上做的,难免会遇到各种问题,同时在设计的过程中也发现了自己的不足之处,对以前的知识理解的不够深刻,掌握的不够牢固。
此次课程设计,学到了很多课内学不到的东西,比如独立思考解决问题的能力,出现差错随机应变的能力,和同学互相讨论合作,都受益匪浅,相信今后碰到的实践项目,自己会更加轻松地完成,更加得心应手。
同时也得到了教训,做事应该趁早完成,不要拖拉,不然地话自己也可以设计出更多功能完善的模块。
在此也给细心指导的老师和其它无私给予帮助的同学致以谢意。
2、待改进的问题
(1)对于量程溢出的问题,即如果频率超过99999hz或者频率不足1hz的方波,只能错误显示而没有给出超量程预警。
(2)测频法对于频率较大的方波,测得结果误差稍大可以考虑换用测周法。
3、功能扩展
(1)显示模块可以改用另外两种led显示的方法
(2)可以设置一个量程预警显示led,在被测信号频率超过99999hz和不足1hz时给出警示。
九、参考书目
1.谢自美主编.电子线路设计综合设计.华中科技大学出版社,2006
2.罗杰,谢自美主编.电子线路设计.实验.测试(第4版).电子工业出版社,2008.4
3.罗杰主编.VerilogHDL与数字ASIC设计基础.华中科技大学出版社,2008.3
4.FPGA与SOPC设计教程-DE2实践,张志刚编著,西安电子科技大学出版社,2007.4
5.夏宇闻.Verilog数字系统设计教程.北京航空航天大学出版社
十、附录
源代码及注释
modulecymometer(seg1,seg2,seg3,seg4,sysclk,clkin,rst,clk_out,rst1);
//顶层模块
output[6:
0]seg1,seg2,seg3,seg4;
//4个7位数码管输出变量
outputclk_out;
//方波输出信号变量
regclk_out;
//输出为寄存器型
inputsysclk;
//输入变量50M的时钟信号
inputclkin;
//输入的测试信号
inputrst;
//输入复位清零信号
inputrst1;
//输入量程转换显示信号
reg[3:
0]led;
reg[6:
0]seg1,seg2,seg3,seg4;
reg[25:
0]cnt;
//分频计数变量1
reg[25:
0]cnt1;
//分频计数变量2
regclk_cnt;
//周期2s的阀门信号
reg[3:
0]cntp1,cntp2,cntp3,cntp4,cntp5;
//5位十进制计数变量
reg[3:
0]cntq1,cntq2,cntq3,cntq4,cntq5;
//5位锁存计数的变量
reg[3:
0]dat;
always@(posedgesysclk)
//50M时钟信号上升沿到来时执行一次模块
begin
if(cnt1==500)
begin
clk_out<=~clk_out;
//cnt1计数到500时,clk_out信号翻转一次,然后清零
cnt1<=0;
end
else
begin
cnt1<=cnt1+1'b1;
end
end
//方波产生模块,输出50000HZ的方波到clk_out
always@(posedgesysclk)
begin
if(cnt==50_000_000)
begin
clk_cnt<=~clk_cnt;
cnt<=0;
end
else
begin
cnt<=cnt+1'b1;
end
//cnt每计数到50M时,clk_cnt信号翻转一次,然后清零
end
always@(posedgeclkin)
begin
if(clk_cnt)
//在阀门信号为高电平时
begin
if(cntp1=='b1001)
//个位满10进1
begin
cntp1<='b0000;
cntp2<=cntp2+1;
//个位清零,十位加一
if(cntp2=='b1001)
begin
cntp2<='b0000;
cntp3<=cntp3+1;
//十位清零,百位加一
if(cntp3=='b1001)
begin
cntp3<='b0000;
cntp4<=cntp4+1;
//百位清零,千位加一
if(cntp4=='b1