1数字时钟设计一、题目分析1、功能介绍1)具有时、分、秒计数显示功能,以24小时循环计时。2)时钟计数显示时有LED灯的花样显示。3)具有调节小时、分钟及清零的功能。4)具有整点报时功能。2、总体方框图3、性能指标及功能设计1)时钟计数:完成时、分、秒的正确计时并且显示所计的数字;对秒、分——60进制计数,即从0到59循环计数,时钟——24进制计数,即从0到23循环计数,并且在数码管上显示数值。2)时间设置:手动调节分钟、小时,可以对所设计的时钟任意调时间,这样使数字钟真正具有使用功能。我们可以通过实验板上的键7和键4进行任意的调整,因为我们用的时钟信号均是1HZ的,所以每LED灯变化一次就来数字时钟控制单元使能端信号输出信号复位信号LED显示‘CLK信号2一个脉冲,即计数一次。3)清零功能:reset为复位键,低电平时实现清零功能,高电平时正常计数。可以根据我们自己任意时间的复位。4)蜂鸣器在整点时有报时信号产生,蜂鸣器报警。产生“滴答.滴答”的报警声音。5)LED灯在时钟显示时有花样显示信号产生。即根据进位情况,LED不停的闪烁,从而产生“花样”信号。二、选择方案1、方案选择方案一:根据总体方框图及各部分分配的功能可知,本系统可以由秒计数器、分钟计数器、小时计数器、整点报时、分的调整以及小时的调整和一个顶层文件构成。采用自顶向下的设计方法,子模块利用VHDL语言设计,顶层文件用原理图的设计方法。显示:小时采用24进制,而分钟均是采用6进制和10进制的组合。方案二:根据总体方框图及各部分分配的功能可知,本系统可以由秒计数器、分钟计数器、小时计数器、整点报时、分的调整以及小时的调整和一个顶层文件构成。采用自顶向下的设计方法,子模块利用VHDL语言设计,顶层文件用原理图的设计方法。显示:小时采用24进制,而分钟和秒均60进制。终上所述,考虑到试验时的简单性,故我选择了方案二。三、细化框图根据自顶向下的方法以及各功能模块的的功能实现上述设计方案应系统细化框图:3四、编写程序、仿真和分析1、秒计数器1)VHDL语言描述程序见附录2)秒计数器的仿真波形图3)波形分析利用60进制计数器完成00到59的循环计数功能,当秒计数至59时,再来一个时钟脉冲则产生进位输出,即enmin=1;reset作为复位信号低电平有效,数字时钟控制单元时调整分调整使能端信号CLK信号时显示分显示秒显示24进制60进制60进制LED显示整点报时花样显示4即高电平时正常循环计数,低电平清零。因为这种60进制的VHDL语言是很好写的,它并不复杂,再说我们必须要学会这些基本的硬件语言的描写。2、分钟计数器1)VHDL语言描述程序见附录2)分钟计数器的仿真波形图3)波形分析小时计数模块利用24进制计数器,通过分钟的进位信号的输入可实现从00到23的循环计数。3、小时计数器1)VHDL语言描述程序见附录2)小时计数器的仿真波形图3)波形分析小时计数模块利用24进制计数器,通过分钟的进位信号的输入可实现从00到23的循环计数。4、整点报时报警模块1)VHDL语言描述程序见附录2)整点报时模块仿真波形图51)波形分析由图知对于整点报时模块,当分钟计数至59时来一个时钟脉冲则产生一个进位信号,分钟计数到00,此时产生报警信号持续一分钟。当有时钟脉冲时lamp显示灯就闪烁轮续点亮。五、全系统联调1、数字时钟系统原理图2、数字时钟系统波形图仿真6六、附录(源程序)1、小时计数器VHDL语言源程序(底层文件)LIBRARYIEEE;useIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYhourISPORT(clk,reset:INSTD_LOGIC;daout:outSTD_LOGIC_VECTOR(5DOWNTO0));ENDENTITYhour;ARCHITECTUREfunOFhourISSIGNALcount:STD_LOGIC_VECTOR(5DOWNTO0);BEGINdaout=count;PROCESS(clk,reset)BEGINIF(reset='0')THENcount=000000;——若reset=0,则异步清零ELSIF(clk'eventandclk='1')THEN——否则,若clk上升沿到IF(count(3DOWNTO0)=1001)THEN——若个位计时恰好到“1001”即9IF(count16#23#)THEN——23进制count=count+7;——若到23D则elsecount=000000;——复0ENDIF;ELSIF(count16#23#)THEN——若未到23D,则count进1count=count+1;ELSE——否则清零count=000000;ENDIF;——ENDIF(count(3DOWNTO0)=“1001”)ENDIF;——ENDIF(reset=‘0’)ENDPROCESS;7ENDfun;2、分钟计数器VHDL语言源程序(底层文件)LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYminuteISPORT(clk,clk1,reset,sethour:INSTD_LOGIC;enhour:OUTSTD_LOGIC;daout:OUTSTD_LOGIC_VECTOR(6DOWNTO0));ENDENTITYminute;ARCHITECTUREfunOFminuteISSIGNALcount: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)BEGINIF(reset='0')THEN——若reset为0,则异步清零count=0000000;ELSIF(clk'eventandclk='1')THEN——否则,若clk上升沿到IF(count(3DOWNTO0)=1001)THEN——若个位计时恰好到“1001”即9IF(count16#60#)THEN——又若count小于16#60#,即60IF(count=1011001)THEN——又若已到59Denhour_1='1';——则置进位为1count=0000000;——count复0ELSEcount=count+7;——若count未到59D,则加7,即作“加6校正”ENDIF;——使前面的16#60#的个位转变为8421BCD的容量ELSEcount=0000000;——count复0(有此句,则对无效状态电路可自启动)ENDIF;——ENDIF(count16#60#)ELSIF(count16#60#)THENcount=count+1;——若count16#60#则count加1enhour_1='0'after100ns;——没有发生进位ELSEcount=0000000;——否则,若count不小于16#60#count复0ENDIF;——ENDIF(count(3DOWNTO0)=“1001”)ENDIF;——ENDIF(reset=‘0’)ENDprocess;ENDfun;83、秒钟计数器VHDL语言源程序(底层文件)LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYsecondISPORT(clk,reset,setmin:STD_LOGIC;enmin:OUTSTD_LOGIC;daout:OUTSTD_LOGIC_VECTOR(6DOWNTO0));ENDENTITYsecond;ARCHITECTUREfunOFsecondISSIGNALcount: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)BEGINIF(reset='0')THENcount=0000000;——若reset为0,则异步清零ELSIF(clk'eventandclk='1')then——否则,若clk上升沿到IF(count(3downto0)=1001)then——若个位计时恰好到“1001”即9IF(count16#60#)then——又若count小于16#60#,即60HIF(count=1011001)then——又若已到59Denmin_1='1';count=0000000;——则置进位为1及count复0ELSE——未到59Dcount=count+7;——则加7,而+7=+1+6,即作“加6校正”ENDIF;ELSE——若count不小于16#60#(即count等于或大于16#60#)count=0000000;——count复0ENDIF;——ENDIF(count16#60#)ELSIF(count16#60#)then——若个位计数未到“1001”则转此句再判count=count+1;——若count16#60#则count加1enmin_1='0'after100ns;——没有发生进位ELSE——否则,若count不小于16#60#count=0000000;——则count复0ENDIF;——ENDIF(count(3DOWNTO0)=“1001”)ENDIF;——ENDIF(reset=‘0’)ENDPROCESS;ENDfun;4、整点报时报警模块VHDL语言源程序(底层文件)LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;9ENTITYalertISPORT(clk:INSTD_LOGIC;dain:INSTD_LOGIC_VECTOR(6DOWNTO0);speak:OUTSTD_LOGIC;lamp:OUTSTD_LOGIC_VECTOR(2DOWNTO0));ENDalert;ARCHITECTUREfunOFalertISSIGNALcount:STD_LOGIC_VECTOR(1DOWNTO0);SIGNALcount1:STD_LOGIC_VECTOR(1DOWNTO0);BEGINspeaker:PROCESS(clk)BEGINspeak=count1(1);IF(clk'eventandclk='1')THENIF(dain=0000000)THENIF(count1=10)THENcount1=00;——count1为三进制加法计数器ELSEcount1=count1+1;ENDIF;ENDIF;ENDIF;ENDPROCESSspeaker;lamper:PROCESS(clk)BEGINIF(rising_edge(clk))THENIF(count=10)THENIF(count=00)THENlamp=001;——循环点亮三只灯ELSIF(count=01)THENlamp=010;ELSIF(count=1