多功能数字钟.docx
《多功能数字钟.docx》由会员分享,可在线阅读,更多相关《多功能数字钟.docx(14页珍藏版)》请在冰豆网上搜索。
多功能数字钟
设计报告
课程名称在系统编程技术
任课教师
设计题目多功能数字钟
班级
学号
一.题目分析
1.总体方框图
2.技术指标
1)时钟计数:
完成时、分、秒的正确计时并且显示所计的数字;对秒、分
——60进制计数,即从0到59循环计数,时钟——24进制计数,即从0到23循环计数,并且在数码管上显示数值。
键8开始计时。
2)时间设置:
手动调节分钟、小时,可以对所设计的时钟任意调时间,这样使数字钟真正具有使用功能。
我们可以通过实验板上的键5和4进行任意的调整,因为我们用的时钟信号均是1HZ的,所以每LED灯变化一次就来一个脉冲,即计数一次。
3)清零功能:
reset为复位键,低电平时实现清零功能,高电平时正常计数。
可以根据我们自己任意时间的复位。
4)蜂鸣器在整点时有报时信号产生,蜂鸣器报警。
产生“滴答.滴答”的报警声音。
3.功能介绍
1)具有时、分、秒计数显示功能,以24小时循环计时。
2)时钟计数显示时有LED灯的显示。
3)具有调节小时、分钟、秒及清零的功能。
4)具有整点报时功能。
该数字钟实现了计时、重置时间、整点报时三大功能。
在给数字钟重置时间后,数字钟便开始从所置的时间计时,到达59秒时,秒计时器回到0秒,并且给分钟加1;当到达59分时,分计时器回到0分钟,并且给小时加1;当到达23小时时,时计时器回到0小时;当到达59分,分计时器回到0时,报时装置输出高电平,并且持续一段时间,直到分计时器的值不为0。
二.选择方案
方案一:
用CN6无进位六进制计数器选择数码管的亮灭以及对应的数,循环扫描显示,用SEL61六选一选择器选择给定的信号输出对应的数送到七段码译码器。
K4模块进行复位,设置小时和分,输出整点报时信号和时,分,秒信号。
方案二:
根据总体方框图及各部分分配的功能可知,本系统可以由秒计数器、分钟计数器、小时计数器、整点报时、分的调整以及小时的调整和一个顶层文件构成。
采用自顶向下的设计方法,子模块利用VHDL语言设计,顶层文件用原理图的设计方法。
显示:
小时采用24进制,而分钟和秒均60进制。
终上所述,考虑到试验时的可行性,我选择了方案二。
三.细化框图
1.闹钟系统的移位寄存器的设计
本模块的功能是在CLK端口输入信号的上升沿同步下,将KEY端口的输入信号移入NEW_TIME端口的输出信号最低位,原有信息依次向左移,最高位信息丢失;而RESET端口的输入信号对NEW_TIME端口输出信号进行异步清零复位。
电路系统示意图如图所示。
2.报时系统的译码器的设计
本模块的功能是将每次按下报时系统的数字键盘后产生的一个数字所对应的10位二进制数据信号转换为1位十进制整数信号,以作为小时、分钟计数的4个数字之一,如图1.3所示。
其中KEYPAD为输入端口,接收10位二进制数据信号;VALUE为输出端口,输出相应的1位十进制整数信号。
输入数据与输出数据的译码关系见表1.4。
3.闹钟系统的闹钟寄存器的设计
闹钟寄存器模块的功能是在时钟上升沿同步下,根据LOAD_NEW_A端口的输入信号控制ALARM_TIME端口的输出,当控制信号有效(高电平)时,把NEW_ALARM_TIME端口的输入信号值输出;而RESET端口输入信号对ALARM_TIME端口的输出进行异步的清零复位。
图是闹钟寄存器模块的示意图。
4.时间计数器的设计
时间计数器模块的功能是当RESET端口输入信号为高电平时,对CURRENT_TIME端口输出信号清零复位;当LOAD_NEW_C端口输入信号为高电平时,将NEW_CURRENT_TIME端口的输入信号输出给CURRENT_TIME端口。
RESET端口D的控制优先于LOAD_NEW_C端口。
当这两个控制信号都无效时,在时钟上升沿同步下,对CURRENT_TIME端口输出信号累加1,并根据小时、分钟的规律处理进位。
图是时间计数器模块的示意图。
5.闹钟系统的显示驱动器的设计
本模块的功能是:
当SHOW_NEW_TIME端口输入信号有效(高电平)时,根据NEW_TIME端口输入信号(时间数据),产生相应的4个七段数码显示器的驱动数据,并在DISPLAY端口输出该信号。
图为显示驱动器示意图。
6.闹钟系统的分频器的设计
本模块的功能是将CLK_IN端口输入的时钟信号分频后送给CLK_OUT端口。
当RESET端口输入信号有效(高电平)时,CLK_OUT端口输出信号清零。
图为分频器示意图。
四.程序与仿真
1.闹钟模块应用程序(见附录)
2.小时模块应用程序(见附录)
3.分钟模块应用程序(见附录)
4.秒模块应用程序(见附录)
5模块打包图
1)小时模块
2)分钟模块
3)秒数模块
4)整点报时模块
五.系统联调
1.主电路图
2.仿真波形
六.硬件测试
电路引脚选择
七.结论
通过以上硬件和软件的结合运行,主控制模块能够完全实现数字钟计时定时报时的功能,对于本次实验闹钟系统得设计,通过上网查资料,我搞清原理并输出了正确系统时序仿真图与系统功能仿真图。
做硬件仿真实现的时候出现了问题,通过自己的探索与老师的指点,我检查出有一个按键不灵敏,通过修改引脚,功能得以实现。
八.课程总结
学习了EDA这门课程,我的收获比较大,计算机本来是硬件和软件共存的专业,但在实际的学习中,真正接触到硬件层次上的并不多,而EDA恰好就是硬件编程,这是一门很实用的课程,通过这门课程的学习,我们可以深入了解硬件编程的基本原理及实现方法,独立的设计制作某一系统,并以硬件方式实现.总的来说,EDA技术,是以硬件描述语言为系统逻辑描述的主要表达方式,以计算机\大规模可编程逻辑器件的开发软件及实验开发系统为设计工具,通过有关的开发软件,直至对于特定目标芯片的适配编译\逻辑映射\编程下载等工作,最终形成集成电子系统或专用集成芯片的一门新技术。
在编写顶层文件的程序时,遇到了不少问题,特别是各元件之间的连接,以及信号的定义,总是有错误,在细心的检查下,终于找出了错误和警告,排除困难后,程序编译就通过了,心里终于舒了一口气。
做硬件仿真实现的时候出现了问题,通过自己的探索与老师的指点,我检查出有一个按键不灵敏,通过修改引脚,功能得以实现。
总的来说,这次设计的数字钟还是比较成功的,我学到了很多知识,并且平时所学的知识有了实用的价值,达到了理论与实际相结合的目的,我对闹钟系统的原理及设计方法有了深刻的了解,对VHDL语言的结构有了深刻的理解,也对EDA这门课程产生了浓厚的兴趣。
九.参考文献
《EDA技术实用教程》第三版,科学出版社
《在系统编程技术》实验指导书,合肥学院电子系
十.附录:
源程序
1.闹钟模块
Alert.vhd
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:
STD_LOGIC_VECTOR(1DOWNTO0);
BEGIN
speaker:
PROCESS(clk)
BEGIN
--speak<=count1
(1);
IF(clk'eventandclk='1')THEN
IF(dain="0000000")THEN
speak<=count1
(1);
IF(count1>="10")THEN
count1<="00";--count1为三进制加法计数器
ELSE
count1<=count1+1;
ENDIF;
ENDIF;
ENDIF;
ENDPROCESSspeaker;
lamper:
PROCESS(clk)
BEGIN
IF(rising_edge(clk))THEN
IF(count<="10")THEN
IF(count="00")THEN
lamp<="001";--循环点亮三只灯
ELSIF(count="01")THEN
lamp<="010";
ELSIF(count="10")THEN
lamp<="100";
ENDIF;
count<=count+1;
ELSE
count<="00";
ENDIF;
ENDIF;
ENDPROCESSlamper;
ENDfun;
2.小时模块
Hour.vhd
LIBRARYIEEE;
useIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYhourIS
PORT(clk,reset:
INSTD_LOGIC;
daout:
outSTD_LOGIC_VECTOR(5DOWNTO0));
ENDENTITYhour;
ARCHITECTUREfunOFhourIS
SIGNALcount:
STD_LOGIC_VECTOR(5DOWNTO0);
BEGIN
daout<=count;
PROCESS(clk,reset)
BEGIN
IF(reset='0')THENcount<="000000";--若reset=0,则异步清零
ELSIF(clk'eventandclk='1')THEN--否则,若clk上升沿到
IF(count(3DOWNTO0)="1001")THEN--若个位计时恰好到"1001"即9
IF(count<16#23#)THEN--23进制
count<=count+7;--若到23D则
else
count<="000000";--复0
ENDIF;
ELSIF(count<16#23#)THEN--若未到23D,则count进1
count<=count+1;
ELSE--否则清零
count<="000000";
ENDIF;--ENDIF(count(3DOWNTO0)="1001")
ENDIF;--ENDIF(reset='0')
ENDPROCESS;
ENDfun;
3.分钟模块
Minute.vhd
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYminuteIS
PORT(clk,clk1,reset,sethour:
INSTD_LOGIC;
enhour:
OUTSTD_LOGIC;
daout:
OUTSTD_LOGIC_VECTOR(6DOWNTO0));
ENDENTITYminute;
ARCHITECTUREfunOFminuteIS
SIGNALcount:
STD_LOGIC_VECTOR(6DOWNTO0);
SIGNALenhour_1,enhour_2:
STD_LOGIC;--enmin_1为59分时的进位信号
BEGIN--enmin_2由clk调制后的手动调时脉冲信号串
daout<=count;
enhour_2<=(sethourandclk1);--sethour为手动调时控制信号,高电平有效
enhour<=(enhour_1orenhour_2);
PROCESS(clk,reset,sethour)
BEGIN
IF(reset='0')THEN--若reset为0,则异步清零
count<="0000000";
ELSIF(clk'eventandclk='1')THEN--否则,若clk上升沿到
IF(count(3DOWNTO0)="1001")THEN--若个位计时恰好到"1001"即9
IF(count<16#60#)THEN--又若count小于16#60#,即60
IF(count="1011001")THEN--又若已到59D
enhour_1<='1';--则置进位为1
count<="0000000";--count复0
ELSE
count<=count+7;--若count未到59D,则加7,即作"加6校正"
ENDIF;--使前面的16#60#的个位转变为8421BCD的容量
ELSE
count<="0000000";--count复0(有此句,则对无效状态电路可自启动)
ENDIF;--ENDIF(count<16#60#)
ELSIF(count<16#60#)THEN
count<=count+1;--若count<16#60#则count加1
enhour_1<='0'after100ns;--没有发生进位
ELSE
count<="0000000";--否则,若count不小于16#60#count复0
ENDIF;--ENDIF(count(3DOWNTO0)="1001")
ENDIF;--ENDIF(reset='0')
ENDprocess;
ENDfun;
4.秒模块
Second.vhd
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYsecondIS
PORT(clk,reset,setmin:
STD_LOGIC;
enmin:
OUTSTD_LOGIC;
daout:
OUTSTD_LOGIC_VECTOR(6DOWNTO0));
ENDENTITYsecond;
ARCHITECTUREfunOFsecondIS
SIGNALcount:
STD_LOGIC_VECTOR(6DOWNTO0);
SIGNALenmin_1,enmin_2:
STD_LOGIC;--enmin_1为59秒时的进位信号
BEGIN--enmin_2由clk调制后的手动调分脉冲信号串
daout<=count;
enmin_2<=(setminandclk);--setmin为手动调分控制信号,高电平有效
enmin<=(enmin_1orenmin_2);--enmin为向分进位信号
PROCESS(clk,reset,setmin)
BEGIN
IF(reset='0')THENcount<="0000000";--若reset为0,则异步清零
ELSIF(clk'eventandclk='1')then--否则,若clk上升沿到
IF(count(3downto0)="1001")then--若个位计时恰好到"1001"即9
IF(count<16#60#)then--又若count小于16#60#,即60H
IF(count="1011001")then--又若已到59D
enmin_1<='1';count<="0000000";--则置进位为1及count复0
ELSE--未到59D
count<=count+7;--则加7,而+7=+1+6,即作"加6校正"
ENDIF;
ELSE--若count不小于16#60#(即count等于或大于16#60#)
count<="0000000";--count复0
ENDIF;--ENDIF(count<16#60#)
ELSIF(count<16#60#)then--若个位计数未到"1001"则转此句再判
count<=count+1;--若count<16#60#则count加1
enmin_1<='0'after100ns;--没有发生进位
ELSE--否则,若count不小于16#60#
count<="0000000";--则count复0
ENDIF;--ENDIF(count(3DOWNTO0)="1001")
ENDIF;--ENDIF(reset='0')
ENDPROCESS;
ENDfun;