您好,欢迎来到华拓科技网。
搜索
您的当前位置:首页通信工程专业课程设计报告--多功能数字钟的设计与实现

通信工程专业课程设计报告--多功能数字钟的设计与实现

来源:华拓科技网
一、 设计任务及要求:

(1) 拥有正常的时、分、秒计时功能。

(2) 能利用实验板上的按键实现校时、校分及秒清零功能。 (3) 能利用实验板上的扬声器做整点报时。 (4) 闹钟功能。

(5) 在QUARTUS Ⅱ中采用层次化设计方法进行设计。

(6) 完成全部电路设计后在实验板上下载,验证设计课题的正确性。

二、 多功能数字钟的总体设计方案

根据总体设计框图,可以将整个系统分成6个模块来实现,分别是计时模块、校时模块、整点报时模块,分频模块,动态显示模块,闹钟模块。

设计总图:

1. 计时模块

该模块的设计相对简单,使用一个二十四进制和两个六十进制计数器级联,构成数字钟的基本框架。二十四进制的计数器用于计时,六十进制计数器用于计分和计秒。只要给秒计数器一个1Hz的时钟脉冲,则可以进行正常计时。分计数器以秒计数器的进位作为计数脉冲,小时计数器以分计数器的进位作为计数脉冲。

cnt24jh[3..0]clkql[3..0]qh[3..0]tcinstVCCjh[7..4]cnt60jm[3..0]clkql[3..0]clrqh[3..0]tcjm[7..4]NOTinst15inst1

(24进制计数器构成时计数器,60进制计数器构成的秒、分计数器)

24进制的仿真图:

1

60进制的仿真图

以下是计时模块设计VHDL语言: (1)library ieee;

use ieee.std_logic_11.all; use ieee.std_logic_unsigned.all; entity cnt24 is

port(clk:in std_logic;

ql,qh:out std_logic_vector(3 downto 0); tc:out std_logic); end cnt24;

architecture one of cnt24 is

begin

process(clk)

variable iql,iqh:std_logic_vector(3 downto 0); begin

if clk'event and clk='1' then iql:=iql+1;

if iql=\"1010\" then iqh:=iqh+1; iql:=\"0000\"; end if;

2

if (iqh=\"0010\")and(iql=\"0100\") then tc<='0'; iqh:=\"0000\"; iql:=\"0000\"; end if;

end if;

ql<=iql; qh<=iqh;

end process; end one;

(2)library ieee;

use ieee.std_logic_11.all; use ieee.std_logic_unsigned.all; entity cnt60 is

port(clk,clr:in std_logic;

ql,qh:buffer std_logic_vector(3 downto 0); tc:out std_logic ); end cnt60;

architecture behavor of cnt60 is begin

tc<='0' when(clk='1' and ql=\"0000\" and qh=\"0110\") else '1'; process(clk,clr,ql,qh)

variable iql,iqh:std_logic_vector(3 downto 0); begin

if(clr='0'or (iql=\"0000\" and iqh=\"0110\"))then iql:=\"0000\"; iqh:=\"0000\";

else if(clk'event and clk='1')then iql:=iql+1;

if(iql=\"1010\")then iql:=\"0000\"; iqh:=qh+1; end if; end if; end if;

ql<=iql;qh<=iqh; end process; END behavor;

3

2. 校时模块

该模块设计要求实现校时、校分及秒清零的功能。

① 按下校时键,小时计数器迅速递增以调至所需要的小时位。 ② 按下校分键,分计数器迅速递增以调至所需要的分位。 ③ 按下清零键,将秒计数器清零。

可以选择实验板上的3个脉冲按键进行锁定。

对于此模块的设计,有3个需要注意的问题:

① 在校分时,分计数器的计数不应对小时位产生影响。因而需要屏蔽此时分计数器的进位信号以防止小

时计数器计数。具体方法是在分计数器的进位输出时外加一个组合电路。详见下图。

hinputhz4hinputs21muxABSinst6YMULTIPLEXERNAND2hz4tcminputsNOTminputABSinst7YMULTIPLEXERNOTAND2inst13inst10inst9inst1421mux

(二路选择器与计数器之间连了一个组合电路,以屏蔽进位信号)

② 按键的“抖动”的消除。

所谓的“抖动”是指一次按键时的弹跳现象,通常实验板中按键所用的开关为机械性开关,由于机械触点的弹性作用,按键开关在闭合时并不能马上接通,而断开的时候也不能马上断开,使得闭合及断开的瞬间伴随一系列的电压抖动,从而导致本来一次按键,希望计数一次,结果因为抖动计数多次,且次数随机,这样严重影响了时间的校对。

消除抖动较为简单的方法是利用触发器,比如可以使用D触发器进行消抖。原因在于,D触发器边沿触发,则在除去时钟边沿到来前一瞬间之外的绝大部分时间都不接受输入,自然消除了抖动。详见下图

DFFDPRNNOThinputQinst8CLRNinst3DFFDPRNQCLRNinst4NOTinst9

(加D触发器防抖动)

4

③ 计时采用1Hz的脉冲驱动计数器计数,而校对时间时应选用相对高频率的信号驱动计数器以达到快速

校对时间的目的。显然,这两种计数脉冲之间需要进行相应的选择切换。于是将计时和校时模块合起来的电路实现可以实现(见图3)。两种脉冲信号用两路选择器进行选择,选择条件为是否按键。按键输出经过了消抖的过程。

3.整点报时模块

该模块的功能要求是:计时到59分52秒时,每两秒一次低音报时,整点时进行高音报时,可以将报时信号接到实验板上的扬声器输出。而以不同频率的脉冲信号区分低音和高音报时。进行报时的条件是计数器计数至所要求的时间点,因而需要实现一个比较模块,将分计数器和秒计数器的输出连至比较模块输入端完成比较过程。

zdbsjm[7..4]jm[3..0]js[7..4]js[3..0]mh[3..0]ml[3..0]sh[3..0]sl[3..0]sig500sig1kinst16

(整点报时顶层图)

以下是整点报时的比较模块设计VHDL语言 library ieee;

use ieee.std_logic_11.all; use ieee.std_logic_unsigned.all; entity zdbs is

port(mh,ml,sh,sl:in std_logic_vector(3 downto 0); sig500,sig1k: out std_logic );

end zdbs;

architecture behavior of zdbs is begin

sig500<='1' when mh=\"0101\"and ml=\"1001\"and sh=\"0101\"and (sl=\"0010\" or sl=\"0100\" or sl=\"0110\"or sl=\"1000\") ----------------------------------比较,当时间为59分2、4、6、8钞时,sig500端输出为高电平。

else '0';

sig1k<='1' when mh=\"0000\"and ml=\"0000\"and sh=\"0000\"and sl=\"0000\"

else '0'; ------------------------------比较,当时间为0分0钞时,sig1k端输出为高电平。 end behavior;

4.分频模块

在本系统中需要用到多种不同频率的脉冲信号,上至高音报时,下至1Hz的计秒脉冲。所有这些脉冲信号均可以通过一个基准频率分频器生成。基准频率分频器就是一个进制很大的计数器,利用计数器的分频功能,从不同的输出位得到所需要的脉冲信号。

5

freq_dividerhz1clkhz1hz4hzhz512hzhz512hz4inst12 (分频模块顶层图)

以下是分频模块设计VHDL语言

LIBRARY IEEE;

USE IEEE.STD_LOGIC_11.ALL; USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY freq_divider IS

PORT(clk : IN STD_LOGIC; hz1 : OUT STD_LOGIC; hz4 : OUT STD_LOGIC; hz : OUT STD_LOGIC; hz512 : OUT STD_LOGIC); END freq_divider;

ARCHITECTURE rtl OF freq_divider IS

SIGNAL count : STD_LOGIC_VECTOR(9 DOWNTO 0); BEGIN

PROCESS(clk) BEGIN

IF (clk'event and clk='1') THEN IF(count=\"1111111111\") THEN Count <= (OTHERS =>'0'); ELSE

Count <= count +1; END IF ; END IF ; END PROCESS;

hz512 <= count(0); --------------------每2个时钟产生一个时钟输出 hz <= count(3);---------------------每16个时钟产生一个时钟输出 hz4 <= count(7);---------------------每256个时钟产生一个时钟输出 hz1 <= count(9);---------------------每1024个时钟产生一个时钟输出 END rtl;

5.动态显示模块

在动态方式下,所有的数码管对应同一组七段码,每一个数码管由一个选择段控制点亮或熄灭,如果全部点亮,则都显示相同的数字。若要实现6位不同时间的显示。则需要利用人的视觉缺陷。

具体来讲,可以在6个不同的时间段分别将每组时间经过七段译码后输出到6个数码管,当某一组时间的

6

七段码到达时,只点亮对应位置上的数码管,显示相应的数字;下一个循环将相邻一组时间的七段码送至数码管,同样只点亮相应位置的数码管,6次一个循环,形成一个扫描序列。只要扫描频率超过人眼的视觉暂留频率(24Hz),就可以达到点亮单个数码管,却能享有6个同时显示的视觉效果,人眼辨别不出差别,而且扫描频率越高,显示越稳定。

dtsmclkh[7..0]m[7..0]s[7..0]clkh[7..0]m[7..0]s[7..0]seg7out[6..0]sel[2..0]seg[6..0]sel[2..0]inst17 (动态显示模块顶层图)

以下是动态显示模块设计的VHDL语言 LIBRARY IEEE;

USE IEEE.STD_LOGIC_11.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY dtsm is port(

clk:in std_logic;

h:in std_logic_vector(7 downto 0); m:in std_logic_vector(7 downto 0); s:in std_logic_vector(7 downto 0);

seg7out:out std_logic_vector(6 downto 0); sel:buffer std_logic_vector(2 downto 0) ); END dtsm;

ARCHITECTURE beha of dtsm is

signal key:std_logic_vector(3 downto 0); BEGIN

PROCESS(clk)

variable dount:std_logic_vector(2 downto 0):=\"000\"; BEGIN

IF(rising_edge(clk))then---------------------开始扫描 IF dount=\"101\" then dount:=\"000\"; ELSE

dount:=dount+1; END IF; END IF; sel<=dount; end process;

7

PROCESS(sel) BEGIN

CASE sel IS---------------------------------------多路选择代码 when \"000\"=>key<=h(7 downto 4); when \"001\"=>key<=h(3 downto 0); when \"010\"=>key<=m(7 downto 4); when \"011\"=>key<=m(3 downto 0); when \"100\"=>key<=s(7 downto 4); when \"101\"=>key<=s(3 downto 0); when others=>null; END CASE; END PROCESS; PROCESS (key) BEGIN

case key is-------------------------------------七段显示代码 when\"0000\"=>seg7out<=\"0111111\"; when\"0001\"=>seg7out<=\"0000110\"; when\"0010\"=>seg7out<=\"1011011\"; when\"0011\"=>seg7out<=\"1001111\"; when\"0100\"=>seg7out<=\"1100110\"; when\"0101\"=>seg7out<=\"1101101\"; when\"0110\"=>seg7out<=\"1111101\"; when\"0111\"=>seg7out<=\"0000111\"; when\"1000\"=>seg7out<=\"1111111\"; when\"1001\"=>seg7out<=\"1101111\"; when\"1010\"=>seg7out<=\"1110111\"; when\"1011\"=>seg7out<=\"1111100\"; when\"1100\"=>seg7out<=\"0111001\"; when\"1101\"=>seg7out<=\"1011110\"; when\"1110\"=>seg7out<=\"1111001\"; when\"1111\"=>seg7out<=\"1110001\"; when others=>null; END CASE; END PROCESS; END beha;

8

6、闹钟模块

ahinputhz4cnt24AND2halr[3..0]clkql[3..0]qh[3..0]halr[7..4]inst23inst22tcVCChz4aminputAND2cnt60malr[3..0]clkql[3..0]inst25malr[7..4]clrqh[3..0]tc (通过24进制计数器置入时信号,通过60进制计数器置入分信号)

selalarmalarmseth[7..0]jh[7..0]jm[7..0]js[7..0]halr[7..0]malr[7..0]js[7..0]selhclo[7..0]mclo[7..0]sclo[7..0]halr[7..0]malr[7..0]salr[7..0]inst18h[7..0]s[7..0]m[7..0]s[7..0]m[7..0]inst24 (时钟-闹钟信号选择模块)

以下是时钟闹钟信号选择模块设计的VHDL语言: library ieee;

use ieee.std_logic_11.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity alarmset is port(sel:in std_logic;

hclo,mclo,sclo,halr,malr,salr: in std_logic_vector(7 downto 0); h,s,m:out std_logic_vector(7 downto 0)); end alarmset;

architecture beh of alarmset is begin

process(sel) begin

if(sel='0')then h<=hclo; --------------------------------当sel输入端为低电平时,把时钟信号传递到输出端 m<=mclo; s<=sclo;

else h<=halr; --------------------------------当sel输入端为高电平时,把闹钟置入的信号传递到输出端 m<=malr;

9

s<=salr; end if;

end process; end beh;

(当选择开关输入为低电平时,把时钟信号传递到动态显示模块;当选择开关输入为高电平时,把闹钟信号传递到动态显示模块。)

alarmcmpjh[7..0]jm[7..0]halr[7..0]malr[7..0]h[7..0]m[7..0]halr[7..0]malr[7..0]stopinst11sig

(比较模块)

以下是比较模块设计的VHDL语言 library ieee;

use ieee.std_logic_11.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity alarmcmp is

port( h,m,halr,malr: in std_logic_vector(7 downto 0); stop:in std_logic;

sig:out std_logic); end alarmcmp;

architecture beh of alarmcmp is

begin

process(h,m,halr,malr,stop) begin

if stop='1'then

sig<='0'; -----------------当stop端输入为高电平,输出为低电平 end if;

if h=halr and m=malr and stop='0' then

sig<='1'; -----------------当stop端输入为低电平、时钟传来的信号与闹钟置入的信号一致时,输出为高电平 else sig<='0'; --------------------------------当时钟传来的信号与闹钟置入的信号不一致时,输出为低电平

end if;

end process; end beh;

10

sel2selalarmhinputselipabhinputsahinputinst31sel2selalarmminputminputsselipabaminputinst32

(输入选择电路顶层图)

当selalarm端输入为低电平时,时钟实现计时功能,选择电路把输入信号传递到计时模块,使其调整时间; 当selalarm端输入为高电平时,时钟实现闹钟设置功能,选择电路把输入信号传递到闹钟模块,使其设置闹钟。

三、总结

通过这次的数逻课程设计后,我学到了很多,对于VHDL语言有了进一步的认识,掌握了实验板上某些按键的功能。我明白了很多东西都是事在人为,因为一开始弄得时候,什么也不会,后来通过询问同学和找资料,才慢慢的懂了一些。会了以后,感觉还是很好玩的,当报时的声音响起的时候,心里面还是很有成就感的。本次试验不是很困难,用心的话还是挺好玩的,毕竟的合成图老师已给出,只需要按照步骤来就可以了。

然后因为这次实验,我也明白了自己需要学的东西还是很多的,毕竟很多东西都需要询问和查资料才懂,但对于QuartusⅡ还是会比之前更加熟练了,熟能生巧的缘故吧,反正操作起来挺顺手的。但一开始没有将文件置顶,又建立了很多工程名,后来经过老师的指导,才弄好了,因为学的不好的缘故,所以今后还是好好学习吧。总而言之,这次实验给了我很大的学习动力。

11

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo6.cn 版权所有 赣ICP备2024042791号-9

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务