数字钟VHDL程序.docx
《数字钟VHDL程序.docx》由会员分享,可在线阅读,更多相关《数字钟VHDL程序.docx(18页珍藏版)》请在冰豆网上搜索。
![数字钟VHDL程序.docx](https://file1.bdocx.com/fileroot1/2023-2/4/c8462fa4-524b-4ad6-8226-dc656a34db7f/c8462fa4-524b-4ad6-8226-dc656a34db7f1.gif)
数字钟VHDL程序
大连理工大学本科实验报告
题目:
数字钟的VHDL设计
课程名称:
数字电路课程设计
学院(系):
电子信息与电气工程学部
专业:
电子信息工程
班级:
学生姓名:
学号:
完成日期:
成绩:
2013年12月15日
数字钟的VHDL设计
1.设计任务及要求:
设计任务:
设计一台能显示时、分、秒的数字钟。
具体要求如下:
(1)设计一个数字钟,能够显示当前时间,分别用6个数码管显示小时、分钟、秒钟的时间,秒针的计数频率为1Hz,可由系统脉冲分频得到。
(2)在整点进行提示,可通过LED闪烁实现,闪烁频率及花型可自己设计。
(3)能够调整小时和分钟的时间,调整的形式为通过按键进行累加。
(4)具有闹钟功能,闹钟时间可以任意设定(设定的形式同样为通过按键累加),并且在设定的时间能够进行提示,提示同样可以由LED闪烁实现
设计要求:
(1)编写设计报告,要求包括方案选择、程序代码清单、调试过程、测试结果及心得体会。
2.设计原理
1HZ
图1数字钟的系统框图
该系统由振荡器、分频器、“时、分、秒”计数器、译码器及显示器、校时电路、整点报时电路等组成。
石英晶体振荡器和分频器产生整个系统的时基信号,它直接决定计时系统的精度。
“秒计数器”采用六十进制计数器,每累计60秒向“分计数器”进位;“分计数器”采用六十进制计数器,每累计60分向“时计数器”进位;“时计数器”采用二十四进制计数器,按照“24翻1”规律计数。
“时、分、秒”计数器的输出经译码器送显示器显示。
校时电路用来当计时出现误差时对“时、分、秒”进行校对调整。
整点报时电路是根据计时系统的输出状态产生一脉冲信号,然后去触发音频发生器实现报时。
3.设计过程
3.1.设计思路
时钟脉冲信号作为数字钟的时间基准,再经分频器输出标准秒脉冲。
秒计数器计满60后向分计数器进位,分计数器计满60后向小时计数器进位,小时计数器是计满24后,系统自动复位重新开始计数。
计数器的输出经译码电路后送到显示器显示。
可以用校时电路进行校时。
整点报时电路在每小时的最后50秒开始报时间隔一秒报一次时直至下一小时开始。
3.2.数字钟的设计方案
数字钟的设计包括编码模块、分频模块、秒计时模块、分计时模块、小时计时模块、闹钟模块和报时模块。
该数字钟可以实现3个功能:
计时功能、报时功能、闹铃和设置时间功能。
3.2.1.编码模块
编码模块主要是对时、分、秒的设置输入。
3.2.2.分频模块
在数字钟的设计中,外部输入时钟信号clk1的频率为50Mhz,其分频后的频率为clk,使其分频结果为1hz,用来提供给秒计时模块、分计时模块、小时计时模块。
3.2.3.秒计时模块
将“秒计时脉冲”clk接信号源单元的1HZ脉冲信号,此时秒显示将从00计时到59,然后回到00,重新计时。
在秒位进行计时的过程中。
秒计时器是由一个60进制的计数器构成的,具有置数和计数功能。
其中reset为置数信号,当reset为1时,秒计时器置数。
clk为驱动秒计时器的时钟,sec2、sec1为秒计时器的高位和低位输出。
3.2.4.分计时模块
分计时电路:
将“分计时脉冲”clk接信号源单元的c1脉冲信号,此时分显示将从00计时到59,然后回到00,重新计时。
在分位进行计时的过程中。
分计时器是由一个60进制的计数器构成的,具有置数和计数功能。
其中rese为置数信号,当reset为1时,分计时器置数。
fen4、fen3为分计时器的高位和低位输出。
3.2.5.小时计时模块
将“小时计时脉冲”clk接信号源单元的c2脉冲信号,此时小时显示将从00计时到23,然后回到00,重新计时。
时计时器是由一个24进制的计数器构成的,具有置数和计数功能。
其中的reset为置数信号,当reset为1时,时计时器置数。
shi6、shi5为时计时器的高位和低位输出。
3.2.6.报时模块
当分位到59时,秒位计到51秒、53秒、55秒、57秒、59秒时报时一次,而后小时位加1。
3.2.7.VHDL引脚分配图
4.源程序
4.1.数字钟整体程序
整个程序分为六个部分,分别为分频部分、校时部分、秒部分、分部分、小时部分和报时部分。
4.2.VHDL程序及波形分析
4.2.1.VHDL程序
libraryieee;--count60
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitycount60is
port(clk:
instd_logic;
reset:
instd_logic;
set:
instd_logic;
inc:
instd_logic;
out1:
outstd_logic_vector(3downto0);
out2:
outstd_logic_vector(3downto0);
c:
outstd_logic;
alight:
outstd_logic);
end;
architecturerun2ofcount60is
signalts1,ts2,as1,as2:
std_logic_vector(3downto0):
="0000";
signaltclk,aclk:
std_logic;
begin
process(inc,clk,set)--根据设置模式,处理inc上的脉冲信号
begin
ifset='0'then--时间调整模式
aclk<='0';
ifclk='1'andinc='1'then--clk=1则tclk<=0,通过挖洞方式添加一个脉冲
tclk<='0';
elsifclk='0'andinc='1'then--clk=0,则tclk<=1,产生一个高电平,添加一脉冲
tclk<='1';
else
tclk<=clk;
endif;
elsifset='1'then--闹铃调整模式
tclk<=clk;
aclk<=inc;--inc上的脉冲直接修改闹铃定时值
endif;
endprocess;
process(tclk,reset)
begin
if(reset='0')thents1<="0000";ts2<="0000";
elsif(tclk'eventandtclk='1')then
ifts1="1001"thents1<="0000";
ifts2="0101"thents2<="0000";
elsets2<=ts2+1;
endif;
elsets1<=ts1+1;--计数过程
endif;
endif;
endprocess;--结束进程
process(aclk,reset)
begin
if(reset='0')thenas1<="0000";as2<="0000";
elsif(aclk'eventandaclk='1')then
ifas1="1001"thenas1<="0000";
ifas2="0101"thenas2<="0000";
elseas2<=as2+1;
endif;
elseas1<=as1+1;--计数过程
endif;
endif;
endprocess;--结束进程
process(ts1,ts2,as1,as2)--显示时间或闹铃定时值
begin
ifset='0'then--显示时间
out1<=ts1;
out2<=ts2;
else--显示定时值
out1<=as1;
out2<=as2;
endif;
endprocess;
process(ts1,ts2,as1,as2)--判断定时值与时间值相等,输出闹铃触发信号
begin
if(ts1="1001"andts2="0101")then
c<='1';
elsec<='0';
endif;
ifts1=as1andts2=as2then
alight<='1';
else
alight<='0';
endif;
endprocess;
endrun2;
libraryieee;--count24
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitycount24is
port(clk:
instd_logic;
reset:
instd_logic;
set:
instd_logic;
inc:
instd_logic;
out1:
outstd_logic_vector(3downto0);
out2:
outstd_logic_vector(3downto0);
c:
outstd_logic;
alight:
outstd_logic);
end;
architecturerun1ofcount24is
signalts1,ts2,as1,as2:
std_logic_vector(3downto0):
="0000";
signaltclk,aclk:
std_logic;
begin
process(inc,clk,set)--根据设置模式,处理inc上的脉冲信号
begin
ifset='0'then--时间调整模式
aclk<='0';
ifclk='1'andinc='1'then--clk=1则tclk<=0,通过挖洞方式添加一个脉冲
tclk<='0';
elsifclk='0'andinc='1'then--clk=0,则tclk<=1,产生一个高电平,添加一脉冲
tclk<='1';
else
tclk<=clk;
endif;
elsifset='1'then--闹铃调整模式
tclk<=clk;
aclk<=inc;--inc上的脉冲直接修改闹铃定时值
endif;
endprocess;
process(tclk,reset)
begin
if(reset='0')thents1<="0000";ts2<="0000";
elsif(tclk'eventandtclk='1')then
ifts2<"0010"then
if(ts1="1001")thents1<="0000";ts2<=ts2+1;
elsets1<=ts1+1;
endif;
elsif(ts2="0010")then
if(ts1="0011")then
ts1<="0000";ts2<="0000";--计数过程
elsets1<=ts1+1;
endif;
endif;
endif;
endprocess;--结束进程
process(aclk,reset)
begin
if(reset='0')thenas1<="0000";as2<="0000";
elsif(aclk'eventandaclk='1')then
ifas2<"0010"then
if(as1="1001")thenas1<="0000";as2<=as2+1;
elseas1<=as1+1;
endif;
elsif(as2="0010")then
if(as1="0011")then
as1<="0000";as2<="0000";--计数过程
elseas1<=as1+1;
endif;
endif;
endif;
endprocess;--结束进程
process(ts1,ts2,as1,as2)--显示时间或闹铃定时值
begin
ifset='0'then--显示时间
out1<=ts1;
out2<=ts2;
else--显示定时值
out1<=as1;
out2<=as2;
endif;
endprocess;
process(ts1,ts2,as1,as2)--判断定时值与时间值相等,输出闹铃触发信号
begin
ifts1="0010"andts2="0011"then
c<='1';
elsec<='0';
endif;
ifts1=as1andts2=as2then
alight<='1';
else
alight<='0';
endif;
endprocess;
endrun1;
libraryieee;--xianshi
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityxianshiis
port(clk:
instd_logic_vector(3downto0);
qq:
outstd_logic_vector(6downto0));
end;
architecturerun3ofxianshiis
begin
process(clk)
begin
caseclkis
when"0000"=>qq<="1000000";
when"0001"=>qq<="1111001";
when"0010"=>qq<="0100100";
when"0011"=>qq<="0110000";
when"0100"=>qq<="0011001";
when"0101"=>qq<="0010010";
when"0110"=>qq<="0000010";
when"0111"=>qq<="1111000";
when"1000"=>qq<="0000000";
whenothers=>qq<="0010000";
endcase;
endprocess;
end;
libraryieee;--shizhong
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityshizhongis
port(clk:
instd_logic;--PIN_N2
reset:
instd_logic;--PIN_N25
set:
instd_logic;--PIN_N26
inc1,inc2,inc3:
instd_logic;--PIN_G26,PIN_N23,PIN_P23
shi6,shi5,fen4,fen3,miao2,miao1:
outstd_logic_vector(6downto0);
alight,light1,light2:
outstd_logic);--闹铃
end;
architecturerunofshizhongis
signalsshi6,sshi5,sfen4,sfen3,smiao2,smiao1:
std_logic_vector(3downto0);
signalc1,c2,c3,clk1s,clk2ms,clk1ms:
std_logic;
signalalight1,alight2,alight3:
std_logic;
componentcount60
port(clk:
instd_logic;
reset:
instd_logic;
set:
instd_logic;
inc:
instd_logic;
out1:
outstd_logic_vector(3downto0);
out2:
outstd_logic_vector(3downto0);
c:
outstd_logic;
alight:
outstd_logic);
endcomponent;
componentcount24
port(clk:
instd_logic;
reset:
instd_logic;
set:
instd_logic;
inc:
instd_logic;
out1:
outstd_logic_vector(3downto0);
out2:
outstd_logic_vector(3downto0);
c:
outstd_logic;
alight:
outstd_logic);
endcomponent;
componentxianshi
port(clk:
instd_logic_vector(3downto0);
qq:
outstd_logic_vector(6downto0)
);
endcomponent;
begin
process(clk)
variablecount1:
integerrange0to49999999;
begin
if(clk'eventandclk='1')thencount1:
=count1+1;--在clk的上升沿计数
ifcount1<=24999999thenclk1s<='0';
elsifcount1<=49999999thenclk1s<='1';
elsecount1:
=0;
endif;
endif;
endprocess;--产生周期为1s的时钟信号
process(clk)
variablecount2:
integerrange0to99999;
begin
if(clk'eventandclk='1')thencount2:
=count2+1;--在clk的上升沿计数
ifcount2<=49999thenclk2ms<='0';
elsifcount2<=99999thenclk2ms<='1';
elsecount2:
=0;
endif;
endif;
endprocess;--产生周期为2ms的时钟信号500Hz
process(clk)
variablecount3:
integerrange0to49999;
begin
if(clk'eventandclk='1')thencount3:
=count3+1;--在clk的上升沿计数
ifcount3<=24999thenclk1ms<='0';
elsifcount3<=49999thenclk1ms<='1';
elsecount3:
=0;
endif;
endif;
endprocess;--产生周期为1ms的时钟信号1000Hz
process(alight1,alight2,alight3)
begin
ifalight1='1'andalight2='1'andalight3='1'
thenalight<='1';
elsealight<='0';
endif;
endprocess;
process(sfen4,sfen3,smiao2,smiao1)
begin
ifsfen4="0101"andsfen3="1001"then
ifsmiao2="0101"then
ifsmiao1="0001"then
light1<=clk2ms;
elsifsmiao1="0011"then
light1<=clk2ms;
elsifsmiao1="0101"then
light1<=clk2ms;
elsifsmiao1="0111"then
light1<=clk2ms;
elsifsmiao1="1001"then
light2<=clk1ms;
else
light1<='0';
light2<='0';
endif;
endif;
endif;
endprocess;
u1:
count60portmap(clk1s,reset,set,inc1,smiao1,smiao2,c1,alight1);
u2:
count60portmap(c1,reset,set,inc2,sfen3,sfen4,c2,alight2);
u3:
count24portmap(c2,reset,set,inc3,sshi5,sshi6,c3,alight3);
u4:
xianshiportmap(smiao1,miao1);
u5:
xianshiportmap(smiao2,miao2);
u6:
xianshiportmap(sfen3,fen3);
u7:
xianshiportmap(sfen4,fen4);
u8:
xianshiportmap(sshi5,shi5);
u9:
xianshiportmap(sshi6,shi6);
endrun;
4.2.2.仿真波形
60进制仿真波形
24进制仿真波形
5.实验结果及说明
本实验采用VHDL语言描述系统功能,并在QUARTUSII工具软件中进行仿真,下载到EDA实验箱进行验证。
配置文件下载成功后,上电后,秒满59向分进1后又从00开始计数,分满59向小时进1后从00开始计数,小时满24从00开始计数。
按键reset后,计时停止,可以用键key[2]、key[1]、key[0]分别对小时、分、秒进行重新设置时间数码管显示为设置的新时间,再按键reset后,系统就再设置的时间上开始计数。
当时间到59分51、53、55、55、59秒时,输出报时信号。