基于VHDL的电子钟设计.docx
- 文档编号:9315660
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:27
- 大小:21.25KB
基于VHDL的电子钟设计.docx
《基于VHDL的电子钟设计.docx》由会员分享,可在线阅读,更多相关《基于VHDL的电子钟设计.docx(27页珍藏版)》请在冰点文库上搜索。
基于VHDL的电子钟设计
EDA
课程设计
题目:
利用VHDL进行电子钟设计
院系:
物理工程学院
专业班级:
学生姓名:
学生学号:
2010年6月3日
一、设计要求:
功能:
显示年月日、星期、时分秒、闹钟和整点报时(几点响几下),并且所有显示均可调。
二、设计原理:
1)模块设计:
根据要求可将实验分成三个大的模块:
年月日,时分秒和闹钟。
时分秒:
时、分、秒分为三个独立模块,同时秒的脉冲为1HZ,秒进位作为分的时钟信号,分进位作为时的时钟信号,时进位作为日和星期的时钟信号。
年月日:
日进位作为月的时钟信号,月进位作为年的时钟信号。
由于年、月、日三者之间存在反馈机制(即闰年与非闰年有差别,大月与小月间有差别),故将它们放在同一个模块中。
闹钟和整点报时具有相似性,故归为一类。
总共需要13个独立模块。
2):
显示设计:
根据实验箱上只有8个LED数码管的具体情况,将显示分三种模式显示出来:
(1)星期、时分秒;
(2)年月日;(3)闹钟时间。
3):
按键设计:
共设计5个按键:
J8键:
高电平显示年月日,低电平显示星期、时分秒。
J7键:
高电平显示闹钟。
J5键:
系统复位键,高电平有效。
J3键:
可调区域选择键,高电平有效,选中可调区域相应灯亮。
J1键:
累加键,高电平有效,可调区域实现累加。
4):
报时设计:
蜂鸣器在整点报时时几点响几下,闹时响一分钟。
5):
时钟设计:
秒和时钟clk接1HZ,其它模块clk1接2HZ。
6):
模式设计:
实验箱选择模式5。
三、注意事项:
1:
由于本设计采用了两个不同频率的时钟,所以在刚下载完程序后会发现所有数码管都在跑动。
解决办法:
按下J3键,将各个模块扫描一遍。
2:
xian1中输出的res需和J5的reset经过一个或门后输出,再与各模块的reset相连。
四:
实验程序:
----------------------------------------------------------秒计数器
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitysecondis
port(clk,setmin,reset,clk1:
instd_logic;--clk接1HZclock0,clk1为按键触发时钟,接2HZclk2
seout:
outstd_logic_vector(6downto0);
enmin:
outstd_logic);
endentitysecond;
architectureoneofsecondis
signalcount:
std_logic_vector(6downto0);
signalenmin1,enmin2:
std_logic;--enmin1为59秒时进位信号,enmin2由clk1调制后的手动调分脉冲
begin
seout<=count;
enmin2<=(setminandclk1);
enmin<=(enmin1orenmin2);
process(clk,reset,setmin)
begin
if(reset='1')thencount<="0000000";
elsif(clk'eventandclk='1')then
if(count(3downto0)="1001")then
if(count<16#60#)then--即60H,为16进制数写法,此步是必须的
if(count="1011001")then
enmin1<='1';count<="0000000";--如果count已经到了59D,则置进位为1及count为0
else
count<=count+7;--则加7,由09h变为10h
endif;
else
count<="0000000";-->60h,为无效操作
endif;
elsif(count<16#60#)then
count<=count+1;
enmin1<='0';
else
count<="0000000";
endif;
endif;
endprocess;
endone;
---------------------------------------------分计数器
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityminis
port(clk,sethour,reset,clk1:
instd_logic;
miout:
outstd_logic_vector(6downto0);
enhour:
outstd_logic);
endentitymin;
architectureoneofminis
signalcount:
std_logic_vector(6downto0);
signalenhour1,enhour2:
std_logic;--enhour1为59秒时进位信号,enhour2由clk2调制后的手动调分脉冲
begin
miout<=count;
enhour2<=(sethourandclk1);
enhour<=(enhour1orenhour2);
process(clk,reset,sethour)
begin
if(reset='1')thencount<="0000000";
elsif(clk'eventandclk='1')then
if(count(3downto0)="1001")then
if(count<16#60#)then
if(count="1011001")then
enhour1<='1';count<="0000000";
else
count<=count+7;
endif;
else
count<="0000000";
endif;
elsif(count<16#60#)then
count<=count+1;
enhour1<='0';
else
count<="0000000";
endif;
endif;
endprocess;
endone;
-------------------------------------时计数器
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityhouris
port(clk,clk1,setda,setweek,reset:
instd_logic;
enda,enweek:
outstd_logic;
hout:
outstd_logic_vector(5downto0));
endentityhour;
architecturefunofhouris
signalcount:
std_logic_vector(5downto0);
signaljwd1,jwd2,jwd3:
std_logic;---jwd1是进位信号,jwd1是天,jwd2是星期
begin
hout<=count;
jwd2<=(setdaandclk1);
jwd3<=(setweekandclk1);
enweek<=(jwd1orjwd3);
enda<=(jwd1orjwd2);
process(clk,reset,setda,setweek)
begin
if(reset='1')then
count<="000000";
elsif(clk'eventandclk='1')then
if(count(3downto0)="1001")then
if(count<16#23#)then--注意这里的写法与前面有一点不同,后面模块如此。
count<=count+7;
else
count<="000000";
endif;
elsif(count="100011")then
jwd1<='1';count<="000000";
elsif(count<16#23#)then
count<=count+1;
jwd1<='0';
else
count<="000000";
endif;
endif;
endprocess;
endfun;
----------------------------------------------星期
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityweekis
port(clk,reset:
instd_logic;
weout:
outstd_logic_vector(2downto0));
endentityweek;
architectureoneofweekis
signalcount:
std_logic_vector(2downto0);
begin
weout<=count;
process(clk,reset)
begin
if(reset='1')then
count<="001";
elsif(clk'eventandclk='1')then
if(count<16#7#)then
count<=count+1;
else
count<="001";
endif;
endif;
endprocess;
endone;
---------------------------------------------年月日
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitydmy3is
port(reset,clk1,clk,setm,sety:
instd_logic;--clk1为计数时钟信号,clk接前面hour输出信号
dtout:
outstd_logic_vector(5downto0);--dtout为日输出
mtout1:
outstd_logic_vector(4downto0);--mtout为月输出
ytout:
outstd_logic_vector(15downto0));--ytout为年输出
endentitydmy3;
architectureoneofdmy3is
signalcountd:
std_logic_vector(5downto0);
signalcountm:
std_logic_vector(4downto0);
signalcounty:
std_logic_vector(7downto0);
signaly1:
std_logic_vector(3downto0);
signaly2:
std_logic_vector(3downto0);
signalday_out,month_out:
std_logic;---程序内部天和月的进位,也可放于前面设为buffer
signalmtout:
std_logic_vector(4downto0);
signalday_out1,day_out2,month_out1,month_out2:
std_logic;
begin
dtout<=countd;
mtout<=countm;--此处mtout的作用是后面作为一个数据的中转
mtout1<=mtout;
ytout(15downto8)<="00100000";--年的前两位固定20,显示为16进制
ytout(7downto0)<=county;--年的后面两位
y1<=county(3downto0);--判断闰年的标志位
y2<=county(7downto4);
day_out2<=(setmandclk1);--setm为手动调月控制信号、高电平有效
day_out<=(day_out2orday_out1);
month_out2<=(setyandclk1);--sety为手动调年控制信号、高电平有效
month_out<=(month_out1ormonth_out2);
pro1:
process(month_out,reset)--对年的设制
begin
if(reset='1')then
county<="00000000";--若reset为1,则异步清零
elsif(month_out'eventandmonth_out='1')then--否则,若month_out上升沿到
if(county(3downto0)="1001")then--若个位计数值恰好到“1001”
if(county<16#99#)then--又若count小于16#99#,共是100年
county<=county+7;--则加7,9变为10
else
county<="00000000";--若count不小于16#99#,则count复0
endif;
elsif(county<16#99#)then--若各位计数未到“1001”则转到此句再判断;
county<=county+1;--否则若count<16#99#,count加1
else
county<="00000000";--则count复0(此句对无效状态电路可自启动)
endif;--endif(count(3downto0)=“1001”)
endif;--endif(reset=‘1’)
endprocess;
pro2:
process(day_out,reset,sety)--对月的调制
begin
if(reset='1')then
countm<="00001";--1月,初始状态
elsif(day_out'eventandday_out='1')then
if(countm(3downto0)="1001")then
if(countm<16#12#)then
countm<=countm+7;
else
countm<="00001";
endif;
elsif(countm="10010")then
month_out1<='1';countm<="00001";
elsif(countm<16#12#)then
countm<=countm+1;
month_out1<='0';
else
countm<="00001";
endif;
endif;
endprocess;
pro3:
process(clk,reset,setm)--小时的输出
begin
if(reset='1')then
countd<="000001";
elsif(clk'eventandclk='1')then
if(mtout=1ormtout=3ormtout=5ormtout=7--大月份31天
ormtout=8ormtout=10ormtout=12)then
if(countd(3downto0)="1001")then--末尾是9时
if(countd<16#32#)then
countd<=countd+7;--十进制调整
else
countd<="000001";
endif;
elsif(countd="110001")then--到了第31天
day_out1<='1';countd<="000001";
elsif(countd<16#32#)then--末尾不是9,又未到第31天
countd<=countd+1;
day_out1<='0';
else
countd<="000001";
endif;
elsif(mtout=4ormtout=6ormtout=9ormtout=11)then--小月份30天
if(countd(3downto0)="1001")then
if(countd<16#31#)then
countd<=countd+7;
else
countd<="000001";
endif;
elsif(countd="110000")then--30天
day_out1<='1';countd<="000001";
elsif(countd<16#31#)then
countd<=countd+1;
day_out1<='0';
else
countd<="000001";
endif;
Else--对闰年的判断
if((Y2=0ORY2=2ORY2=4ORY2=6ORY2=8)AND(Y1=0ORY1=4ORY1=8))OR
((Y2=1ORY2=3ORY2=5ORY2=7ORY2=9)AND(Y1=2ORY1=6))THEN
if(countd(3downto0)="1001")then
if(countd<16#30#)then
if(countd="101001")then
day_out1<='1';countd<="000001";
else
countd<=countd+7;
endif;
else
countd<="000001";
endif;
elsif(countd<16#30#)then
countd<=countd+1;
day_out1<='0';
else
countd<="000001";
endif;
else--不是闰年,二月份28天
if(countd(3downto0)="1001")then
if(countd<16#29#)then
countd<=countd+7;
else
countd<="000001";
endif;
elsif(countd="101000")then
day_out1<='1';countd<="000001";
elsif(countd<16#29#)then
countd<=countd+1;
day_out1<='0'after100ns;
else
countd<="000001";
endif;
endif;--判断闰年的语句
endif;--判断月份的语句
endif;
endprocess;
endone;
-------------------------------------整点报时
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityalarmis
port(clk1:
instd_logic;
zmin,zse:
instd_logic_vector(6downto0);
hour:
instd_logic_vector(5downto0);
speak:
outstd_logic);
endentityalarm;
architectureoneofalarmis
signalcount:
std_logic_vector(5downto0);
signalzhour:
std_logic_vector(5downto0);--zhour将与hour进行比较,也可是buffer
signalcount1:
std_logic_vector(1downto0);
begin
zhour<=count;
process(clk1)
begin
speak<=count1(0);
if(clk1'eventandclk1='1')then
if(zse="0000000")then---当秒为0时,count为0,只有让分秒为开才有可能实现几点响几下
count<="000000";
endif;
if(zmin="0000000")then--且当分也为0时,开始让count计时,此时计时不受秒的影响
if(zhour if(count(3downto0)="1001")the
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 VHDL 电子钟 设计