基于CPLD的VHDL时钟设计

发布时间 : 星期五 文章基于CPLD的VHDL时钟设计更新完毕开始阅读

摘要:

数字钟学习的目的是掌握各类计数器及它们相连的设计方法;掌握多个数码管显示的原理与方法;掌握模块化设计方式;掌握用VHDL语言的设计思想以及整个数字系统的设计。此数字钟具有时,分,秒计数显示功能,以24小时为计数循环;能实现清零,调时,调分以及整点报时等功能。本设计是一个显示时(2位)分(2位)秒(2位)共六个数字的多功能电子钟。信号发生器输出的40Mhz作为系统频率(时钟),因此将其分频得1Hz的秒钟信号,秒计满60即得1分钟,分满60即得1小时信号,小时满24即得一天。

关键词:数字钟,计数器,数码管,模块化设计, VHDL。

一、设计分析

1.1 设计要求

1)具有时、分、秒计数显示功能,以24小时循环计时。 2)时钟计数显示时有LED灯的花样显示。 3)具有调节小时、分钟及清零的功能。 4)具有整点报时功能。

1.2 性能指标及功能设计

1)时钟计数:完成时、分、秒的正确计时并且显示所计的数字;对秒、分 60进制计数,即从0到59循环计数,时钟——24进制计数,即从0到23循环计数,并且在数码管上显示数值。

2)时间设置:手动调节分钟、小时,可以对所设计的时钟任意调时间,这样使数字钟真正具有使用功能。我们可以通过实验板上的键7和键4进行任意的调整,因为我们用的时钟信号均是1HZ的,所以每LED灯变化一次就来一个脉冲,即计数一次。

3)清零功能:reset为复位键,低电平时实现清零功能,高电平时正常计数。可以根据我们自己任意时间的复位。

4)蜂鸣器在整点时有报时信号产生,蜂鸣器报警。产生“滴答.滴答”的报警声音。

5)LED灯在时钟显示时有花样显示信号产生。即根据进位情况,LED不停的闪烁,从而产生“花样”信号。

1.3 系统方框图

时调整分调整花样显示二、设计方案

本设计采用自顶向下的设计方法和模块化设计方式,它由秒计数模块,分计数模块,小时计数模块,报警模块,秒分时设置模块和译码模块,程序包,entity模块(顶层模块)八部分组成。

优点:设计简单方便,层次清晰,工程的建立方便,无需单独设计各个组件模块产生原理图文件后再进行电路连接设计。 三、设计原理和过程 3.1 硬件设计

本设计使用VHDL硬件开发板,可编程逻辑器件EMP1270T144C5系列。设计过程中用到的外围电路的设计如下: 3.1.1 电源部分

3.1.2 可编程器件EMP1270T144C5 3.1.3 CPLD –JTAG接口 3.1.4 晶振和蜂鸣器 3.1.4 LED数码管显示

3.1.5 DIP开关与按键输入(具体电路见附录)

3.2 软件设计

3.2..1 程序包my_pkg的设计说明

为了简化程序设计增加可读性,系统采用模块化的设计方法,重复使用的组件以元件(component)的形式存在,以便相关块的调用。主程序内用不同的功能模块构成一完整的结构。下面列出my_pkg组件包的代码。

------------------------------自定义的包集合(用到的几个模块元件声明)------------------------------

控制单元 CLK信号 使能端信号 数字时钟时显示 分显示 秒显示 24进制 60进制 60进制 LED显示 整点报时

library ieee;

use ieee.std_logic_1164.all; package my_pkg is

component div40M---------------------------------------------------------------------元器件1 Port( clk: in std_logic;

f1hz : out std_logic); end component;

component count60---------------------------------------------------------------------元器件2 Port(clr,clk:in std_logic;

one :buffer std_logic_vector(3 downto 0); ten :buffer std_logic_vector(3 downto 0); full:out std_logic;

dout:buffer std_logic_vector(7 downto 0)); end component;

component count24------------------------------------------------------------------- -元器件3 Port(clr,clk:in std_logic;

one :buffer std_logic_vector(3 downto 0); ten :buffer std_logic_vector(3 downto 0); full:out std_logic); end component;

component scan6-----------------------------------------------------------------------元器件4 port (clr,clk : in STD_LOGIC;

h_ten,h_one,m_ten,m_one,s_ten,s_one: in STD_LOGIC_vector(3 downto 0); cs: out STD_LOGIC_vector(5 downto 0);

mux_out: out STD_LOGIC_vector(3 downto 0)); end component;

component bin2led---------------------------------------------------------------------元器件5 port (bin : in std_logic_vector (3 downto 0); led : out std_logic_vector (7 downto 0) ); end component;

component sh1k -------------------------------------------------------------------------元器件6 Port( clk: in std_logic;--from system clock(40MHz) f1hz : out std_logic);-- 1Hz output signal end component;

component alarm_set------------------------------------------------------------------------元器件7 Port(rst,hz1: in std_logic;--system clock 1Hz

alarm,ok: in std_logic;--keep pushing to declare alarm set sec_tune: in std_logic;

sec_one,sec_ten:out std_logic_vector(3 downto 0)); end component; end my_pkg;

3.2.2 count60组件

由此提供分(秒)计数值,当分计数器计数到59再来一个脉冲信号秒计数器清零从新开始计数,而进位则作为小时计数器的计数脉冲,使小时计数器计数加1,同时分计数器在分设置时钟信号的响应下设置分计数器的数值。在count60组件中,个位(one)和十位(ten)分别计数,都设为二进制四位矢量形式,当个位从0计到9时,在下一个clk上升沿来临后,十位进1,个位变0,十位从0到5计数,在十位为5,个位9的时候,下一个上升沿来临后,十位个位都变0,进位full加1。因此在程序设计中需要两个进程process来分别完成计数,秒计数以1Hz的输入为触发信号,分计数以秒的full信号为触发信号。具体的count60的组件代码如下:

-----------------------------------------60进制计数模块------------------------------------ Library ieee;

Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all; Entity count60 is

Port(clr,clk:in std_logic;

one :buffer std_logic_vector(3 downto 0); ten :buffer std_logic_vector(3 downto 0); full:out std_logic;

dout:buffer std_logic_vector(7 downto 0)); end count60;

architecture behav of count60 is begin process(clr,clk) begin

if(clr='0')then

one<=\ elsif(rising_edge(clk))then if(one=\ one<=\ else

one<=one+1; end if; end if; end process; process(clr,clk) begin

if(clr='0')then

ten<=\ elsif(rising_edge(clk))then if(one=\ if(ten=\ ten<=\

联系合同范文客服:xxxxx#qq.com(#替换为@)