VHDL数字钟设计

VHDL数字钟设计
VHDL数字钟设计

题目:VHDL数字钟设计

1 设计要求

1:可以正常计时,能够准确实现由秒到分,由分到时的进位;

2:具有修改时间功能,可以对分位和时位置数;

3:具有整点报时功能,分位向时位进位时响铃;

4:具有闹钟功能,可以设置闹钟时间,当闹钟时间与计时时间一样时响铃;

2 设计分析及系统方案设计

1:正常计时,采用三个进程,分别控制秒、分、时,低位进程走满时产生进位信号控制高位。

2:修改时间,采用键5、6、7、8和键4配合,当键4按下方可保存修改值。四键中某一个按下时,每一个时钟沿,分别对应分加1、分减1、时加1、时减1。

3:整点报时,当秒个位为9、秒十位为5,、分个位为9、分十位为5时,再来一个时钟信号则时个位加1以上各位都清零,同时响铃,响铃持续一分钟。

4:闹钟,设置一个闹钟位,当闹钟位置1时调整时间是设置闹钟时间,当闹钟位置0时调整时间是设置正常计时的时间。设置好闹钟时间后,当正常计时的分个位、分十位、时个位、时十位均与设置的闹钟时间相等时响铃一分钟。

3系统以及模块硬件电路设计

下载时选择的开发系统模式以及管脚定义(注:采用模式“0”)

4 系统的VHDL设计

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

entity dc_1 is

port( clk,alarm,close,set:in std_logic;

--走时频率,闹钟频率,修改控制键,脑中设置控制键

choice: in std_logic_vector(3 downto 0);

--模式选择键组合

speak : out std_logic; --喇叭频率来源

s1,s2,m1,m2,h1,h2 :out std_logic_vector(3 downto 0));

--时间输出,依次是秒个位,秒十位,分个位,分十位,时个位,时十位end;

architecture a of dc_1 is

signal s_1,s_2,m_1,h_1,m_2,h_2 : std_logic_vector(3 downto 0);

--存正常走时的时间,不能存修改的时间

signal ss1,ss2,mm1,hh1,mm2,hh2 : std_logic_vector(3 downto 0);

--转存所有时间,赋值给输出

signal as1,as2,am1,ah1,am2,ah2 : std_logic_vector(3 downto 0):

--存放闹钟设定值

signal clksp,x,y: std_logic;

--整点报时低频信号,分走满的进位信号,时走满的进位信号signal n:std_logic_vector(1 downto 0); --控制分频产生clksp begin

process(alarm)

begin --get low frequency of strike on the hour if alarm'event and alarm='1' then

if n="10" then

n<="00";clksp<=not clksp;

else n<=n+1;

end if;

end if;

end process;

process(clk)

begin

if clk'event and clk='1' then --second if(s_1="0101" and s_2="1001") then

s_1<="0000";s_2<="0000";x<='1';

elsif (s_2="1001") then

s_2<="0000";s_1<=s_1+1;x<='0';

else s_2<=s_2+1;x<='0';

end if;

end if;

end process;

process(clk) --adjust the second to match minute and hour begin

if clk'event and clk='1' then ss1<=s_1;ss2<=s_2;

end if;

end process;

process(clk)

begin if close='1' then m_1<=mm1;m_2<=mm2; --minute elsif clk'event and clk='0' then

if s_2="1001" and s_1="0101" then

if m_2="1001" then

m_2<="0000";

if (m_1="0101") then

m_1<="0000";y<='1';

else m_1<=m_1+1;y<='0';

end if;

else m_2<=m_2+1;y<='0';

end if;

end if;

end if;

end process;

process(clk)

begin

if clk'event and clk='1' then ---change minute if set='0' then

if choice="0000" then

mm1<=m_1;mm2<=m_2;

elsif choice="0001" then

if (mm2="1001" and mm1="0101") then

mm2<="0000";mm1<="0000";

elsif mm2="1001" then

mm2<="0000";mm1<=mm1+1;

else mm2<=mm2+1;

end if;

elsif choice="0010" then

if (mm2="0000" and mm1="0000") then

mm2<="1001";mm1<="0101";

elsif (mm2="0000") then

mm2<="1001";mm1<=mm1-1;

else mm2<=mm2-1;

end if;

end if;

end if;

end if;

end process;

process(clk) --hour begin

if close='1' then h_1<=hh1;h_2<=hh2;

elsif clk'event and clk='0' then

if x='1' and y='1' then

if (h_1="0010" and h_2="0100") then

h_1<="0000" ;h_2<="0000";

elsif(h_2="1001") then

h_2<="0000";h_1<=h_1+1;

else h_2<=h_2+1;

end if;

end if;

end if;

end process;

process(clk)

begin

if clk'event and clk=’1’ then --change hour if set='0' then

if choice="0000" then

hh1<=h_1;hh2<=h_2;

elsif choice="0100" then

if (hh2="0100" and hh1="0010") then

hh2<="0000";hh1<="0000";

elsif hh2="1001" then

hh2<="0000";hh1<=hh1+1;

else hh2<=hh2+1;

end if;

elsif choice="1000" then

if (hh2="0000" and hh1="0000") then

hh2<="0100";hh1<="0010";

elsif (hh2="0000") then

hh2<="1001";hh1<=hh1-1;

else hh2<=hh2-1;

end if;

end if;

end if;

end if;

end process;

process(clk,set) --set alarm begin

if clk'event and clk='1' then

if set='1' then

if choice="0001" then --set second if (as2="1001" and as1="0101") then

as2<="0000";as1<="0000";

elsif as2="1001" then

as2<="0000";as1<=as1+1;

else as2<=as2+1;

end if;

elsif choice="0010" then --set min

if (am2="1001" and am1="0101") then

am2<="0000";am1<="0000";

elsif am2="1001" then

am2<="0000";am1<=am1+1;

else am2<=am2+1;

end if;

elsif choice="0100" then --set hour if (ah2="0100" and ah1="0010") then

ah2<="0000";ah1<="0000";

elsif ah2="1001" then

ah2<="0000";ah1<=ah1+1;

else ah2<=ah2+1;

end if;

end if;

end if;

end if;

end process;

process(clk)

begin --display if set='1' then

s1<=as1;s2<=as2;m1<=am1;m2<=am2;h1<=ah1;h2<=ah2;

else

s1<=s_1;s2<=s_2;m1<=mm1;m2<=mm2;h1<=hh1;h2<=hh2;

end if;

end process;

process(clk)

begin --alarm control and speaker control if set='0' then

if (mm1=am1 and mm2=am2 and hh1=ah1 and hh2=ah2) then

speak<=alarm;

elsif mm1="0101" and mm2="1001" and ss1="0101" then

if ss2="0010" or ss2="0100" or ss2="0110" or ss2="1000" then

speak<=clksp;

end if;

elsif mm1="0000" and mm2="0000" and ss1="0000" and ss2="0000" then

if hh1="0000" and hh2="0000" then

speak<='0';

else

speak<=alarm;

end if;

else speak<='0';

end if;

end if;

end process;

end;

5 结论以及结果说明

在windows系统下运行MAX+PLUSII10.2软件,编译仿真成功后,连接引脚,实验箱选择EPF10K10LC84-4。执行程序后,时钟从00:00:00开始计时并且扬声器发出响声,因为初始闹钟设置时间也默认为00:00:00,这时按下alarm键可进入闹钟时间设置状态,数码管显示的为闹钟时间,再按下mdm键设置闹钟的分位,设置完成后弹起mdm键,再按下mdh键设置闹钟的时位,设置完成后弹起mdh 键,这时再弹起alarm键,则闹钟设置完毕,数码管重新显示计时时间,因为闹钟时间与计时时间不再一样,所以扬声器不再发出声音。

假设以上设置的闹钟时间为,23:58:00,在alarm弹起的状态下,按下mdm,将分位设为57,然后弹起mdm,再按下mdh,将时位设为23,然后弹起mdh。这时正常计时的时间已变成23:57:xx,等秒位计数到59然后计数变为23::58:00,

这时扬声器开始发出响声,铃响一分钟,当时间为23:59:00时停止铃响。再计时一分钟,计时变为00:00:00时,扬声器发出短暂铃响,这是整点报时。

以上调试过程已经实现了设计要求的4个功能,既正常计时,设置时间,整点报时,闹钟。但该程序仍有不足之处,因为在设置时钟时间和闹钟时间时,其它位都暂停了计时,如果设置的时间很长将会影响数字钟的准确度。

图1 设置闹钟

图1是闹钟时间设置的仿真波形,将闹钟时间设置成了20:19:00

图2 闹钟铃响

图2是闹钟铃响的波形图,当时间为20:19:00时铃响一分钟

图3 整点报时

图3是整点报时的波形,当23:59:59的时候,全部清零,并且spk短暂置1

图4 调整时间

图4是设置时间的波形,mdm和mdh分别置1,快速将时间从06:04:53调成23:27:03

相关主题
相关文档
最新文档