【数字钟】课程设计VHDL语言

【数字钟】课程设计VHDL语言
【数字钟】课程设计VHDL语言

一、设计要求

1.具有时,分,秒,计数显示功能,以24小时循环计时。

2.具有清零,调节小时、分钟功能。

3.具有整点报时功能。

二、实验目的

1.掌握多位计数器相连的设计方法。

2.掌握十进制,六进制,二十四进制计数器的设计方法。

3.继续巩固多位共阴级扫描显示数码管的驱动,及编码。

4.掌握扬声器的驱动。

5.掌握EPLD技术的层次化设计方法。

三、实验原理

1.时钟计数:

秒——60进制BCD码计数;

分——60进制BCDD码计数;

时——24进制BCDD码计数;

整个计数器有清零,调分,调时功能,在接近整数时间能提供报时信号。

2.具有驱动8位八段共阴扫描数码管的片选驱动信号输出和八段字形译码输出,编码和扫描部分可参照前面实验。

3.扬声器在整点时有报时驱动信号产生。

四、实验内容及步骤

1.根据电路持点,可在教师指导下用层次设计概念,将此设计任务分成若干模块,规定每一模块的功能和各模块之间的接口,让几个学生分做和调试其中之一,然后再将各模块合起来联试,以培养学生之间的合作精神,同时加深层次化设计概念。

2.了解软件的元件管理深层含义,以及模块元件之间的连接概念。了解如何融合不同目录下的统一设计。

模块说明:

各种进制的计数及时钟控制模块(10进制、6进制、24进制);

扫描分时显示,译码模块;

扬声器编码模块;

各模块都是由VHDL语言编写。

图26-1 数字钟各模块连接示意图

五、实验程序和电路图

(component是对要用的已经生成好的原件模块申明,port map是原件的输入输出端口映射,相当于各个元件之间的端口连线。)

【主程序】

LIBRARY ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.std_logic_arith.all;

LIBRARY work;

ENTITY clock_tp IS

PORT

(

clkdsp : IN STD_LOGIC;--系统时钟

reset : IN STD_LOGIC;--系统复位

clk : IN STD_LOGIC;--时钟频率

f : OUT STD_LOGIC;--数码管f

g : OUT STD_LOGIC;--数码管g

c : OUT STD_LOGIC;--数码管c

d : OUT STD_LOGIC;--数码管d

e : OUT STD_LOGIC;--数码管e

b : OUT STD_LOGIC;--数码管b

a : OUT STD_LOGIC;--数码管a

speaker : OUT STD_LOGIC;--蜂鸣器

dp : OUT STD_LOGIC;----数码管dp

M : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --模式选择位

selout : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) --数码管选择);

END clock_tp;

ARCHITECTURE bdf_type OF clock_tp IS

--分计数模块

COMPONENT minute

PORT(clk : IN STD_LOGIC;

reset : IN STD_LOGIC;

enhour : OUT STD_LOGIC;

daout : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)

);

END COMPONENT;

--数码管译码显示功能模块

COMPONENT deled

PORT(num : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

led : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)

);

END COMPONENT;

--秒计数模块

COMPONENT second

PORT(clk : IN STD_LOGIC;

reset : IN STD_LOGIC;

--setmin : IN STD_LOGIC;

enmin : OUT STD_LOGIC;

daout : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)

);

END COMPONENT;

--时计数模块

COMPONENT hour

PORT(clk : IN STD_LOGIC;

reset : IN STD_LOGIC;

daout : OUT STD_LOGIC_VECTOR(5 DOWNTO 0) );

END COMPONENT;

--报时功能模块

COMPONENT alert

PORT(clk : IN STD_LOGIC;

dain : IN STD_LOGIC_VECTOR(6 DOWNTO 0);

speak : OUT STD_LOGIC

);

END COMPONENT;

--扫描模块

COMPONENT seltime

PORT(clk1 : IN STD_LOGIC;

reset : IN STD_LOGIC;

hour : IN STD_LOGIC_VECTOR(5 DOWNTO 0);

min : IN STD_LOGIC_VECTOR(6 DOWNTO 0);

sec : IN STD_LOGIC_VECTOR(6 DOWNTO 0);

daout : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

sel : OUT STD_LOGIC_VECTOR(2 DOWNTO 0) );

END COMPONENT;

--数码管选择模块,38译码

COMPONENT decode3_8

PORT(SEL : IN STD_LOGIC_VECTOR(2 DOWNTO 0);

Q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) );

END COMPONENT;

--

COMPONENT div_clk

PORT(clk_in : IN STD_LOGIC;

div_out : OUT STD_LOGIC

);

END COMPONENT;

SIGNAL led : STD_LOGIC_VECTOR(0 TO 6);

SIGNAL M_line : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL lINE_0 : STD_LOGIC;

SIGNAL lINE_1 : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL lINE_2 : STD_LOGIC;

SIGNAL lINE_9 : STD_LOGIC_VECTOR(6 DOWNTO 0);

SIGNAL lINE_4 : STD_LOGIC;

SIGNAL lINE_5 : STD_LOGIC_VECTOR(5 DOWNTO 0); SIGNAL lINE_7 : STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL lINE_8 : STD_LOGIC_VECTOR(2 DOWNTO 0);

BEGIN

dp <= '0';

--分计数模块

b2v_2 : minute

PORT MAP(clk => lINE_0,

reset => reset,

enhour => lINE_2,

daout => lINE_9);

--数码管译码显示功能模块

b2v_23 : deled

PORT MAP(num => lINE_1,

led => led);

--秒计数模块

b2v_24 : second

PORT MAP(clk => clk,

reset => reset,

enmin => lINE_0,

daout => lINE_7);

--时计数模块

b2v_3 : hour

PORT MAP(clk => lINE_2,

reset => reset,

daout => lINE_5);

--报时功能模块

b2v_4 : alert

PORT MAP(clk => clk,

dain => lINE_9,

speak => speaker);

--扫描模块

b2v_5 : seltime

PORT MAP(clk1 => lINE_4,

reset => reset,

hour => lINE_5,

min => lINE_9,

sec => lINE_7,

daout => lINE_1,

sel => lINE_8);

--数码管选择模块,38译码

b2v_inst1 : decode3_8

PORT MAP(SEL => lINE_8,

Q => selout);

--

b2v_inst2 : div_clk

PORT MAP(clk_in => clkdsp,

div_out => lINE_4);

f <= led(5);

g <= led(6);

c <= led(2);

d <= led(3);

e <= led(4);

b <= led(1);

a <= led(0);

M <= M_line;

M_line(1) <= '1';

M_line(0) <= '0';

M_line(2) <= '0';

M_line(3) <= '0';

END bdf_type;

【子程序--秒计数】LIBRARY ieee;

use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;

ENTITY second IS

PORT(

clk : IN STD_LOGIC; --外部时钟频率

reset :IN STD_LOGIC; --复位

enmin : OUT STD_LOGIC; --向分进位

daout: out std_logic_vector (6 downto 0));--秒计数

END entity second;

ARCHITECTURE fun OF second IS

SIGNAL count: STD_LOGIC_VECTOR( 6 downto 0);

BEGIN

daout <= count;

process ( clk , reset )

begin

if (reset='0') then--复位

count <= "0000000";

elsif (clk 'event and clk='1') then --clk上升沿

if (count(3 downto 0)="1001") then --个位计数到9

if (count <16#60#) then --count小于60H

if (count="1011001") then--count等于59H

enmin<='1'; --就给进位置1

count<="0000000"; --count归零初始化

ELSE

count<=count+7; --跳过ah,bh,ch,dh,eh,fh。十六进制调整为十进制。

end if;

else

count<="0000000";--count归零初始化

end if;

elsif (count < 16#60#) then

count <= count+1;--count计数加1

enmin<='0' ;

else

count<="0000000";

end if;

end if;

end process;

END fun;

【子程序—分计数】

LIBRARY ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

ENTITY minute IS

PORT(

clk : IN STD_LOGIC;--second进位频率

reset : IN STD_LOGIC;--复位

enhour : OUT STD_LOGIC;--向时进位

daout: out std_logic_vector (6 downto 0));--分计数

END entity minute;

ARCHITECTURE fun OF minute IS

SIGNAL count: STD_LOGIC_VECTOR( 6 downto 0);

BEGIN

daout <= count;

process ( clk,reset)

begin

if (reset='0') then--复位

count <= "0000000";

elsif (clk' event and clk='1') then--clk上升沿

if (count(3 downto 0)="1001") then--个位计数到9

if (count <16#60#) then--count小于60H

if (count="1011001") then--count等于59H

enhour<='1'; --就给进位置1

count<="0000000"; --count归零初始化

ELSE

count<=count+7; --跳过ah,bh,ch,dh,eh,fh。十六进制调整为十进制。

end if;

else

count<="0000000";--count归零初始化

end if;

elsif(count <16#60#) then

count <= count + 1;--count计数加1

enhour<='0' ;

else

count<="0000000";

end if;

end if;

end process;

END fun;

【子程序—时计数】

LIBRARY ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

ENTITY hour IS

PORT(

clk: IN STD_LOGIC; --分进位频率

reset: IN STD_LOGIC;--复位

daout: out std_logic_vector (5 downto 0));--十计数

END entity hour;

ARCHITECTURE fun OF hour IS

SIGNAL count: STD_LOGIC_VECTOR( 5 downto 0);

BEGIN

daout <= count;

process ( clk,reset)

begin

if (reset='0') then--复位

count <= "000000";

elsif (clk' event and clk='1') then--clk上升沿

if (count(3 downto 0)="1001") then--个位计数到9

if (count <16#23#) then--count小于23H

count<=count + 7; --跳过ah,bh,ch,dh,eh,fh。十六进制调整为十进制。

else

count<="000000";--count归零初始化

end if;

elsif(count <16#23#) then --count小于23H

count <= count + 1;--count计数加1

else

count<="000000";--count归零初始化

end if;

end if;

end process;

END fun;

【子程序—数码管译码显示】

LIBRARY ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

ENTITY deled IS

PORT(num: IN std_logic_vector( 3 downto 0);

led: OUT std_logic_vector(6 downto 0)); END deled;

ARCHITECTURE fun OF deled IS

BEGIN

led <= "1111110" when num= "0000" else--0真值

"0110000" when num= "0001" else--1真值

"1101101" when num= "0010" else--2真值

"1111001" when num= "0011" else--3真值

"0110011" when num= "0100" else--4真值

"1011011" when num= "0101" else--5真值

"1011111" when num= "0110" else--6真值

"1110000" when num= "0111" else--7真值

"1111111" when num= "1000" else--8真值

"1111011" when num= "1001" else--9真值

"1110111" when num= "1010" else--A真值

"0011111" when num= "1011" else--b真值

"1001110" when num= "1100" else--C真值

"0111101" when num= "1101" else--d真值

"1001111" when num= "1110" else--E真值

"1000111" when num= "1111" ;--F真值END fun;

【子程序—报时功能】

LIBRARY ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

ENTITY alert IS

PORT(

clk : IN STD_LOGIC;

dain : IN STD_LOGIC_VECTOR(6 DOWNTO 0);

speak: OUT STD_LOGIC

);

END alert ;

ARCHITECTURE fun OF alert IS

signal count: std_logic_vector( 1 downto 0);

BEGIN

speaker:process (clk)

begin

speak <= count(1);

if (dain = "0000000") then--当分计时为0时蜂鸣器开始报数if (clk 'event and clk= '1') then--外部时钟频率为高电平就响

if (count="01") then --3秒循环,响一秒停两秒

count<="11";

else

count <= count - 1;

end if;

end if;

end if;

end process speaker;

END fun ;

【子程序—数码管选择(38译码)】

LIBRARY ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

ENTITY decode3_8 IS

PORT(SEL: IN std_logic_vector(2 downto 0);

Q : OUT std_logic_vector(7 downto 0)

);

END decode3_8;

ARCHITECTURE a OF decode3_8 IS

BEGIN

Q <= "11111110" when sel = 0 else--数码管0

"11111101" when sel = 1 else--数码管1

"11111011" when sel = 2 else--数码管2

"11110111" when sel = 3 else--数码管3

"11101111" when sel = 4 else--数码管4

"11011111" when sel = 5 else--数码管5

"11111111";

END a;

【子程序—扫描】

LIBRARY ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.std_logic_arith.all;

ENTITY seltime IS

PORT(

clk1: IN STD_LOGIC;--内部时钟频率

reset: IN STD_LOGIC;--复位

sec: IN STD_LOGIC_VECTOR(6 downto 0);--秒计数信号

min : IN STD_LOGIC_VECTOR(6 downto 0);--分计数信号

hour : in std_logic_vector (5 downto 0);--时计数信号

daout : OUT STD_LOGIC_vector (3 downto 0);--BCD数据输出

sel : out std_logic_vector ( 2 downto 0)--扫描信号

);

END seltime;

ARCHITECTURE fun OF seltime IS

SIGNAL count: STD_LOGIC_vector ( 2 downto 0);

BEGIN

sel <= count;

process ( clk1,reset)

begin

if (reset ='0') then

count <= "000";

elsif (clk1 'event and clk1='1') then

if ( count >= "101") then--数码管超过编号5

count <= "000";--count归零

else

count <= count + 1;--count加1.现在sel就在不断扫描0~5这6个数码管。

end if;

end if;

case count is--

when "000" => daout <= sec(3 downto 0);--数码管0,输出秒计数低四位

when "001" => daout(3) <= '0';--daout最高位(第3位)补0

daout(2 downto 0) <= sec (6 downto 4);--数码管1输出秒计数高三位when "010" => daout <= min (3 downto 0);--数码管2,输出分计数低四位

when "011" => daout(3) <= '0';--daout最高位(第3位)补0

daout(2 downto 0) <= min (6 downto 4);--数码管3,输出分计数高三位when "100" => daout <= hour (3 downto 0);--数码管4,输出时计数低四位

when others => daout(3 downto 2) <= "00";--daout高二位(第3位第2位)补00

daout(1 downto 0) <= hour(5 downto 4);--数码管5,输出时计数高二位end case;

end process;

end fun;

【子程序— div_clk 】

LIBRARY ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

ENTITY div_clk IS

PORT(clk_in : IN std_logic;--内部时钟频率

div_out: OUT std_logic);--频率输出

END div_clk;

ARCHITECTURE a OF div_clk IS

SIGNAL fre_N : integer range 0 to 100000;

SIGNAL clk_tmp: std_logic;

BEGIN

div_out <= clk_tmp;

process(clk_in)

begin

if falling_edge(clk_in) then

if fre_N >= 99999 then--大于等于99999

fre_N <= 0;--则fre_N归零

clk_tmp <= not clk_tmp;--clk_tmp求反else

fre_N <= fre_N + 1;--fre_N加1

end if;

end if;

end process;

END a;

【电路图】

六、实验连线

◎输入接口:

1.代表清零,调时,调分信号RESET,SETHOUR,SETMIN的管脚分别已经连接按键开关。

2.代表计数时钟信号CLK和扫描时钟信号CKDSP的管脚分别已经同1HZ时钟源和32HZ (或更高)时钟源相连。

3.Reset键为低电平复位,已经接上。

◎输出接口:

1.代表扫描显示的驱动信号管脚SCAN2,SCAN1,SCAN0已经接到实验箱上的SCAN0~SCAN2,A…G接八位数码管显示模块的A~G。

2.代表花样LED灯显示的信号管脚LAMP0…LAMP2已经同3个LED灯相连。代表到时LED 灯闪烁提示的ENHOUR接LED灯。

SETHOUR、SETMIN分别对应CPU板上的PB0、PB1(有些CPU板对应的标识是SW1、

SW2)

RESET对应CPU板上的RESET。CLKDSP对应CPU板上的50MHz固定晶振输入。LAMP对应IO9-IO11。CLK,对应IO3。

功能选择位M[3..0]状态为0010,左端8个数码管,低8位为7位段加小数点选取位,高8位为8个数码管com端选取,即如果要选取数码管0,则发送总线值为:1111 1110 1111 1111,如要选取数码管1,则发送总线值为:1111 1101 1111 1111,此时所选数码管7段和

DP位将全部亮。

底板上ADJ_CLK为4位拨码开关SW17--SW20来控制输出40M分频后的可调时钟

具体对应如下:

SW20 SW19 SW18 SW17 ADJ_CLK

1 1 1 1 1Hz

0 1 1 1 5Hz

1 0 1 1 10Hz

0 0 1 1 25Hz

1 1 0 1 50Hz

0 1 0 1 500Hz

1 0 0 1 1KHz

0 0 0 1 2.5KHz

1 1 1 0 10KHz

0 1 1 0 20KHz

1 0 1 0 50KHz

0 0 1 0 200KHz

1 1 0 0 500KHz

0 1 0 0 2MHz

1 0 0 0 5MHz

0 0 0 0 20MHz

接线:用导线连接IO3与ADJ_CLK,调整SW17-SW20,使输出频率为1Hz;

IO5接到蜂鸣器的BUZZER控制端口。

按下PB0、PB1(有些CPU板对应的标识是SW1、SW2)可以调整时钟,分钟。

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