折腾了一周,终于把数码管搞通了。
啥也不说了,先上张效果图。
本来是按时间格式写的,左边4为数码管显示2013,右边显示分钟.秒。但是精确定时没写,日历也还没研究,所以只是随便显示的一个计数器。左边2013,右边为递增的计数器:右边1、2位数码管增加到60,则像右边3、4为数码管进1。
代码采用VHDL写的,希望大家指点:所有代码没加注释,也算让要学习的学习一下,有不明白的欢迎留言探讨。
library ieee;
use ieee.std_logic_1164.all;
entity Seg_Increasing is
port(
segment:buffer bit_vector(0 to 7);
seg_select:out bit_vector(0 to 7);
clk:in std_logic
);
end Seg_Increasing;
architecture segment_show_number of Seg_Increasing is
signal sel : integer range 0 to 8;
signal data1 : integer range 0 to 10;
signal data2 : integer range 0 to 6;
signal data3 : integer range 0 to 10;
signal data4 : integer range 0 to 6;
--signal data5 : integer range 0 to 10;
--signal data6 : integer range 0 to 10;
--signal data7 : integer range 0 to 10;
--signal data8 : integer range 0 to 10;
procedure show_number(n :in integer; withdot: in bit)is
begin
case n is
when 1 =>
if withdot='1' then segment <= "10011111" and "11111110"; --1
else segment <= "10011111";
end if;
when 2 =>
if withdot='1' then segment <= "00100101" and "11111110"; --2
else segment <= "00100101";
end if;
when 3 =>
if withdot='1' then segment <= "00001101" and "11111110"; --3
else segment <= "00001101";
end if;
when 4 =>
if withdot='1' then segment <= "10011001" and "11111110"; --4
else segment <= "10011001";
end if;
when 5 =>
if withdot='1' then segment <= "01001001" and "11111110"; --5
else segment <= "01001001";
end if;
when 6 =>
if withdot='1' then segment <= "01000001" and "11111110"; --6
else segment <= "01000001";
end if;
when 7 =>
if withdot='1' then segment <= "00011111" and "11111110"; --7
else segment <= "00011111";
end if;
when 8 =>
if withdot='1' then segment <= "00000001" and "11111110"; --8
else segment <= "00000001";
end if;
when 9 =>
if withdot='1' then segment <= "00001001" and "11111110"; --9
else segment <= "00001001";
end if;
when 0 =>
if withdot='1' then segment <= "00000011" and "11111110"; --0
else segment <= "00000011";
end if;
when others=>segment <= "11111111";
end case;
end show_number;
begin
process(Clk)
constant N:integer :=8000;
variable count:integer range 0 to N :=0;
begin
if(rising_edge(Clk)) then
count := count + 1;
if count>=N then
if sel>8 then
sel <= 1;
else
sel <= sel + 1;
end if;
count := 0;
end if;
end if;
end process;
process(Clk)
constant N:integer :=3000;
variable count1:integer range 0 to N :=0;
variable count2:integer range 0 to N :=0;
begin
if(rising_edge(Clk)) then
count1 := count1 + 1;
if count1>=N then
count1 := 0;
count2 := count2+1;
if count2 >= N then
count2 := 0;
if data1>=9 then
data1 <= 0;
if(data2>=5) then
data2 <= 0;
if data3 >= 9 then
data3 <= 0;
if data4>=5 then
data4 <= 0;
else
data4 <= data4+1;
end if;
else
data3 <= data3+1;
end if;
else
data2 <= data2+1;
end if;
else
data1 <= data1 + 1;
end if;
end if;
end if;
end if;
end process;
process(sel)
begin
case (sel) is
when 1 => show_number(2,'0');seg_select <= "11111110";
when 2 => show_number(0,'0');seg_select <= "11111101";
when 3 => show_number(1,'0');seg_select <= "11111011";
when 4 => show_number(3,'1');seg_select <= "11110111";
when 5 => show_number(data4,'0');seg_select <= "11101111";
when 6 => show_number(data3,'1');seg_select <= "11011111";
when 7 => show_number(data2,'0');seg_select <= "10111111";
when 8 => show_number(data1,'0');seg_select <= "01111111";
WHEN OTHERS => seg_select <= "11111111";
end case;
end process;
end architecture;