数字时钟Word下载.docx
《数字时钟Word下载.docx》由会员分享,可在线阅读,更多相关《数字时钟Word下载.docx(17页珍藏版)》请在冰豆网上搜索。
![数字时钟Word下载.docx](https://file1.bdocx.com/fileroot1/2022-11/27/8d81b3c1-0c49-4d42-9a08-caa385733bef/8d81b3c1-0c49-4d42-9a08-caa385733bef1.gif)
清零功能:
reset为复位键,低电平时实现清零功能,高电平时正常计数。
可以根据我们自己任意时间的复位。
2、顶层实体描述
基于可编程逻辑器件CPLD/FPGA的芯片,使用硬件描述语言(VHDL)设计一个数字电子钟芯片[5],并进行计算机仿真和编程下载。
要求该数字电子钟芯片能够实现如下功能:
(1).计数功能:
完成00时00分00秒到23时59分59秒的计时功能。
(2).清零功能:
到23时59分59秒时电路自动清零,并设有一个手动清零开关,通过它可以对电路实现随时的手动的清零。
(3).定时功能:
能够随意设定,精确到秒,由开关调节设定需要设定的时刻。
(4).动态显示功能:
能够动态显示电子中的时刻数。
顶层电路图
3、模块划分
根据该数字电子钟的功能要求,现划分为以下5个模块:
(1).秒计数模块
(2).分计数模块
(3).时计数模块
(4).显示模块
(5).顶层模块
在计数模块中,程序中的控制信号表示如下:
clk是脉冲控制输入信号。
reset是清零输入信号,低电平有效。
总体方框图
3、模块详细描述
秒计数模块的功能是从00计数到59,为六十进制,所以可以由1个六进制计数器和1个十进制计数器组成1个六十进制的计数器。
六进制计数器设计图如图3.1所示。
图3.1六进制计数器设计图
其中RESET是六进制计数器的清零输入信号,低电平有效,CLK是脉冲控制输入信号。
DIN[2..0]是秒计数模块的十位输入信号,用来调整秒的十位的数值。
DOUT[2..0]是秒计数模块的十位输出信号。
C为秒计数器的进位。
十进制计数器设计图如图3.2所示。
图3.2十进制计数器设计图
其中RESET是十进制计数器的清零输入信号,低电平有效,CLK是脉冲控制输入信号。
DIN[3..0]是秒计数模块的个位输入信号,用来调整秒的个位的数值。
DOUT[3..0]是秒计数模块的个位输出信号。
C为秒计数器的个位的进位。
秒计数模块的原理图如图3.3所示。
图3.3秒计数模块原理图
分计数模块的功能同样是从00计数到59,所以分计数模块的构成和秒计数模块的构成一样。
同样由1个六进制计数器和1个十进制计数器组成。
设计图同秒计数模块。
原理图如图3.4所示。
其中需将秒的进位输出信号接到分计数模块的个位的时钟信号上。
图3.4分计数模块原理图
时计数模块的功能是从00计数到23,为24进制。
所以该模块只需1个24进制计数器构成。
24进制计数器设计图如图3.5所示。
其中需将分的进位输出信号接到时计数模块的时钟信号上。
图3.524进制计数器设计图
其中RESET是24进制计数器的清零输入信号,低电平有效,CLK是脉冲控制输入信号。
DIN[5..0]是秒计数模块的输入信号,用来调整小时的数值。
DOUT[5..0]是时计数模块的输出信号。
时计数模块原理图如图3.6所示。
图3.6时计数模块原理图
显示模块通过译码,将秒、分、时的高低位数字分别译成LED七段数码管上对应的高低电平,然后输出七段值。
7段数码显示器由7个显示码管组成,4个输入信号d0,d1,d2,d3来表示0000到1111,即表示十六进制中的0到F;
同时它有7个输出信号,分别用a,b,c,d,e,f,g来表示,决定可发光二极管的状态。
该数码管为共阳数码管,当某位为0时,表示这位所在的数码管发光;
如为1,则表示不发光;
共阴数码管则正好相反。
从7段数码显示器的原理可以知道,7段数码显示器用4个输入信号对应16个输出信号,并且一个输入信号只能对应一个唯一的输出。
从这点出发,很容易想到前面所学的译码器电路,事实上,7段数码显示器的显示就是调用了一个4-16线译码器。
本设计采用的是共阳数码管,共阳数码管的真值表如图3.8所示。
图3.8七段共阳极数码管真值表
显示模块设计图如图3.9所示。
图3.9显示模块设计图
其中DIN[3..0]是数字电子钟的时、分、秒的个位或者十位输入信号,DOUT[6..0]是显示模块的输出信号。
显示模块原理图如图3.10所示。
图3.10显示模块原理图
各功能子模块设计完成后,再设计顶层模块,它主要是通过元件声明和元件例化语句对各子模块进行调用来完成的。
顶层模块设计图如图3.11所示。
图3.11顶层模块设计图
其中RESET是顶层模块的清零输入信号,低电平有效,CLK是脉冲控制输入信号。
DINS[6..0]是顶层模块的秒输入信号,用来调整秒的数值。
DINM[6..0]是顶层模块的分输入信号,用来调整分的数值。
DINH[5..0]是顶层模块的时输入信号,用来调整小时的数值。
输出信号为时、分、秒的个位和十位的输出,将此输出分别接到6个七位LED数码管上便可显示。
顶层模块原理图如图3.12所示。
图3.12顶层模块原理图
3、方案实现
1、各模块仿真及描述
3.16进制计数器的仿真
6进制计数器的计数状态仿真图如图3.1所示。
图3.16进制计数器计数状态仿真图
当输入信号reset为1时,在时钟信号的上升沿来临时,计数器加1,加到5时,在下一个时钟信号的上升沿来临时,计数器清零,进位信号变为高电平,如此反复。
当输入信号reset为0,且din为0时,得到6进制计数器的清零状态,如图3.2所示。
图3.26进制计数器清零状态仿真图
当输入信号reset为0,且din不为0时,得到6进制计数器的置数状态,即将din的值赋给dout,如图3.3所示。
图3.36进制计数器置数状态仿真图
3.210进制计数器的仿真
将程序使用QuartusIII进行运行并仿真,得到10进制计数器计数状态仿真图如图3.4所示。
图3.410进制计数器计数状态仿真图
当输入信号reset为1时,在时钟信号的上升沿来临时,计数器加1,加到9时,在下一个时钟信号的上升沿来临时,计数器清零,进位信号变为高电平,如此反复。
当输入信号reset为0,且din为0时,得到10进制计数器的清零状态,如图3.5所示。
图3.510进制计数器清零状态仿真图
当输入信号reset为0,且din不为0时,得到10进制计数器的置数状态,即将din的值赋给dout,如图3.6所示。
图3.610进制计数器置数状态仿真图
3.324进制计数器的仿真
将程序使用QuartusII进行运行并仿真,得到24进制计数状态的仿真图如图3.7所示。
图3.724进制计数状态仿真图
当输入信号reset为1时,在时钟信号的上升沿来临时,计数器加1,加到23时,在下一个时钟信号的上升沿来临时,计数器清零,如此反复。
当输入信号reset为0,且din为0时,得到24进制计数器的清零状态,如图3.8所示。
图3.824进制清零状态仿真图
当输入信号reset为0,且din不为0时,得到24进制计数器的置数状态,即将din的值赋给dout,如图3.9所示。
图3.924进制置数状态仿真图
3.4显示模块的仿真
将程序使用QuartusII进行运行并仿真,得到显示模块仿真图如图3.10所示。
图3.10显示模块仿真图
此模块是将4为二进制输入信号转化成对应的七段数码管的7位二进制输出信号。
2、顶层电路仿真及描述
将程序使用QuartusII进行运行并仿真,得到顶层模块仿真图如图3.11所示。
图3.11顶层模块仿真图
此模块是通过元件声明和元件例化语句对各子模块进行调用,同时将时、分、秒的个位和十位都转换成4位二进制数,然后将这六组数据传给显示模块。
顶层模块的输出的数据是七段数码管的7位二进制输出信号。
4、硬件测试及说明
实验箱使用模式7,键8为复位按键,键8为1时正常工作。
键4设置小时,键7设置分钟。
下载成功后,按下键8,及使六个LED复位清零,显示数秒的自动计时,可以通过4键设置小时数,7键设置分钟数。
当秒数满60则进一位,分钟数满60进一位,当显示为23:
59:
59时,秒数在加一则显示00:
00:
00,之后从新计时。
5、结论
本课题要求基于可编程逻辑器件,使用硬件描述语言VHDL编写一个数字电子钟芯片,并用QuartusII软件进行仿真。
根据自己对数字电子钟的理解我设计了四大功能:
一是计数功能,二是清零功能,三是定时功能,四是动态显示功能。
由此必需设计出五个大的模块:
一是秒计数模块,此模块是由1个6进制计数器和1个10进制计数器组成1个60进制计数器;
二是分计数模块,此模块也是是由1个6进制计数器和1个10进制计数器组成1个60进制计数器;
三是时计数模块,此模块由1个24进制计数器构成;
四是显示模块,主要功能是把输入的4位二进制信号转换为对应的七段数码管的7位二进制信号。
五是顶层模块,此模块是通过元件声明和元件例化语句对各子模块进行调用,将其余模块整合成一块芯片,避免的繁杂的连线。
课程总结
经过几个星期对实践的制作,从中学到了很多。
首先是对EDA的VHDL语言的更深层次认识,对可编程逻辑器件,VHDL语言,QuartusII软件有了一定的了解,尤其是用VHDL语言编程和仿真。
本来觉得EDA编程语言比较麻烦,可是接触了以后也就觉得它还是有它方便的地方,尤其是和图形编程结合的特点。
其次,这个实践其实到目前为止应该还不是一个成功的作品,还是有很多的仿真没有完成,原因可能也是自己的技术不到位。
但是整个制作的过程中,它促进了同学之间的相互沟通,也让我在自己的专业知识的学习过程中,更多的,更好的学习一门知识,用于以后的实践应用中,做这个数字钟的设计中包含了很多不同功能的程序,让我在其中学到了一些程序的中的思路,特别一步一步去把错误的程序改正确是一种很有成就感的事!
这样让我学到了更多的知识!
我在网上查了好多程序,证实了好多错误的程序并从中更改出正确的程序!
我会更努力的学习。
6、附录
本次试验中基于VHDL语言所编写的源程序代码如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYalertIS
PORT(clk:
INSTD_LOGIC;
dain:
INSTD_LOGIC_VECTOR(6DOWNTO0);
speak:
OUTSTD_LOGIC;
lamp:
OUTSTD_LOGIC_VECTOR(2DOWNTO0));
ENDalert;
ARCHITECTUREfunOFalertIS
SIGNALcount:
STD_LOGIC_VECTOR(1DOWNTO0);
SIGNALcount1:
BEGIN
speaker:
PROCESS(clk)
--speak<
=count1
(1);
IF(clk'
eventandclk='
1'
)THEN
IF(dain="
0000000"
speak<
IF(count1>
="
10"
count1<
00"
;
--count1为三进制加法计数器
ELSE
=count1+1;
ENDIF;
ENDPROCESSspeaker;
lamper:
IF(rising_edge(clk))THEN
IF(count<
IF(count="
lamp<
001"
--循环点亮三只灯
ELSIF(count="
01"
010"
100"
ENDIF;
count<
=count+1;
ENDPROCESSlamper;
ENDfun;
Hour:
useIEEE.STD_LOGIC_1164.ALL;
ENTITYhourIS
PORT(clk,reset:
daout:
outSTD_LOGIC_VECTOR(5DOWNTO0));
ENDENTITYhour;
ARCHITECTUREfunOFhourIS
SIGNALcount:
STD_LOGIC_VECTOR(5DOWNTO0);
daout<
=count;
PROCESS(clk,reset)
IF(reset='
0'
)THENcount<
000000"
--若reset=0,则异步清零
ELSIF(clk'
)THEN--否则,若clk上升沿到
IF(count(3DOWNTO0)="
1001"
)THEN--若个位计时恰好到"
即9
16#23#)THEN--23进制
=count+7;
--若到23D则
else
--复0
ELSIF(count<
16#23#)THEN--若未到23D,则count进1
ELSE--否则清零
--ENDIF(count(3DOWNTO0)="
)
--ENDIF(reset='
ENDPROCESS;
Minute:
ENTITYminuteIS
PORT(clk,clk1,reset,sethour:
enhour:
OUTSTD_LOGIC_VECTOR(6DOWNTO0));
ENDENTITYminute;
ARCHITECTUREfunOFminuteIS
SIGNALcount:
STD_LOGIC_VECTOR(6DOWNTO0);
SIGNALenhour_1,enhour_2:
STD_LOGIC;
--enmin_1为59分时的进位信号
BEGIN--enmin_2由clk调制后的手动调时脉冲信号串
enhour_2<
=(sethourandclk1);
--sethour为手动调时控制信号,高电平有效
enhour<
=(enhour_1orenhour_2);
PROCESS(clk,reset,sethour)
BEGIN
)THEN--若reset为0?
IF(count(3DOWNTO0)="
)THEN--若个位计时恰好到"
IF(count<
16#60#)THEN--又若count小于16#60#,即60
1011001"
)THEN--又若已到59D
enhour_1<
='
--则置进位为1
--count复0
ELSE
--若count未到59D,则加7,即作"
加6校正"
--使前面的16#60#的个位转变为8421BCD的容量
--count复0(有此句,则对无效状态电路可自启动)
--ENDIF(count<
16#60#)
ELSIF(count<
16#60#)THEN
--若count<
16#60#则count加1
after100ns;
--没有发生进位
--否则,若count不小于16#60#count复0
ENDprocess;
Second:
ENTITYsecondIS
PORT(clk,reset,setmin:
STD_LOGIC;
enmin:
ENDENTITYsecond;
ARCHITECTUREfunOFsecondIS
STD_LOGIC_VECTOR(6DOWNTO0);
SIGNALenmin_1,enmin_2:
--enmin_1为59秒时的进位信号
BEGIN--enmin_2由clk调制后的手动调分脉冲信号串
enmin_2<
=(setminandclk);
--setmin为手动调分控制信号,高电平有效
enmin<
=(enmin_1orenmin_2);
--enmin为向分进位信号
PROCESS(clk,reset,setmin)
--若reset为0,则异步清零
ELSIF(clk'
)then--否则,若clk上升沿到
IF(count(3downto0)="
)then--若个位计时恰好到"
16#60#)then--又若count小于16#60#,即60H
)then--又若已到59D
enmin_1<
count<
--则置进位为1及count复0
ELSE--未到59D
--则加7,而+7=+1+6,即作"
ELSE--若count不小于16#60#(即count等于或大于16#60#)
ELSIF(count<
16#60#)then--若个位计数未到"
则转此句再判
16#60#则count加1
after100ns;
--没有发生进位
ELSE--否则,若count不小于16#60#
--则count复0
ENDPROCESS;