基于CPLD的数字频率计.docx
《基于CPLD的数字频率计.docx》由会员分享,可在线阅读,更多相关《基于CPLD的数字频率计.docx(23页珍藏版)》请在冰点文库上搜索。
![基于CPLD的数字频率计.docx](https://file1.bingdoc.com/fileroot1/2023-5/6/c86cd6d2-1f20-4e75-a775-532bf4fa610e/c86cd6d2-1f20-4e75-a775-532bf4fa610e1.gif)
基于CPLD的数字频率计
第1章设计总体思路,基本原理和框图
1.1设计总体思路
数字频率计是数字电路中的一个典型应用,这里我们采用ALTERA公司的EP1C3T144C8作为控制核心,利用VHDL语言进行编程,硬件下载烧制实现。
将所有集成器件集成到一块芯片上,体积大大减小的同时还大大提高了稳定性,可实现大规模和超大规模的集成电路,测频测量精度高,测量频率范围大,而且编程灵活,调试方便。
1.2基本原理
频率计的基本原理是利用一个稳定度高的频率源作为基准时钟,对比测量其他信号的频率。
通常情况下计算每秒内待测信号的脉冲个数,即闸门时间为1s。
闸门时间可以根据需要取值,大于或小于1s都可以。
测得的频率时间间隔与闸门时间的取值成正比,在这里取的闸门时间为1s。
其实频率就是1s中之内测得的周期个数,这里我们可以以时钟信号的频率作为基准来分频,即时钟信号是多大的频率我们就进行多少分频,这样被测信号就是1s钟读出来的周期个数,也就是可以进行直接读数。
数字频率计的关键组成部分包括分频器,计数器、锁存器、片选电路,译码驱动电路和显示电路.
1.3总体框图
第2章单元电路设计
2.1分频模块设计
在分频模块中,我们选择的是10分频。
分频器在总电路中有两个作用。
由总图框图中不难看出分频器有两个输出,一个给计数器,一个给锁存器。
时钟信号经过分频电路形成了10分频后的门信号。
另一个给锁存器作锁存信号,当信号为低电平时就锁存计数器中的数。
模块图如下:
图2.1分频模块
2.2片选信号模块
片选信号在整个模块中有两个作用,其中一个输出是给译码器用于选择四位数据哪个数据输出。
另一个输出是给片选,用于选中哪个LED灯点亮。
这里我们有8个LED灯,片选信号给出给出信号再经过片选选择哪个高电平,哪个灯就点亮,反之不亮。
片选信号的模块图如下:
图2.2片选信号模块
2.3计数器模块
计数器模块主要负责的是计数,当被测信号来一个上升沿,计数器就加一,当个位数满了就向十位进一,以此类推。
计数器的输出送给锁存器锁存,当clr为低电平时计数器就清零。
当door信号为高电平时才开始计数。
计数器模块图如下:
图2.3计数模块
2.4锁存器模块
锁存器主要是将计数器送过来的数据锁存起来再送给显示器进行显示,锁存器的主要作用是防止送过来的信号直接送给显示器出现的闪烁现象,当来一个下降沿锁存器就将数据锁存。
锁存模块图如下:
图2.4锁存器模块
2.5译码信号模块
该模块主要的对锁存器送过来的数据进行选择分个输给译码器译码,再进行显示。
这样再结合片选信号送过来的脉冲就可以实现共用8段显示管的LED灯显示不同的数字。
译码信号的模块如下:
图2.5译码信号模块
2.6片选模块
该模块主要的送过来的片选信号进行处理,处理后的输出就是选择哪个数码管点亮,由8位2进制数组成,哪位为1,哪个数码管就点亮,否则不点亮。
片选模块图如下:
图2.6片选模块
2.7译码模块
译码模块主要是将送过来的译码信号进行译码,译码信号由4位二进制数组成,译码输出由7位二进制数组成(用来点亮LED灯的7段数码管分别显示0-9的数字)。
译码模块图如下:
图2.7译码模块
第3章设计仿真图
3.1分频电路仿真
打开quartusII后,建立工程文件,然后输入程序,保存后编译。
编译无错误既可以生成电路图。
其仿真图如下:
图3.1分频仿真图
3.2片选信号仿真
设置Endtime为50ms时钟周期为15us,其仿真图如下:
图3.2片选信号仿真图
3.3计数器模块的仿真
设置clr为1,door为1,endtime为50ms,sig周期为1us其仿真图如下:
图3.3计数器仿真图
3.4锁存器模块仿真
设置输入,就可以输出,输出和输入一样,只是有点延时,其仿真图如下:
图3.4锁存器仿真图
3.5译码信号模块仿真
其仿真电路图如下:
图3.5译码信号仿真图
3.6片选模块仿真
设置输入从0-7,则输人为0时输出第一个为1,输入为1输出第二个为1,以此类推,其仿真图如下:
图3.6片选仿真图
3.7译码器模块仿真
其仿真图如下:
图3.7译码器仿真图
3.8总电路图的仿真
总电路调用其他7个模块,设置clk周期为15us,被测信号sig周期为1us,其仿真图如下:
图3.8总电路图的仿真
图3.8为总的电路图,图中alm为进位输出,clk为时钟信号,设为15us。
Clr为清零信号,点电平清零,高电平计数。
Q为显示输出端。
Sel为片选,sig为被测信号,设为1us。
图中显示结果为011111111011010000110为150.本电路为10分频。
结果应为15*10=150,所以测量结果正确。
3.9软件调试与硬件调试
(1)软件调试
仿真时,打开软件QuartusII,建立工程文件,然后输入程序。
保存后,编译,无误后及可以仿真了。
进入仿真界面后,先点击edit菜单,设置endtime,一般设为50ms,由于软件的缘故,endtime不要设的太小,否则延时会很大出现错乱.时钟,被测信号分别设置为15us和1us。
对总电路图仿真的时候也出现了一个问题,一开始我们怎么也仿真不出来,后来上网一查才知道总图仿真的endtime设小了,而且时钟周期和被测信号的周期也设小了。
改正后,仿真顺利的出来了。
(2)硬件调试
硬件调试就是将软件编译好了没有错误之后,进行引脚锁定,再进行接线,其中我也出现了一个小的失误,怎么也不能将程序下载到芯片中,然后请教老师之后才知道是芯片选错了,更正后,点击pinplanner锁定引脚,接好线之后就点击programmer下载程序到芯片。
在点击start运行后就看到了实验的结果。
与理论的稍微有一点点的偏差,考虑时延的影响,结果算是正确的。
引脚锁定图如下:
图3.9引脚锁定图
第4章编程下载
4.1分频模块的程序
libraryieee;
useieee.std_logic_1164.all;
entityfenis
port(clk:
instd_logic;
q:
outstd_logic);
endfen;
architecturefen_arcoffenis
begin
process(clk)
variablecnt:
integerrange0to9;
variablex:
std_logic;
begin
ifclk'eventandclk='1'
thenifcnt<9then
cnt:
=cnt+1;
else
cnt:
=0;
x:
=notx;
endif;
endif;
q<=x;
endprocess;
endfen_arc;
4.2片选信号模块的程序
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityselis
port(clk:
instd_logic;
q:
outstd_logic_vector(2downto0));
endsel;
architecturesel_arcofselis
begin
process(clk)
variablecnt:
std_logic_vector(2downto0);
begin
ifclk'eventandclk='1'then
cnt:
=cnt+1;
endif;
q<=cnt;
endprocess;
endsel_arc;
4.3计数器模块的程序
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityjishuis
port(clr,sig,door:
instd_logic;
alm:
outstd_logic;
q3,q2,q1,q0,dang:
outstd_logic_vector(3downto0));
endjishu;
architecturejishu_arcofjishuis
begin
process(door,sig)
variablec3,c2,c1,c0:
std_logic_vector(3downto0);
variablex:
std_logic;
begin
ifsig'eventandsig='1'then
ifclr='0'then
alm<='0';
c3:
="0000";
c2:
="0000";
c1:
="0000";
c0:
="0000";
elsifdoor='0'then
c3:
="0000";
c2:
="0000";
c1:
="0000";
c0:
="0000";
elsifdoor='1'then
ifc0<"1001"then
c0:
=c0+1;
else
c0:
="0000";
ifc1<"1001"then
c1:
=c1+1;
elsec1:
="0000";
ifc2<"1001"then
c2:
=c2+1;
else
c2:
="0000";
ifc3<"1001"then
c3:
=c3+1;
else
c3:
="0000";
alm<='1';
endif;
endif;
endif;
endif;
endif;
ifc3/="0000"then
q3<=c3;
q2<=c2;
q1<=c1;
q0<=c0;
dang<="0100";
elsifc2/="0000"then
q3<="0000";
q2<=c2;
q1<=c1;
q0<=c0;
dang<="0011";
elsifc1/="0000"then
q3<="0000";
q2<="0000";
q1<=c1;
q0<=c0;
dang<="0010";
else
q3<="0000";
q2<="0000";
q1<="0000";
q0<=c0;
dang<="0001";
endif;
endif;
endprocess;
endjishu_arc;
4.4锁存器模块的程序
libraryieee;
useieee.std_logic_1164.all;
entitylockis
port(l:
instd_logic;
a4,a3,a2,a1,a0:
instd_logic_vector(3downto0);
q4,q3,q2,q1,q0:
outstd_logic_vector(3downto0));
endlock;
architecturelock_arcoflockis
begin
process(l)
variablet4,t3,t2,t1,t0:
std_logic_vector(3downto0);
begin
ifl'eventandl='0'then
t4:
=a4;
t3:
=a3;
t2:
=a2;
t1:
=a1;
t0:
=a0;
endif;
q4<=t4;
q3<=t3;
q2<=t2;
q1<=t1;
q0<=t0;
endprocess;
endlock_arc;
4.5译码信号模块的程序
libraryieee;
useieee.std_logic_1164.all;
entityymsigis
port(sel:
instd_logic_vector(2downto0);
a3,a2,a1,a0,dang:
instd_logic_vector(3downto0);
q:
outstd_logic_vector(3downto0));
endymsig;
architectureymsig_arcofymsigis
begin
process(sel)
begin
caseselis
when"000"=>q<=a0;
when"001"=>q<=a1;
when"010"=>q<=a2;
when"011"=>q<=a3;
when"111"=>q<=dang;
whenothers=>q<="1111";
endcase;
endprocess;
endymsig_arc;
4.6片选模块的程序
libraryieee;
useieee.std_logic_1164.all;
entitypxis
port(d:
instd_logic_vector(2downto0);
q:
outstd_logic_vector(7downto0));
endpx;
architecturepx_arcofpxis
begin
process(d)
begin
casedis
when"000"=>q<="00000001";
when"001"=>q<="00000010";
when"010"=>q<="00000100";
when"011"=>q<="00001000";
when"100"=>q<="00010000";
when"101"=>q<="00100000";
when"110"=>q<="01000000";
when"111"=>q<="10000000";
whenothers=>q<="00000000";
endcase;
endprocess;
endpx_arc;
4.7译码器模块的程序
libraryieee;
useieee.std_logic_1164.all;
entityymis
port(d:
instd_logic_vector(3downto0);
q:
outstd_logic_vector(6downto0));
endym;
architectureym_arcofymis
begin
process(d)
begin
casedis
when"0000"=>q<="0111111";
when"0001"=>q<="0000110";
when"0010"=>q<="1011011";
when"0011"=>q<="1001111";
when"0100"=>q<="1100110";
when"0101"=>q<="1101101";
when"0110"=>q<="1111101";
when"0111"=>q<="0000111";
when"1000"=>q<="1111111";
when"1001"=>q<="1101111";
whenothers=>q<="0000000";
endcase;
endprocess;
endym_arc;
4.8顶层模块的程序
libraryieee;
useieee.std_logic_1164.all;
entitypinglvjiis
port(sig,clr,clk:
instd_logic;
alm:
outstd_logic;
q:
outstd_logic_vector(6downto0);
se:
outstd_logic_vector(7downto0));
endpinglvji;
architectureartofpinglvjiis
componentjishu
port(clr,sig,door:
instd_logic;
alm:
outstd_logic;
q3,q2,q1,q0,dang:
outstd_logic_vector(3downto0));
endcomponent;
componentfen
port(clk:
instd_logic;
q:
outstd_logic);
endcomponent;
componentlock
port(l:
instd_logic;
a4,a3,a2,a1,a0:
instd_logic_vector(3downto0);
q4,q3,q2,q1,q0:
outstd_logic_vector(3downto0));
endcomponent;
componentsel
port(clk:
instd_logic;
q:
outstd_logic_vector(2downto0));
endcomponent;
componentymsig
port(sel:
instd_logic_vector(2downto0);
a3,a2,a1,a0,dang:
instd_logic_vector(3downto0);
q:
outstd_logic_vector(3downto0));
endcomponent;
componentym
port(d:
instd_logic_vector(3downto0);
q:
outstd_logic_vector(6downto0));
endcomponent;
componentpx
port(d:
instd_logic_vector(2downto0);
q:
outstd_logic_vector(7downto0));
endcomponent;
signalt1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t12:
std_logic_vector(3downto0);
signalt11:
std_logic;
signalt20:
std_logic_vector(2downto0);
begin
u1:
jishuportmap(clr=>clr,sig=>sig,door=>t11,alm=>alm,q3=>t1,q2=>t2,q1=>t3,q0=>t4,dang=>t5);
u2:
fenportmap(clk=>clk,q=>t11);
u3:
lockportmap(l=>t11,a4=>t1,a3=>t2,a2=>t3,a1=>t4,a0=>t5,q4=>t6,q3=>t7,q2=>t8,q1=>t9,q0=>t10);
u4:
selportmap(clk=>clk,q=>t20);
u5:
ymsigportmap(sel=>t20,a3=>t6,a2=>t7,a1=>t8,a0=>t9,dang=>t10,q=>t12);
u6:
ymportmap(d=>t12,q=>q);
u7:
pxportmap(d=>t20,q=>se);
endarchitectureart;
第5章总结与体会
短短两周的课程设计结束了,回顾这两周我的努力,我觉得我还是收获蛮大的,通过这两周的课程设计,我对CPLD有了更深的认识,对VHDL有了更深入的了解,CPLD就是复杂的可编程逻辑器件,其实就是做硬件的。
这次我接到的课题是做一个频率计,刚开始时觉得没什么难度,因为我们上EDA课的时候也做过类似的实验,那次我们做的是一个时钟,也是要做硬件,不过那次是老师给了我们程序,只需要自己编译,运行,再锁定引脚做硬件就行了。
所以做起来没什么太大的难度,其实那次也只是教会我们怎样使用Quartus这个软件。
然而这次却不同,软件,仿真,硬件全部自己动手。
一开始觉得毫无头绪,但经过网上资料的查找及其阅读EDA这本书,我开始有点头绪了,其实频率计也就是测1s内的周期个数,在实践的过程中我也遇到了各种问题,比如仿真出不来,endtime设小了,时钟周期设小了,建立工程的时候芯片选错了,程序出问题等等,但是我通过上网提问,及询问老师这些问题也得到了顺利的解决。
现在我对Quartus这个软件也是有了更深入的了解。
对硬件也是有了一定的了解。
对EDA中VHDL这门语言也是有了深刻的理解。
现在要我编个不是很大的程序我想我也是没什么问题了。
通过这两周的学习,我学到了很多,毕竟自己也做出了一点东西,蛮有成就感的,其实我也知道这只是冰山一角,要想真正的弄通EDA,今后的学习道路还很漫长,我想我也会深深的记住这次课设给我的经验与教训,在今后的学习中一定要多思考,多实践,那样我才会真正有所成就。
最后衷心感谢陈老师在这两周对我的细心指导。
附录
顶层原理图:
参考文献
1.康华光主编.电子技术基础(数字部分),高等教育出版社。
2.阎石主编.电子技术基础(数字部分),清华大学出版社。
3.陈大钦主编,电子技术基础实验,高等教育出版社。
4.彭介华主编,电子技术课程设计指导,高等教育出版社。
5.张原编著,可编程逻辑器件设计及应用,机械工业出版社。
6.荀殿栋,徐志军编著,数字电路设计实用手册,电子工业出版社。
7.刘洪喜,陆颖编著.VHDL电路设计实用教程清华大学出版社