EDA实验数字闹钟的设计.docx
《EDA实验数字闹钟的设计.docx》由会员分享,可在线阅读,更多相关《EDA实验数字闹钟的设计.docx(19页珍藏版)》请在冰豆网上搜索。
![EDA实验数字闹钟的设计.docx](https://file1.bdocx.com/fileroot1/2023-5/19/f5d8b011-b1e6-414b-ac36-e381f2a957b5/f5d8b011-b1e6-414b-ac36-e381f2a957b51.gif)
EDA实验数字闹钟的设计
实验题目:
数字闹钟
1.实验内容:
设计一个带闹钟功能的24小时计时器。
它包括以下几个组成部分:
①显示屏,由6个七段数码管组成,用于显示当前时间(时:
分:
秒)或设置的闹钟时间或设置当前时间;②Mkey,Hkey,Makey,Hakey键分别用来设置时钟的(分,时)和闹钟的(分,时)③TIME(时间)键,用于显示新的时间设置(将显示闹钟时间的状态转换为显示当前时间的状态);④ALARM(闹钟)键,用于显示已设置的闹钟时间;⑤扬声器(这里用一个发光二极管代替),在当前时钟时间与闹钟时间相同时,发出蜂鸣声(二极管亮)。
主要功能:
(1)计时功能:
这是本数字闹钟设计的基本功能,每隔一分钟计时一次,并在显示屏上显示当前时间。
(2)闹钟功能:
如果当前时间与设置的闹钟时间相同,则“扬声器”发出“蜂鸣声”(二极管亮)。
(3)设置新的数字钟时间:
用户用Mkey和Hkey键对当前时间进行修改。
(4)设置新的闹钟时间:
用户用Makey和Hakey键对闹钟时间进行修改。
(5)显示所设置的闹钟时间:
在正常计时显示状态下,用户直接按下“ALARM”键,则已设置的闹钟时间将显示在显示屏上。
二.设计方案:
根据系统的设计要求,整个系统分为4个模块:
时间计数器、闹钟寄存器、显示驱动器、显示模块。
功能介绍:
(1)时间计数器:
实际上是一个异步复位、异步置数的累加器,通常情况下进行时钟累加计数,必要时可置入新的时钟值,然后从该值开始新的计数。
(2)闹钟寄存器:
用于保存用户设置的闹钟时间,并可设置新的闹钟时钟时间并判断当前时间是否等于闹钟时间。
(3)显示驱动器:
用来选择显示闹钟时间还是显示当前时间。
(4)显示模块:
用来显示闹钟时间或当前时间。
设计思路:
(1)时间计数器:
时间计数有两个60进制计数器和一个24进制的计数器级联组成。
在正常计时,前面计数器的cout(进位端)作为下一个计数器的信号。
当修改当前时间时,选用频率更快的信号,使所显示的时间的值较快的达到要设定的值。
此处用一个2选1的选择器来选择适当的信号。
此处分和时的修改是分开进行的,分别用Mkey和Hkey进行控制(即:
他们作为多路选择器的sel信号)。
逻辑图:
VHDL语言:
libraryieee;-----60进制计数器
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitycnt60is
port(Clk,clrn,En:
instd_logic;
Q1,Q2:
outstd_logic_vector(3downto0);
cout:
outstd_logic);
endcnt60;
architecturebhvofcnt60is
signalCQ1,CQ2:
std_logic_vector(3downto0);
begin
process(En,Clk,clrn,CQ1,CQ2)
begin
ifclrn='1'
then
CQ1<="0000";
CQ2<="0000";
elsifClk'eventandClk='1'then
ifEn='1'then
ifCQ1<9thenCQ1<=CQ1+1;
else
CQ1<="0000";CQ2<=CQ2+1;
endif;
endif;
ifCQ1=9andCQ2=5then
CQ1<="0000";CQ2<="0000";
cout<='1';
elsecout<='0';
endif;
endif;
Q1<=CQ1;Q2<=CQ2;
endprocess;
endbhv;
LIBRARYIEEE;-------24进制计数器
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYcnt24IS
PORT(CLK,clrn,en:
INSTD_LOGIC;
CQ1,CQ2:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
COUT:
OUTSTD_LOGIC);
ENDcnt24;
ARCHITECTUREbehavOFcnt24IS
signalQ1,Q2:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
PROCESS(CLK,clrn,en)
BEGIN
ifclrn='1'then
Q1<="0000";
Q2<="0000";
elsIFCLK'EVENTANDCLK='1'THEN
ifen='1'then
Q1<=Q1+1;
IFQ1>8THENQ1<="0000";Q2<=Q2+1;
ENDIF;
endif;
IFQ2=2ANDQ1=3THENQ1<="0000";Q2<="0000";COUT<='1';
ELSECOUT<='0';
ENDIF;
ENDIF;
CQ1<=Q1;CQ2<=Q2;
ENDPROCESS;
END;
(2)闹钟寄存器:
闹钟系统的闹钟时间由闹钟寄存器保存和传递,并与当前的时间进行比较。
若两者相等(分和时分别比较,将两者的结果经过与门输出),则二极管发光。
设定新的闹钟时间的方法与修改当前时间的放法类似。
逻辑图:
libraryieee;-----闹钟寄存器(分)部分,时和分类似
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityalarm_reg1is
port(
load_new_a:
instd_logic;
Clk,Reset:
instd_logic;
T1,T2:
instd_logic_vector(3downto0);
Q1,Q2:
bufferstd_logic_vector(3downto0);
sound_alarm:
outstd_logic);
endalarm_reg1;
architecturertlofalarm_reg1is
signalCQ1,CQ2:
std_logic_vector(3downto0);
signals_a:
std_logic:
='0';
begin
process(Clk,Reset,load_new_a,T1,T2,Q1,Q2)
begin
ifReset='1'then
CQ1<="0000";CQ2<="0000";s_a<='0';
elsifClk'eventandClk='1'then
ifload_new_a='1'then
ifCQ1<9thenCQ1<=CQ1+1;
elseCQ1<="0000";CQ2<=CQ2+1;
endif;
endif;
ifCQ1=9andCQ2=5then
CQ1<="0000";
CQ2<="0000";
endif;
endif;
if(CQ1=T1andCQ2=T2)then
s_a<='1';
elses_a<='0';
endif;
Q1<=CQ1;
Q2<=CQ2;
sound_alarm<=s_a;
endprocess;
endrtl;
(3)显示驱动器:
用来选择显示闹钟时间或当前时间。
当修改闹钟时间或按下alarm时显示闹钟时间。
当修改时钟时间时或正常计时或按下time键时显示当前时间。
逻辑图:
libraryieee;----显示驱动器
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitydisplay_driveris
port(
Reset,new_time,alarm_time:
instd_logic;
T1,T2,T3,T4,A1,A2,A3,A4:
instd_logic_vector(3downto0);
Q1,Q2,Q3,Q4:
bufferstd_logic_vector(3downto0)
);
enddisplay_driver;
architecturertlofdisplay_driveris
Begin
process(Reset,T1,T2,T3,T4,A1,A2,A3,A4,Q1,Q2,Q3,Q4)
begin
ifReset='1'then
Q1<="0000";Q2<="0000";Q3<="0000";Q4<="0000";
elsifalarm_time='1'then
Q1<=A1;Q2<=A2;
Q3<=A3;Q4<=A4;
else
Q1<=T1;Q2<=T2;
Q3<=T3;Q4<=T4;
endif;
endprocess;
endrtl;
(4)显示模块:
由模6计数器,3—6译码器,6选1多路选择器和七段译码器组成。
整体组装说明:
Alarm_reg
counter
SHOW
Dispaly
Alarm_time
New_time
3、仿真验证:
(一)时间计数器:
波形图:
(1)正常的计数
(1)秒——分——时
(2)加载新的时间
信号说明:
ENDTIME:
1msGRIDESIZE:
100ns
Clk:
时钟信号Reset:
清零信号
EN:
使能端Hkey:
更改当前的时间(分)
Mkey:
更改当前时间(时)
Q1,Q2,Q3,Q4,Q5,Q6:
当前时间。
结论:
当Mkey为1时,对当前时间(分)进行修改,当Hkey为1时,对当前时间(时)进行修改。
当都为0时,正常计时,即实现了正常计时和修改当前时间的功能。
(二)闹钟寄存器:
信号说明:
Clk:
时钟信号Reset:
清零信号
Hakey:
修改闹钟时间(时)Makey:
修改闹钟时间(分)
T1,T2,T3,T4:
输入的当前时间
Aq3,aq4,aq5,aq6:
闹钟时间
Sound_alarm:
闹钟信号
结论:
当Hakey为1时对闹钟的时间(时)进行修改,当Makey为1时对闹钟的时间(分)进行修改。
该部分正确实现了闹钟和更改闹钟时间的功能。
(三)显示驱动器:
信号说明:
Reset:
清零信号alarm_time:
显示闹钟时间new_time:
显示当前时间
A1,A2,A3,A4:
输入的闹钟时间
T1,T2,T3,T4:
输入的当前时间
S1,s2,s3,s4:
选择输出的时间
结论:
当alarm_time为1时输出闹钟时间,当new_time为1时输出当前时间。
该部分正确实现了选择显示的功能。
4、下载验证:
对计时功能,闹钟功能,设置新的时间,设计新的闹钟时间,显示闹钟时间的功能进行验证。
引脚分配:
5、实验日志:
实验遇到的问题:
本次实验主要在修改当前时间遇到较大的问题。
原打算用直接输入数字的方式实现。
通过译码器将试验箱上(10个键)的译成相应的十进制数,通过移位寄存器来显示数字的不断读取,后发现工作不稳定。
后改用一个键控制一位来操控相应的数字增加,来实现修改当前时间的功能。
但VHD语言一直报错,改了好久也没能成功。
最后只好决定采用两个频率,分别实现正常计时和修改时间的功能。
在显示时,定义了alarm和time键,分别用来显示闹钟时间和当前时间。
后来修改为当alarm或Makey或Hakey为1时,显示闹钟时间,当time或Mkey或Hkey为1时,显示当前时间。
这样当修改闹钟时间和修改当前时间时,就不必按下alarm和time键了。
实验心得:
本次实验是一个综合实验,该实验分模块设计,一开始只是有大体的思路,并没有具体到每一个细节,这导致在后来的试验中进行了好多修改。
浪费了大量的时间。
以后在做综合实验时,一定要先考虑清楚。
本次实验大部分是用VHDL语言写的,期间遇到了不少错误,加深对VHDL语言的掌握。
但也意识到自己的不足,自己设计的能力还有待提高。
本次实验分模块设计,每个独立验证,让我及时找出错误,进行修改,也使各部分间的联系更加清晰。