多功能电子时钟数字系统课程设计设计实验报告文档格式.doc
《多功能电子时钟数字系统课程设计设计实验报告文档格式.doc》由会员分享,可在线阅读,更多相关《多功能电子时钟数字系统课程设计设计实验报告文档格式.doc(53页珍藏版)》请在冰点文库上搜索。
![多功能电子时钟数字系统课程设计设计实验报告文档格式.doc](https://file1.bingdoc.com/fileroot1/2023-4/28/15422e78-98d1-4925-92a9-3ac45d484cfb/15422e78-98d1-4925-92a9-3ac45d484cfb1.gif)
三、各模块具体介绍
本设计主要分成计数器模块和控制模块。
计数器模块主要包括60进制计数器模块和24进制计数器模块,向量与整数转换模块,1Hz时钟分频模块,整数转换为两个向量的模块,动态显示模块和8段数码管译码模块。
控制模块主要包括。
1、60进制计数器模块
此模块主要提供60进制数的计数,通过连接外部1Hz时钟信号来控制计数频率。
只要检测时钟上升沿到来,计数器就加1,直至计到60,又从0开始计时。
此外,此模块还有复位和置数功能。
复位端低电平就能将计数器清0,而置位端的高电平能将外部送来的数据加载到计算器里面,计数器从加载的值开始计数。
除此之外,进位信号用于下一位计数的时钟信号。
这主要用于接收控制模块中,通过外部设置时间来修改时钟当前时间的功能。
60进制计数器模块主要是秒和分位的计数。
2、24进制计数器模块
此模块和60进制计数器模块有一样的功能,只是这个模块是24进制的,用于时位的计数,同样也有复位和置数的功能。
3、向量与整数转换模块
由于整数处理起来比较方便,所以添加了向量到整数的转换模块。
其中用到了conv_integer来进行转换。
4、1Hz时钟分频模块
由于实验板上的时钟频率为50MHz,而时间显示最低位为秒,故需要分频。
分频器实际也是一个计数器,只是在计数的中点处,将输出信号置为1,在终点处将其置为0,便可实现50%占空比的1Hz时钟信号。
5、整数转换为两个向量的模块
由于本设计将时分秒都作为一个整体来处理,但是在显示时需要有两个数码管分别显示,所以必须拆成两个,且8段数码管的译码的输入为向量,故需转换成两个向量。
主要是利用对10整除取其十位,对10取余取出个位的方法,再用conv_std_logic_vector将其转换为向量。
6、动态显示模块
由于实验板上将4个8段数码管的端口连在一起,所以每一时刻4个数码管的显示数值应该是一样的,故不能分别显示不同时间。
然而,动态显示通过人眼的余晖效应,以很高的频率来扫描数码管,不断的依次轮流点亮数码管,使得看起来是4个数码管同时显示不同数字。
这主要是通过设置数码管的使能端,同时选择此数码管应该显示的数据,进行动态显示。
此外,我们对数码管显示时的小数点进行控制,使其在显示分和秒之间点亮而其他位不亮。
所以我们设置了一个标志位来对译码电路进行控制,使其点亮或熄灭小数点。
7、8段数码管译码模块
此模块主要将输入的4位向量转换成相应的在8端数码管上显示的向量,使其显示相应的数字。
而且,我们通过从动态显示模块接收到的标志位来控制译码的程序,使得相应的小数点亮或灭。
1.消抖模块:
由于每个按键机械触点的闭合或断开都会有一个抖动的暂态过程,即按键闭合时不是立即稳定闭合,而是处于闭合—断开交替变化的过程,持续一段时间才变为稳定闭合的状态,按键松开时有类似的效果,而由于CPU的反映速度很快,能够检测出抖动过程产生的电压波动,如果直接检测电平判断按键是否按下或松开会造成重复识别,因此通过消抖模块来检测按键是否按下。
2.按键模块:
此模块利用3个按键来对时钟进行操作,每个按键按下,输出一个高电平信号给按键记录模块。
按键1是切换键,用来切换当前时钟工作状态;
按键2是启动停止键,用于调整时间和设定闹钟时间;
按键3是确认键,按下使时钟回到原始状态,即时间显示状态。
3.按键记录模块:
此模块用来记录按键按下的数目,以切换到相应的工作模式进行进行操作。
Sum记录按键1的按下数:
1表示时间显示状态;
2表示时间的时调整状态;
3表示时间的分调整状态;
4表示闹铃的时设定状态;
5表示闹铃的分设定状态;
6表示秒表状态。
Sum1记录按键2的按下数:
1表示启动,时间开始变化;
2表示停止,时间调整或设定完毕。
Sum2记录按键3的按下数:
按一下表示确认,时钟回到时间显示工作状态。
4.时分选择模块:
此模块用来选择‘时’或‘分’,并将结果送到显示模块进行数码管显示。
这是由于实验板只有4个数码管不够用来完整显示时、分、秒的限制而设计的。
时分选择通过拨盘来进行控制。
拨盘拨下(关闭):
选择显示‘分’;
拨盘拨上(开启):
选择显示‘时’。
5.显示选择模块:
此模块主要区分秒表工作状态下和其他工作状态的的结果显示。
6.主控模块:
此模块用来控制时钟当前工作状态,并对各种工作状态下的操作指令进行接受和处理。
(1)输入信号有:
Clk:
时钟信号;
setsnd:
闹铃开关信号;
setsnd=’1’时,闹铃开;
setsnd=’0’时,闹铃关。
sum:
切换按键1的按下数;
sum=1时,时钟工作在时间显示状态;
sum=2时,时钟工作在时间的时调整状态;
sum=3时,时钟工作在时间的分调整状态;
sum=4时,时钟工作在闹铃的时设定状态;
sum=5时,时钟工作在闹铃的分设定状态;
sum=6时,时钟工作在秒表状态。
Sum1:
启动停止按键2的按下数;
sum=1表示启动,时间开始变化;
sum=2表示停止,时间调整或设定完毕。
Sum2:
确认键3的按下数:
Sum2=1,表示操作完毕,使sum=1,时钟回到时间显示状态,并使sum1=0.
Hour:
时;
Min:
分;
Sec:
秒。
(2)输出信号:
Rst:
复位信号,用来消除秒表的记录,使其变为0;
Showchu:
显示选择信号,用来切换秒表状态和其他状态的显示;
Begincnt:
秒表启动信号;
Load:
时间重置信号,用于将显示时间改变到经调整设置得到的新时间;
Clear:
按键记录清除信号;
Sound:
闹铃信号,达到设定的闹铃时间时,该信号是蜂鸣器鸣叫;
Output1:
经处理后的‘时’;
Output2:
经处理后的‘分’;
Output3:
经处理后的‘秒’;
四、仿真
1、计数器模块仿真
由以上仿真图可知此计数器可以实现计时功能,且能够及时进位,符合设计的目标。
由以上仿真图可知,当load信号为1时,可以实现置位,即将当前计数器的值改为外部输入的值(图中外部输入为0)。
2、向量整数转换模块仿真
由以上两幅图可知向量与整数转换模块能正确地实现向量到整数的转换。
3、整数转换为两个向量的模块仿真
由以上两幅图可知,此模块可以将一个整数拆分成两个向量,以用于两个数码管的显示。
4、按键记录模块仿真
5、时分选择模块仿真:
6、显示选择模块仿真:
五、实验成果
六、实验总结和感想
1、实验错误排查和解决
实验最开始是计时器,由于实验板上只有4个数码管,不够同时显示时分秒共6位数,故我们采用外部拨码开关控制切换时和分的显示。
在显示时,由于译码模块将所有数码管的小数点都点亮,所以看起来并不直观。
我们后来在动态显示模块加入一个标记信号,使得译码时,需要小数点亮的数码管按原来的程序译码,不需小数点点亮的数码管按另外的方法译码,便解决了这个问题。
秒表显示也是同样的道理控制小数点亮灭。
在控制模块中,设置闹钟时,一开始,我们设置完闹钟时间后,按下确认键,总是会先短暂地响一声。
后来在找程序时才发现再确认键后对信号进行复制,此时信号还未来得及变化,还是原来的值,和闹钟设定值是一样的,所以会有那个响声。
将其先赋给一个变量,在用变量与闹钟设定值比较,就可以得到正确结果,等到闹钟时间时响铃。
2、实验感想
在这次的VHDL课程设计中,我们小组做的是多功能电子时钟实验,在参与之前,我以为同单片机课程设计一样,照着老师给的要求,设计程序、再下载进去即可。
而且在VHDL的学习中,由于邢老师的讲课条理清晰,教授细致,我们都学得比较轻松。
但是真正参与到设计的过程中时,却比想象中的难得多,不过收获和付出是成正比的,有挑战性的实验,才会让人受益匪浅。
一是知识一定要掌握完整,理解透彻才有可能用于实际用途。
由于原先对程序设计过程掌握不熟练,导致经常犯下简单的错误,拖延了设计的完成时间,基础不够扎实。
在此次的数字钟设计过程中,我们更进一步地熟悉有关数字电路的知识和具体应用。
学会了利QuarterII软件进行原理图的绘制,硬件描述语言VHDL的编写,程序的仿真等工作。
并能根据仿真结果分析设计的存在的问题和缺陷,从而进行程序的调试和完善。
二是模块化的思想,在实践中真正的体会到了其简便、易懂的特点。
通过对模块化思想的应用,我们的实验思路非常的清晰,大大提高了实验过程的简洁度,不仅方便基本功能的设计,还会便于扩展功能的实现。
这些平时听得晕乎乎,人云亦云的好处,终于在实践过程中得到了非常好的体现。
以上就是我们在这次实验中的收获和感想,学习不能只靠书本和试卷,更重要的是类似于这样的动手过程,这样才能稳扎稳打,真正的学到有用的知识。
七、各模块代码
1、计数器模块
(1)60进制计数器模块
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitycount60sis
port(rst,clk,load:
instd_logic;
num:
instd_logic_vector(5downto0);
num1:
outstd_logic_vector(5downto0);
outp:
outstd_logic);
endentity;
architecturebehavofcount60sis
begin
process(clk,rst,load)
variablecnt:
std_logic_vector(5downto0);
begin
if(rst='
0'
)then
cnt:
="
000000"
;
elsif(load='
1'
=num;
outp<
='
elsif(clk'
eventandclk='
if(cnt="
111011"
cnt:
outp<
else
=cnt+"
000001"
endif;
endif;
num1<
=cnt;
endprocess;
endbehav;
(2)24进制计数器模块
entitycount24sis
architecturebehavofcount24sis
010111"
(3)向量与整数转换模块
useieee.std_logic_arith.all;
entityrris
port(a:
b:
outintegerrange63downto0);
architecturebehavofrris
begin
b<
=conv_integer(a);
(4)1Hz时钟分频模块
entityclkdivis
port(clk:
q:
outstd_logic);
endclkdiv;
architecturebehavofclkdivis
process(clk)
variabletimed:
integerrange0to50000000;
begin
ifrising_edge(clk)then
timed:
=timed+1;
iftimed=25000000then
q<
elsiftimed=50000000then
=0;
endif;
endprocess;
(5)整数转换为两个向量的模块
entitytransis
port(num:
inintegerrange63downto0;
num_l,num_h:
outstd_logic_vector(3downto0));
architecturebehavoftransis
signalm,n:
integerrange9downto0;
m<
=num/10;
n<
=numrem10;
num_l<
=conv_std_logic_vector(n,4);
num_h<
=conv_std_logic_vector(m,4);
(6)动态显示模块
entityshowis
port(secondl,secondh,minutel,minuteh:
instd_logic_vector(3downto0);
sum:
clk:
en:
outstd_logic_vector(3downto0);
seg:
flag:
architecturebehavofshowis
process(clk)
variablecounter:
integerrange0to3;
if(clk'
if(counter=3)then
counter:
=0;
else
=counter+1;
endif;
casecounteris
when0=>
if(sum="
0110"
)then
flag<
else
en<
="
0111"
seg<
=minuteh;
when1=>
1011"
=minutel;
when2=>
1101"
=secondh;
when3=>
1110"
=secondl;
whenothers=>
null;
endcase;
endprocess;
(7)8段数码管译码模块
entitycounter_displayeris
port(flag:
displayer_en:
count:
seven_seg_input:
outstd_logic_vector(7downto0));
endcounter_displayer;
architecturebehavofcounter_displayeris
signalseven_seg_input_reg:
std_logic_vector(7downto0);
display:
process(displayer_en,count)
ifdisplayer_en='
then
if(flag='
casecountis
when"
0000"
=>
seven_seg_input_reg<
00000010"
0001"
10011110"
0010"
00100100"
0011"
00001100"
0100"
10011000"
0101"
01001000"
01000000"
00011110"
1000"
00000000"
1001"
00001000"
1010"
00010000"
11000000"
1100"
01100010"
10000100"
01100000"
1111"
01110000"
WHENOTHERS=>
seven_seg_input_reg<
else
casecountis
00000011"
10011111"
00100101"
00001101"
10011001"
01001001"
01000001"
seven_seg_input_re