VHDL编程--数字钟
一、数字钟要求:
1、能进行正常的时、分、秒计时功能,分别由6个数码管显示24h、60min、60s。
2、可以进行当前时间设置。
二、应用系统功能的详细说明
该数字钟使用的是二十四时计时制。计时时间范围从00:00:00到23:59:59。当时间及时到23:59:59时,钟面跳转到00:00:00重新下一轮计时。
该数字钟总共有三个按钮,分别是md1控制数字钟的开关,md2(1)控制数字钟的正常运行还是时间设置和md2(0)控制对时还是对分的设置。
md1:为0时,数字钟电源关闭;为1时,数字钟电源开启。
md2(1):为0时,数字钟正常运行;为1时,数字钟进入设置状态。
md2(0):为0时,数字钟对时进行设置;为1时,数字钟对分进行设置。
三、主要模块的算法描述
1、扫描显示模块scan6
由于试验箱上的8只显示数码管只有16个接脚,当显示四个以上时,每次只能显示一位,所以要显示六位要轮流输出,即扫描显示。人的视觉暂留大约为1/30s,所以每只数码管闪动频率为32Hz即可。那么8只数码管轮流显示一遍,
2、计时模块hourten,huoroen,minten,minone,secten,secone
计时模块共分为6个部分,分别是时、分、秒的十位和个位。由每位之间的逻辑关系以及md1和md2来控制正常计数、进位和对小时分钟的设置。
3、译码模块dec7s
把计时模块输出的时、分、秒各位的二进制数翻译成能在七段数码管上显示的七位二进制码,能够显示0~9各个数字。
四、程序的源代码清单
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity digital_clock is
port(clk:in std_logic; --扫描频率,>=256Hz clk1:in std_logic; --计时频率,1Hz
md1:in std_logic; --开关,0时有效
md2:in std_logic_vector(1 downto 0); --时间设置
dout:out std_logic_vector(6 downto 0); --译码显示
ms:out std_logic_vector(5 downto 0)); --扫描控制
end digital_clock;
architecture one of digital_clock is
signal sel:std_logic_vector(2 downto 0);
signal hou1,hou2,min1,min2,sec1,sec2:std_logic_vector(3 downto 0);
signal time:std_logic_vector(3 downto 0);
begin
---------------------------------------------scan6
scan6:process(clk1,hou1,hou2,min1,min2,sec1,sec2)
begin
if clk1'event and clk1='1' then
if sel="101" then
sel<="000";
else
sel<=sel+1;
end if;
end if;
case sel is
when "000"=>ms<="000001";
time<=hou1;
when "001"=>ms<="000010";
time<=hou2;
when "010"=>ms<="000100";
time<=min1;
when "011"=>ms<="001000";
time<=min2;
when "100"=>ms<="010000";
time<=sec1;
when "101"=>ms<="100000";
time<=sec2;
when others=>ms<="100000";
time1=sec2;
end case;
end process scan6;
---------------------------------------------hourten
hourten:process(clk,hou2,min1,min2,sec1,sec2,md1,md2)
begin
if clk'event and clk='1' then
if (hou1&hou2&min1&min2&sec1&sec2="001000110101100101011001") then hou1<="0000"; --当23:59:59时,时十位归0
elsif (hou1&hou2="00100011"and md1&md2="001") then
hou1<="0000"; --当设置小时,时位是23时,时十位归0
elsif ((hou2&min1&min2&sec1&sec2="10010101100101011001")
or(hou2="1001"and md1&md2="001")) then
hou1<=hou1+1; --当正常计时,时间是x9:59:59时,或设置小时,end if; --时位是x9时,时十位加1
end if;
end process hourten;
---------------------------------------------hourone
hourone:process(clk,min1,min2,sec1,sec2,md1,md2,hou1)
begin
if clk'event and clk='1' then
if (hou1&hou2&min1&min2&sec1&sec2="001000110101100101011001") then hou2<="0000"; --当23:59:59时,时个位归0
elsif (hou2&min1&min2&sec1&sec2="001000110101100101011001") then
hou2<="0000"; --当x9:59:59时,时个位归0
elsif ((hou2="1001"or hou1&hou2="00100011")and(md1&md2="001")) then
hou2<="0000"; --当设置小时,时位是x9或23时,时个位归0 elsif (min1&min2&sec1&sec2="0101100101011001)or(md1&md2="001")then hou2<=hou2+1; --当正常计时,时间是xx:59:59时,或设置小时,时个位加1 end if;
end if;
end process hourone;
---------------------------------------------minten
minten:process(clk,min2,sec1,sec2,md1,md2)
begin
if clk'event and clk='1' then
if (min1&min2&sec1&sec2="0101100101011001") then
min1<="0000"; --当xx:59:59时,分十位归0
elsif (min1&min2="01011001"and md1&md2="000")then
min1<="0000"; --当设置分钟,分位是59时,分十位归0
elsif (min2&sec1&sec2="100101011001")or --正常计时,时间是xx:x9:59时,或(min2="1001"and md1&md2="000") then --设置分钟,时间是x9,分十位加1
min1<=min1+1;
end if;
end if;
end process minten;
---------------------------------------------minone
minone:process(clk,sec1,sec2,md1,md2)
begin
if clk'event and clk='1' then
if (min2&sec1&sec2="100101011001") then
min2<="0000"; --当xx:x9:59时,分个位归0
elsif (min2="1001"and md1&md2="000") then
min2<="0000"; --当设置分钟,分位是x9时分个位归0
elsif (sec1&sec2="01011001")or(md1&md2="000") then
min2<=min2+1; --正常计时,时间是xx:xx:59时,或设置分钟,分个位加1 end if;
end if;
end process minone;
---------------------------------------------secten
secten:process(clk)
begin
if clk'event and clk='1' then
if (sec1&sec2="01011001") then --当时间是xx:xx:59时,秒十位归0
sec1<="0000";
elsif sec2="1001"then --当秒位是x9时,秒十位加1
sec1<=sec1+1;
end if;
end if;
end process secten;
--------------------------------------------secone
secone:process(clk)
begin
if clk'event and clk='1' then
if sec2="1001" then --当秒位是x9时,秒个位归0
sec2<="0000";
else sec2<=sec2+1; --否则加1
end if;
end if;
end process secone;
------------------------------------------dec7s
dec7s:process(time)
begin
case time is
when "0000"=>dout<="0111111";
when "0001"=>dout<="0000110";
when "0010"=>dout<="1011011";
when "0011"=>dout<="1001111";
when "0100"=>dout<="1100110";
when "0101"=>dout<="1101101";
when "0110"=>dout<="1111101";
when "0111"=>dout<="0000111";
when "1000"=>dout<="1111111";
when "1001"=>dout<="1101111";
when others=>dout<="0111111";
end case;
end process dec7s;
end one;