所用开发板:正点原子新起点V2
目录
功能介绍:
实现了一个带有小数位的正计时功能的计时器,按下reset键系统复位,key1开始计时,key2暂停计时,按下按键蜂鸣器会发出响声
系统总框图:
分频器模块:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.all;
ENTITY divider IS
PORT(
clk:IN std_logic;
rst_n:IN std_logic;
clk_div:OUT std_logic
);
END ENTITY;
ARCHITECTURE behav OF divider IS
signal count:integer range 1 to 25000000;
signal clk_out:std_logic;
BEGIN
PROCESS(clk)
BEGIN
IF (rst_n='0') THEN clk_out<='0';
ELSIF rising_edge(clk)
THEN count<=count+1;
if (count=2500000)
THEN clk_out<=not clk_out;
count<=1;
end if;
END IF;
clk_div<=clk_out;
END PROCESS;
END behav;
数码管显示模块:
library ieee;use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity seg is
port(
clk: in std_logic;
rst_n:in std_logic;
ids_data: in std_logic_vector (11 downto 0);
seg_duan: out std_logic_vector (7 downto 0);
seg_wei: out std_logic_vector (5 downto 0)
);
end seg;
architecture behav of seg is
constant num0:std_logic_vector(7 downto 0) := x"c0";
constant num1:std_logic_vector(7 downto 0) := x"f9";
constant num2:std_logic_vector(7 downto 0) := x"a4";
constant num3:std_logic_vector(7 downto 0):= x"b0";
constant num4:std_logic_vector(7 downto 0) := x"99";
constant num5:std_logic_vector(7 downto 0) := x"92";
constant num6:std_logic_vector(7 downto 0):= x"82";
constant num7:std_logic_vector(7 downto 0) := x"f8";
constant num8:std_logic_vector(7 downto 0) := x"80";
constant num9:std_logic_vector(7 downto 0) := x"90";
constant num00:std_logic_vector(7 downto 0) := x"40";
constant num11:std_logic_vector(7 downto 0) := x"79";
constant num22:std_logic_vector(7 downto 0) := x"24";
constant num33:std_logic_vector(7 downto 0) := x"30";
constant num44:std_logic_vector(7 downto 0) := x"19";
constant num55:std_logic_vector(7 downto 0) := x"12";
constant num66:std_logic_vector(7 downto 0) := x"02";
constant num77:std_logic_vector(7 downto 0) := x"78";
constant num88:std_logic_vector(7 downto 0) := x"00";
constant num99:std_logic_vector(7 downto 0) := x"10";
constant numa:std_logic_vector(7 downto 0) := x"88";
constant numb:std_logic_vector(7 downto 0) := x"83";
constant numc:std_logic_vector(7 downto 0):= x"c6";
constant numd:std_logic_vector(7 downto 0) := x"a1";
constant nume:std_logic_vector(7 downto 0) := x"86";
constant numf:std_logic_vector(7 downto 0) := x"8e";
constant we0:std_logic_vector(5 downto 0) := "111110";
constant we1:std_logic_vector(5 downto 0) := "111101";
constant we2:std_logic_vector(5 downto 0) := "111011";
constant we:std_logic_vector(5 downto 0) := "111111";
signal a:integer range 0 to 100 :=0;
signal b:integer range 0 to 100 :=0;
signal c:integer range 0 to 100 :=0;
begin
process(rst_n,clk,ids_data)
variable cnt_4 : std_logic_vector (9 downto 0);
variable seg_num : std_logic_vector (3 downto 0);
begin
if (rst_n = '0') then cnt_4:="0000000000";
elsif(rising_edge(clk)) then cnt_4:= cnt_4+1;
end if;
if (rst_n= '0') then seg_num:= "0000";
elsif(rising_edge(clk)) then
case (cnt_4 (9 downto 8)) is
when "00" => seg_num:=ids_data (3 downto 0);
when "01" => seg_num:=ids_data (7 downto 4);
when "10" =>seg_num:=ids_data (11 downto 8) ;
when others=>NULL;
end case;
end if;
if (rst_n='0') then seg_wei<= "000000";
elsif (rising_edge(clk)) then
if(cnt_4(7 downto 0) <="11100011")then
case cnt_4 (9 downto 8) is
when "00"=>
seg_wei<=we0;
when "01"=>
seg_wei<=we1;
when "10"=>
seg_wei<=we2;
when others=>
seg_wei<=we;
end case;
else seg_wei<=we;
end if;
end if;
if (rst_n='0') then seg_duan<= "00000000";
elsif (rising_edge(clk)) then
if(cnt_4(9 downto 8)="01")then
case seg_num is
when "0000"=>seg_duan<=num00;
when "0001"=>seg_duan<=num11;
when "0010"=>seg_duan<=num22;
when "0011"=>seg_duan<=num33;
when "0100"=>seg_duan<=num44;
when "0101"=>seg_duan<=num55;
when "0110"=>seg_duan<=num66;
when "0111"=>seg_duan<=num77;
when "1000"=>seg_duan<=num88;
when "1001"=>seg_duan<=num99;
when others=>NULL;
end case;
else
case seg_num is
when "0000"=>seg_duan<=num0;
when "0001"=>seg_duan<=num1;
when "0010"=>seg_duan<=num2;
when "0011"=>seg_duan<=num3;
when "0100"=>seg_duan<=num4;
when "0101"=>seg_duan<=num5;
when "0110"=>seg_duan<=num6;
when "0111"=>seg_duan<=num7;
when "1000"=>seg_duan<=num8;
when "1001"=>seg_duan<=num9;
when others=>NULL;
end case;
end if;
end if;
end process;
end behav;
计时器模块:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.All;
USE IEEE.std_logic_arith.ALL;
ENTITY demo1 IS
PORT(clk:IN std_logic;
clk_div:IN std_logic;
reset:IN std_logic; --复位按键
key1:IN std_logic; --开始按键
key2:IN std_logic; --停止按键
sound:OUT std_logic;
led_0:OUT std_logic;--等待状态指示灯
led_1:OUT std_logic;--开始计时状态
led_2:OUT std_logic;--暂停计时状态
num:out std_Logic_vector(11 downto 0) );--输出
END ENTITY;
ARCHITECTURE behav OF demo1 IS
TYPE state_type IS(s0,s1,s2);
SIGNAL present_state,next_state:state_type;
Signal waiting_time:integer range 0 to 999:=0 ; --抢答倒计时时间
signal o1,o2,o3 :std_logic_vector(3 downto 0); --用来组成输出的数字
SIGNAL q1,q2,q3:integer range 0 to 1200 :=0;
SIGNAL tmp:integer range 0 to 1200 :=0;
SIGNAL flag:std_logic_vector(1 DOWNTO 0):="00";
BEGIN
seq:PROCESS(clk_div,reset)
BEGIN
IF (reset='0')THEN
present_state<=s0;
ELSIF(rising_edge(clk_div))THEN
present_state<=next_state;
END IF;
END PROCESS;
ns:PROCESS(clk_div,present_state)
BEGIN
CASE present_state IS
WHEN s0=> --等待状态
IF(key1='0')THEN next_state<=s1;
ELSE next_state<=s0;
END IF;
WHEN s1=> --计时状态
IF(key2='0')THEN next_state<=s2;
ELSE next_state<=s1;
END IF;
WHEN s2=> --暂停状态
IF(key1='0')THEN next_state<=s1;
ELSE next_state<=s2;
END IF;
END CASE;
END PROCESS;
PROCESS(clk_div, present_state,reset)
BEGIN
IF rising_edge(clk_div) THEN
CASE present_state IS
WHEN s0=>
led_0<='1';
led_1<='0';
led_2<='0';
waiting_time<=0;
WHEN s1=>
led_0<='0';
led_1<='1';
led_2<='0';
waiting_time<=waiting_time+1;
WHEN s2=>
led_0<='0';
led_1<='0';
led_2<='1';
END CASE;
tmp<=waiting_time/10;
q2<=tmp rem 10;
q3<=waiting_time/100;
q1<=waiting_time rem 10;
o1<=conv_std_logic_vector(q1,4);
o2<=conv_std_logic_vector(q2,4);
o3<=conv_std_logic_vector(q3,4);
num<=o3&o2&o1;
END IF;
END PROCESS;
PROCESS(clk_div, key1, key2)
BEGIN
IF rising_edge(clk_div) THEN
IF (key1='0') or (key2='0')THEN
flag <= "10";
sound <= '1';
ELSIF reset='0' THEN sound<='0';flag<="00";
ELSIF flag="00" THEN
sound <= '0';
ELSE flag <= flag - '1';
END IF;
END IF;
END PROCESS;
END behav;
实验效果图:
待机状态:
计时状态:
暂停计时状态:
恢复计时状态: