基于VHDL的电子计时器的设计方法详解

描述

本文为大家介绍电子计时器的VHDL设计方法。

设计要求

设计一个电子计时器,给定时钟信号为512HZ,要求系统达到以下功能:

(1)用6个数码管分别显示时、分、秒,计时范围为00:00:00~23:59:59。

(2)计时精度是1s。

(3)具有启/ 停开关, 复位开关。

VHDL代码

总体方框图

内部各功能模块

本系统由六十进制计数器模块、二十四进制计数器模块、分频模块执行计时功能, 输入信号是512Hz,通过分频后为1Hz,时钟信号是1Hz作为计时器的秒输入,秒为60进制计数器,分也为60进制计数器,小时采用二十四进制计数器, 各级进位作为高位的使能控制。

六十进制计数器模块

设计一个八位的六十进制计数器模块,输入信号为en、reset、clk,分别为使能、复位和时钟信号,输出信号为qa[3„0]、qb[3„0]、rco,分别为低4位输出、高4位输出和进位位。

VHDL代码

六十进制计数器

波形分析

VHDL代码

秒计数器的仿真波形图

利用60进制计数器完成00到59的循环计数功能,当秒计数至59时,再来一个时钟脉冲则产生进位输出,即enmin=1;reset作为复位信号低电平有效,即高电平时正常循环计数,低电平清零。因为这种60进制的VHDL语言是很好写的,它并不复杂,再说我们必须要学会这些基本的硬件语言的描写。

VHDL代码

分钟计数器的仿真波形图

VHDL源程序

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.ALL;

ENTITY count60 IS

PORT( en,Reset,clk: in STD_LOGIC;

qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);

qb: out STD_LOGIC_VECTOR(3 DOWNTO 0);

rco: OUT STD_LOGIC); END count60;

ARCHITECTURE a OF count60 IS

BEGIN

process(clk)

variable tma: STD_LOGIC_VECTOR(3 DOWNTO 0);

variable tmb: STD_LOGIC_VECTOR(3 DOWNTO 0); begin

If Reset =‘0’then tma:=“0000”;

tmb:=“0000”;

elsif clk‘event and clk=’1‘ then

if en=’1‘ then

rco<=tmb(2)and tmb(0)and tma(3)and tma(0);

if tma=“1001” then

tma:=“0000”;

if tmb=“0101” then

tmb:=“0000”;

else tmb:=tmb+1;

end if;

else tma:=tma+1;

end if;

end if;

end if;

qa<=tma;qb<=tmb; end process; END a;

二十四进制计数器模块

设计一个八位的二十四进制计数器模块,输入信号为en、reset、clk,分别为使能、复位和时钟信号,输出信号为qa[3„0]、qb[3„0],分别为低4位输出、高4位输出。

VHDL代码

二十四进制计数器示意图

波形分析

VHDL代码

小时计数器的仿真波形图

VHDL源程序

小时计数模块利用24进制计数器,通过分钟的进位信号的输入可实现从00到23的循环计数。

该模块部分VHDL 源程序如下:

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.ALL;

ENTITY count24 IS

PORT( en,Reset,clk: in STD_LOGIC;

qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);

qb: out STD_LOGIC_VECTOR(3 DOWNTO 0));

END count24;

ARCHITECTURE a1 OF count24 IS

BEGIN

process(clk)

variable tma: STD_LOGIC_VECTOR(3 DOWNTO 0);

variable tmb: STD_LOGIC_VECTOR(3 DOWNTO 0);

begin

If Reset = ‘0’then tma:=“0000”;

tmb:=“0000”; else

if clk‘event and clk=’1‘ then

if en=’1‘ then

if tma=“1001” then

tma:=“0000”;

tmb:=tmb+1;

elsif tmb=“0010” and tma=“0011” then

tma:=“0000”;

tmb:=“0000”;

else tma:=tma+1;

end if;

end if;

end if;

end if;

qa<=tma;

qb<=tmb;

end process;

END a1;

分频器模块

设计一个分频器,要求将输入512HZ的时钟信号分频为1HZ的时钟信号作为计时器的秒输入。输入信号为clk和rst,分别为时钟信号和复位信号,输出信号为clk_out,为分频器1HZ的时钟信号输出。

VHDL代码

分频器示意图

VHDL 源程序

该模块部分VHDL 源程序如下:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY fenpinqi IS

PORT (CLK,RST:in std_logic;

CLK_OUT:out std_logic);

END fenpinqi;

ARCHITECTURE behav OF fenpinqi IS

signal clk_data:std_logic;

SIGNAL CNT6 :

INTEGER := 0;

BEGIN

PROCESS(CLK)

BEGIN

IF RST = ‘0’ THEN CNT6<=0

ELSIF CLK‘EVENT AND CLK=’1‘ THEN

IF CNT6=255 THEN

clk_data<=NOT clk_data;

CNT6<=0;

ELSE CNT6<=CNT6+1;

END IF;

END IF;

CLK_OUT<=clk_data;

END PROCESS;

END behav;

LED显示模块

LED有着显示亮度高,响应速度快的特点,最常用的是七段式LED显示器,又称数码管。七段LED显示器内部由七个条形发光二极管和一个小圆点发光二极管组成,根据各管的亮暗组合成字符。

LED数码管的g~a七个发光二极管因加正电压而发亮,因加零电压而不能发亮,不同亮暗的组合就能形成不同的字形,这种组合称之为字形码(段码),如显示”0”,字形码为3fh。

VHDL代码

LED数码管结构图

数码管的接口有静态接口和动态接口。动态接口采用各数码管循环轮流显示的方法,当循环显示频率较高时,利用人眼的暂留特性,看不出闪烁显示现象,这种显示需要一个接口完成字形码的输出(字形选择),另一接口完成各数码管的轮流点亮(数位选择)。

将二十四进制计数器和2个六十进制计数器的输出作为LED显示模块的输入,在时钟信号的控制下通过此模块完成6个LED数码管的显示,输出信号为WEI[2…0]和LED[6…0],分别为位选信号和段码输出。

VHDL代码

LED显示示意图

VHDL 源程序

该模块部分VHDL 源程序如下:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY clock1 IS

PORT(CLK: IN STD_LOGIC;

S1, S2, S3, S4, S5, S6: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

WEI: OUT STD_LOGIC_VECTOR(2 DOWNTO 0);

LED: OUT STD_LOGIC_VECTOR(6 DOWNTO 0));

END ENTITY;

ARCHITECTURE behave OF clock1 IS

SIGNAL CNT6 : INTEGER RANGE 0 TO 5 := 0;

SIGNAL SHUJU: STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

PRO1:PROCESS(CLK)

BEGIN

IF CLK‘EVENT AND CLK = ’1‘ THEN

CNT6 <= CNT6 + 1;

CASE CNT6 IS

WHEN 0 => WEI <= “000”; SHUJU <= S1;

WHEN 1 => WEI <= “001”; SHUJU <= S2;

WHEN 2 => WEI <= “010”; SHUJU <= S3;

WHEN 3 => WEI <= “011”; SHUJU <= S4;

WHEN 4 => WEI <= “100”; SHUJU <= S5;

WHEN 5 => WEI <= “101”; SHUJU <= S6;

CNT6<=0;

WHEN OTHERS => NULL;

END CASE;

END IF;

END PROCESS;

PRO2: PROCESS(SHUJU)

BEGIN

CASE SHUJU IS

WHEN “0000” => LED<= “1111110”

WHEN “0001” => LED<= “0110000”

WHEN “0010” => LED<= “1101101”

WHEN “0011” => LED<= “1111001”

WHEN “0100” => LED<= “0110011”

WHEN “0101” => LED<= “1011011”

WHEN “0110” => LED<= “1011111”

WHEN “0111” => LED<= “1110000”

WHEN “1000” => LED<= “1111111”

WHEN “1001” => LED<= “1111011”

WHEN others=> LED<= “0000000”

END CASE;

END PROCESS;

END

顶层系统联调

通过上面的分频器,两个60进制的计数器,一个12/24进制的计数器,6选1扫描器,7段数码显示器,设计如图所示的顶层。规定每一模块的功能和各模块之间的接口。同时整个计数器有清零。 设计思想,利用脉冲时钟产生一个1Hz的信号来实现一秒钟的控制,要产生1Hz的信号就要用到分频器,实验中用512分频器把512Hz的信号变成1Hz。然后信号进入控制秒的计数器,当第60个脉冲时钟到来时,产生一个进位信号, 送到控制分的计数器,同理,当第60个脉冲时钟到来时,产生一个进位信号,送到控制小时的计数器。当小时计数器计数到12/24时,完成一个周期,跳转到零。输出是由动态扫描器来完成的。扫描器时钟取至前面分频未结束时的一个512Hz的信号。这样就能够在7段数码显示管上,以512Hz的频率扫描显示出时钟的数字变化。

通过元件例化将各个模块连接起来,组成一个整体。

元件例化就是将预先设计好的设计实体定义为一个元件,然后利用特定的语句将此元件与当前的设计实体中的指定端口相连接,从而为当前设计实体引入一个新的低一级的设计层次。所定义的例化元件相当于一个要插在这个电路系统板上的芯片,而当前设计实体中指定的端口则相当于这块电路板上准备接受此芯片的一个插座。

VHDL 源程序

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.std_logic_signed.all;

use ieee.std_logic_arith.all;

entity dzjsq is

port(en,clk,reset:in std_logic;

wei:out std_logic_vector(2 downto 0);

led:out std_logic_vector(7 downto 0));

end entity dzjsq;

architecture abc of dzjsq is

component count60

PORT( en,Reset,clk: in STD_LOGIC;

qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);

qb: out STD_LOGIC_VECTOR(3 DOWNTO 0);

rco: OUT STD_LOGIC);

end component;

component count24

PORT( en,Reset,clk: in STD_LOGIC;

qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);

qb: out STD_LOGIC_VECTOR(3 DOWNTO 0));

end component; component fenpinqi

PORT (CLK,RST:in std_logic; CLK_OUT:out std_logic);

end component; component clock1

PORT(CLK: IN STD_LOGIC;

S1, S2, S3, S4, S5, S6: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

WEI: OUT STD_LOGIC_VECTOR(2 DOWNTO 0);

LED: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));

end component;

signal a1,a2,a3,a4,a5,a6:std_logic_vector(3 downto 0);

signal b1,b2,b3: std_logic; begin

u1: fenpinqi port map(clk,reset,b1);

u2:count60 port map(en,reset,b1,a1,a2,b2);

u3:count60 port map(en,reset,b2,a3,a4,b3);

u4:count24 port map(en,reset,b3,a5,a6);

u5:clock1 port map(clk,a1,a2,a3,a4,a5,a6,wei,led);

end architecture abc;

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.ALL;

ENTITY count60 IS

PORT( en,Reset,clk: in STD_LOGIC;

qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);

qb: out STD_LOGIC_VECTOR(3 DOWNTO 0);

rco: OUT STD_LOGIC);

END count60;

ARCHITECTURE a OF count60 IS

BEGIN

process(clk)

variable tma: STD_LOGIC_VECTOR(3 DOWNTO 0);

variable tmb: STD_LOGIC_VECTOR(3 DOWNTO 0);

begin

If Reset =‘0’then tma:=“0000”;

tmb:=“0000”;

elsif clk‘event and clk=’1‘ then

if en=’1‘ then

rco<=tmb(2)and tmb(0)and tma(3)and tma(0);

if tma=“1001” then

tma:=“0000”;

if tmb=“0101” then

tmb:=“0000”;

else tmb:=tmb+1;

end if;

else tma:=tma+1;

end if;

end if;

end if;

qa<=tma;

qb<=tmb;

end process;

END a;

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.ALL;

ENTITY count24 IS

PORT( en,Reset,clk: in STD_LOGIC;

qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);

qb: out STD_LOGIC_VECTOR(3 DOWNTO 0));

END count24;

ARCHITECTURE a1 OF count24 IS

BEGIN

process(clk)

variable tma: STD_LOGIC_VECTOR(3 DOWNTO 0);

variable tmb: STD_LOGIC_VECTOR(3 DOWNTO 0);

begin

If Reset = ‘0’then tma:=“0000”;

tmb:=“0000”;

else if clk‘event and clk=’1‘ then

if en=’1‘ then

if tma=“1001” then

tma:=“0000”;

tmb:=tmb+1;

elsif tmb=“0010” and tma=“0011” then

tma:=“0000”;

tmb:=“0000”;

else tma:=tma+1;

end if;

end if;

end if;

end if;

qa<=tma;

qb<=tmb;

end process;

END a1; LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY fenpinqi IS

PORT (CLK,RST:in std_logic;

CLK_OUT:out std_logic);

END fenpinqi;

ARCHITECTURE behav OF fenpinqi IS signal clk_data:std_logic;

SIGNAL CNT6 : INTEGER := 0;

BEGIN

PROCESS(CLK) BEGIN

IF RST = ‘0’ THEN

CNT6<=0

ELSIF CLK‘EVENT AND CLK=’1‘ THEN

IF CNT6=512 THEN

clk_data<=NOT clk_data;

CNT6<=0;

ELSE CNT6<=CNT6+1;

END IF;

END IF;

CLK_OUT<=clk_data;

END PROCESS;

END behav;

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY clock1 IS

PORT(CLK: IN STD_LOGIC;

S1, S2, S3, S4, S5, S6: IN STD_LOGIC_VECTOR(3 DOWNTO 0); WEI: OUT STD_LOGIC_VECTOR(2 DOWNTO 0);

LED: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END ENTITY;

ARCHITECTURE behave OF clock1 IS SIGNAL CNT6 : INTEGER RANGE 0 TO 5 := 0;

SIGNAL SHUJU: STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN PRO1:PROCESS(CLK)

BEGIN

IF CLK‘EVENT AND CLK = ’1‘ THEN

CNT6 <= CNT6 + 1;

CASE CNT6 IS

WHEN 0 => WEI <= “000”;

SHUJU <= S1; WHEN 1 => WEI <= “001”;

SHUJU <= S2; WHEN 2 => WEI <= “010”;

SHUJU <= S3; WHEN 3 => WEI <= “011”;

SHUJU <= S4; WHEN 4 => WEI <= “100”;

SHUJU <= S5;

WHEN 5 => WEI <= “101”;

SHUJU <= S6;

CNT6<=0;

WHEN OTHERS => NULL;

END CASE;

END IF;

END PROCESS;

PRO2: PROCESS(SHUJU)

BEGIN CASE SHUJU IS WHEN “0000” => LED<= x“3f”

WHEN “0001” => LED<= x“06”

WHEN “0010” => LED<= x“5b”

WHEN “0011” => LED<= x“4f”

WHEN “0100” => LED<= x“66”

WHEN “0101” => LED<= x“6d”

WHEN “0110” => LED<= x“7d”

WHEN “0111” => LED<= x“07”

WHEN “1000” => LED<= x“7f”

WHEN “1001” => LED<= x“6f”

WHEN others=> LED<= x“00”

END CASE;

END PROCESS;

END

电子计时器的功能仿真结果

VHDL代码

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分