library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; --库和程序包
--实体
entity sz is
port
(
clk ,enb,key,key1,key2,clr:in std_logic ; --输入端口的定义
sk: out integer range 0 to 8; --测试扫描信号的频率输出端口
Q:out std_logic_vector (7 downto 0);--段码的输出端口定义
s: out std_logic_vector (7 downto 0);--位码的输出端口定义
test:out std_logic);
end entity sz;
--结构体
architecture one of sz is
signal cnt_1k : integer range 0 to 50000 ; --定义产生1Khz信号计数值的信号
signal compete_1ms: std_logic;--完成1ms的标志
signal flag_fp,min_fp,hour_fp: std_logic;--为按键控制而定义一个标准逻辑型信号
signal flag_1s,flag_1k,sec_flag ,min_flag : std_logic :='0';--1s和1ms ,秒的进位,分的进--位标志位
signal smiao :integer range 0 to 8;--扫描信号
signal sec_cnt,min_cnt,num1,cnt_num :integer range 0 to 60;--秒的计数,分的计数
signal hour_cnt :integer range 0 to 24;--小时的计数
signal sc_L ,sc_h,min_L ,min_h,hour_L,hour_H :integer range 0 to 9;
--秒,分,时分离后的个位与十位
signal sc_L_q ,sc_h_q,min_L_q ,min_h_q,hour_L_q,hour_H_q :std_logic_vector( 7 downto 0);
--秒,分,时分离后的个位与十位的段码
begin
--分频 ,50mhz分成1khz的信号,并且它的占空比为50%
process (clk)
begin
if clk'event and clk ='1' then
cnt_1k<=cnt_1k+1;
if cnt_1k =50000 then --计数1khz值
cnt_1k<=0;
compete_1ms<='1';
else
if cnt_1k<25000 then
flag_1k<='0'; --cnt_1k小于2500时flag_1k置0
else
flag_1k<='1';--否则置高
end if;
compete_1ms<='0';
end if;
end if;
end process;
--产生1s的信号
process (compete_1ms)
variable cnt_1s: integer range 0 to 1000;
begin
if compete_1ms'event and compete_1ms='1' then --对1kz的信号进行计数
cnt_1s :=cnt_1s +1;
if cnt_1s =1000 then cnt_1s :=0;
else if cnt_1s<500 then flag_1s<='0'; --产生1s信号并且占空比为50%,
else flag_1s<='1';
end if;
end if;
end if;
test<=flag_1s;--测试秒的信号是否产生
end process;
--按键控制秒的信号
process (enb ,key,flag_1s)
begin
if enb='1' then
flag_fp<=flag_1s;--enb为高时送出的是1秒的信号
else
flag_fp<=not key; --否则送出的是按键的信号
end if;
end process;
--按键控制分的信号
process (enb ,key1,sec_flag)
begin
if enb='1' then
min_fp<=sec_flag;--enb为高时送出的是1分钟的信号
else
min_fp<=not key1; --否则送出的是按键的信号
end if;
-- test<=min_fp;--测试按键或者是秒的进位信号
end process;
process (enb ,key2,min_flag)
begin
if enb='1' then
hour_fp<=min_flag;--enb为高时送出的是1小时的信号
else
hour_fp<=not key2; --否则送出的是按键的信号
end if;
-- test<=hour_fp;--测试按键或者是分的进位信号
end process;
--秒的计数
process(flag_fp)
begin
if flag_fp'event and flag_fp='1' then
if sec_cnt=59 then sec_cnt<=0; sec_flag<='1';--秒是否到了1分钟,秒的标志位置为1
else sec_cnt<=sec_cnt+1 ; sec_flag<='0'; --否则秒加1,秒的标志位置为0
end if;
end if;
sc_L <=sec_cnt mod 10; --秒的个位
sc_h<= integer (sec_cnt/10);-- 秒的十位
end process;
--分的计数
process(min_fp)
begin
--if enb='1' then --只加按键的控制秒的数值变化
if min_fp'event and min_fp='1' then
if min_cnt=59 then min_cnt<=0; min_flag<='1';--分是否到了1小时,小时的标志位置为1
else min_cnt<=min_cnt+1; min_flag<='0';--否则分加1,小时的标志位置为0
end if;
end if;
-- end if;
min_L <= min_cnt mod 10;--分的个位
min_h<= integer(min_cnt/10);-- 分的十位
end process;
--小时的计数
process(hour_fp)
begin
-- if enb='1' then --只加按键的控制秒的数值变化
if hour_fp'event and hour_fp='1' then
if hour_cnt =23 then hour_cnt<=0;--小时是否到了24小时
else hour_cnt<=hour_cnt +1; --否则小时加1
end if;
end if;
hour_L <= hour_cnt mod 10;--分的个位
hour_h<= integer (hour_cnt/10);-- 分的十位
end process;
--产生动态扫描信号
process (flag_1k)
begin
if flag_1k'event and flag_1k='1' then --对1khz信号进行计数
if smiao=7 then smiao<=0;
else smiao<=smiao+1;
end if;
end if;
sk<=smiao;--测试扫描信号
end process;
--时钟的秒和分,小时的个位和十位的数码管的段码
PROCESS(sc_l,sc_h,min_l,min_h,hour_l,hour_h)
BEGIN
--秒低位段码
CASE(sc_l) IS
WHEN 0 => sc_l_q<="00000011"; --0的共阳数码管的段码
WHEN 1 => sc_l_q<="10011111"; --1的共阳数码管的段码
WHEN 2 => sc_l_q<="00100101"; --2的共阳数码管的段码
WHEN 3 => sc_l_q<="00001101"; --3的共阳数码管的段码
WHEN 4 => sc_l_q<="10011001"; --4的共阳数码管的段码
WHEN 5 => sc_l_q<="01001001"; --5的共阳数码管的段码
WHEN 6 => sc_l_q<="01000001"; --6的共阳数码管的段码
WHEN 7 => sc_l_q<="00011111"; --7的共阳数码管的段码
WHEN 8 => sc_l_q<="00000001"; --8的共阳数码管的段码
WHEN 9 => sc_l_q<="00001001"; --9的共阳数码管的段码
WHEN OTHERS => NULL;
END CASE;
--秒高位段码
CASE(sc_h) IS
WHEN 0 => sc_h_q<="00000011"; --0的共阳数码管的段码
WHEN 1 => sc_h_q<="10011111";--1的共阳数码管的段码
WHEN 2 => sc_h_q<="00100101"; --2的共阳数码管的段码
WHEN 3 => sc_h_q<="00001101";--3的共阳数码管的段码
WHEN 4 => sc_h_q<="10011001"; --4的共阳数码管的段码
WHEN 5 => sc_h_q<="01001001"; --5的共阳数码管的段码
WHEN OTHERS => NULL;
END CASE;
--分低位段码
CASE(min_l) IS
WHEN 0 => min_l_q<="00000011"; --0的共阳数码管的段码
WHEN 1 => min_l_q<="10011111"; --1的共阳数码管的段码
WHEN 2 => min_l_q<="00100101"; --2的共阳数码管的段码
WHEN 3 => min_l_q<="00001101"; --3的共阳数码管的段码
WHEN 4 => min_l_q<="10011001"; --4的共阳数码管的段码
WHEN 5 => min_l_q<="01001001"; --5的共阳数码管的段码
WHEN 6 => min_l_q<="01000001"; --6的共阳数码管的段码
WHEN 7 => min_l_q<="00011111"; --7的共阳数码管的段码
WHEN 8 => min_l_q<="00000001"; --8的共阳数码管的段码
WHEN 9 => min_l_q<="00001001"; --9的共阳数码管的段码
WHEN OTHERS => NULL;
END CASE;
--分高位段码
CASE(min_h) IS
WHEN 0 => min_h_q<="00000011"; --0的共阳数码管的段码
WHEN 1 => min_h_q<="10011111";--1的共阳数码管的段码
WHEN 2 => min_h_q<="00100101";--2的共阳数码管的段码
WHEN 3 => min_h_q<="00001101";--3的共阳数码管的段码
WHEN 4 => min_h_q<="10011001"; --4的共阳数码管的段码
WHEN 5 => min_h_q<="01001001"; --5的共阳数码管的段码
WHEN OTHERS => NULL;
END CASE;
--小时低位段码
CASE(hour_l) IS
WHEN 0 => hour_l_q<="00000011"; --0的共阳数码管的段码
WHEN 1 => hour_l_q<="10011111"; --1的共阳数码管的段码
WHEN 2 => hour_l_q<="00100101"; --2的共阳数码管的段码
WHEN 3 => hour_l_q<="00001101"; --3的共阳数码管的段码
WHEN 4 => hour_l_q<="10011001"; --4的共阳数码管的段码
WHEN 5 => hour_l_q<="01001001"; --5的共阳数码管的段码
WHEN 6 => hour_l_q<="01000001"; --6的共阳数码管的段码
WHEN 7 => hour_l_q<="00011111"; --7的共阳数码管的段码
WHEN 8 => hour_l_q<="00000001"; --8的共阳数码管的段码
WHEN 9 => hour_l_q<="00001001"; --9的共阳数码管的段码
WHEN OTHERS => NULL;
END CASE;
--小时的高位段码
CASE(hour_h) IS
WHEN 0 => hour_h_q<="00000011";--0的共阳数码管的段码
WHEN 1 => hour_h_q<="10011111"; --1的共阳数码管的段码
WHEN 2 => hour_h_q<="00100101";--2的共阳数码管的段码
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
--此进程为数码管动态显示
PROCESS(smiao)
BEGIN
CASE smiao IS
WHEN 0 => S<="01111111";Q<=sc_l_q; --第1位数码管显示秒的低位
WHEN 1 => S<="10111111";Q<=sc_h_q; --第2位数码管显示秒的高位
WHEN 2 => S<="11011111";Q<="11111101"; --第3位数码管显示“-”
WHEN 3 => S<="11101111";Q<=min_l_q; --第4位数码管显示分的低位
WHEN 4 => S<="11110111";Q<=min_h_q; --第5位数码管显示分的高位
WHEN 5 => S<="11111011";Q<="11111101"; --第6位数码管显示“-”
WHEN 6 => S<="11111101";Q<=hour_l_q; --第7位数码管显示小时的低位
WHEN 7 => S<="11111110";Q<=hour_h_q; --第8位数码管显示小时的高位
WHEN OTHERS => NULL;
END CASE;
end process;
end architecture one;