数字逻辑电路设计课程设计(二)

简介: 数字逻辑电路设计课程设计

4.5 闹钟设置器

闹钟设置器有时钟端clk,使能端en,置数端ld。输出端是两位8421BCD码。当使能端为0时,整个闹钟模块关闭。当使能端开启时,闹钟模块开启。当置数端为1时,闹钟会根据ledagpos信号选择置入十位还是个位。ledagnum为一位8421BCD码,为置入的数,输入无效时视为置入9。小时和分钟的值都需要一个闹钟设置器。闹钟设置器寄存了闹钟设定的时间。

library ieee;
use ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.ALL;
entity alarmsetter_m is
  port(clk,en:in std_logic;
  cc:out std_logic_vector(7 downto 0);
  ledagnum:in std_logic_vector(3 downto 0);
  ledagpos:in std_logic;
  ld:in std_logic);
end alarmsetter_m;
architecture one of alarmsetter_m is
  begin
  process(clk,ld)
  variable mc1,mc0:std_logic_vector(3 downto 0):="0000";
  begin   
    if clk'event and clk='1'then
    if en='0' then
    if ld='1' then--置数
      if(ledagpos='1') then
        if(ledagnum>"0101") then--分钟的十位,最多只能置5
          mc1:="0101";
        else
          mc1:=ledagnum;
        end if;
      elsif(ledagpos='0') then
        if(mc0>="1010") then--个位,只能置0~9
          mc0:="1001";
        else
          mc0:=ledagnum;
        end if;
      end if;
      end if;
    end if;
    end if;
  cc<=mc1&mc0;
  end process;
end one;

4.6闹钟判断器

输入端为当前的小时数和当前的分钟数、闹钟设定的小时数和闹钟设定的分钟数。若它们对应相等,则对蜂鸣器输入信号。

library ieee;
use ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.ALL;
entity alarmjudger is
  port(clk:in std_logic;
  htime:in std_logic_vector(7 downto 0);--当前小时
  halarm:in std_logic_vector(7 downto 0);--闹钟小时
  mtime:in std_logic_vector(7 downto 0);--当前分钟
  malarm:in std_logic_vector(7 downto 0);--闹钟分钟
  alarmon:out std_logic);--输出
end alarmjudger;
architecture one of alarmjudger is
  begin
  process(clk)
  begin   
    if clk'event and clk='1'then
      if htime=halarm and mtime=malarm then--判断两两相等
        alarmon<='1';
      else alarmon<='0';
      end if;
    end if;
  end process;
end one;

4.7 倒计时器

输入端有时钟、复位、使能、置数等,输出有两个8421BCD码表示的秒数、蜂鸣器开启信号。在最后的01秒,输出蜂鸣器开启的信号,以便在下一个时钟信号到来时蜂鸣器发出声音。设置了内部变量,使得倒计时计到0时开始计数,能从0计到60,能够控制蜂鸣器响的时间:60秒。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity countdown is
port(
   clk,rst,en,ld:in std_logic;--时钟、复位、使能、置数
   alarmout:out std_logic;--蜂鸣器开启
  ledagnum:in std_logic_vector(3 downto 0);--设置置入的数
  ledagpos:in std_logic;--设置置入十位还是个位
  sout:out std_logic_vector(7 downto 0)--输出当前倒计时
);
end countdown;
architecture one of countdown is
begin
process(clk,rst,ld)
  variable mc10,mc1:std_logic_vector(3 downto 0);
  variable q1:integer range 0 to 100;--内部变量,
  begin
  if rst='1' then --复位,复位成99秒
    mc10:="1001";
    mc1:="1001";
    q1:=0;
    alarmout<='0';
  elsif clk'event and clk='1' then
    if ld='1' then
      if ledagpos='1' then--置十位
        mc10:=ledagnum;
      end if;
      if ledagpos='0' then--置个位
        mc1:=ledagnum;
      end if;
    end if;
    if ld='0' then
      if en='1' then
        if (mc1=1 and mc10=0) then--在最后01秒
          alarmout<='1';
          mc1:=mc1-1;
q1:=0;
        elsif mc1=0 then
          if mc10=0 then--在0秒,倒计时完成时
          q1:=q1+1;--计数器,每秒+1,在计了60秒前输出蜂鸣器信号
            if q1<59 then
              alarmout<='1';
            else
              q1:=61;
              alarmout<='0';
            end if; 
          else mc10:=mc10-1;
          mc1:="1001";--在十的倍数秒
          end if;
        else
          mc1:=mc1-1;-在十的倍数秒
          alarmout<='0';
          end if; 
        end if;
      else alarmout<='0';
      end if;
    end if; 
  sout<=mc10&mc1;   
end process;
end one;

4.8蜂鸣控制器

蜂鸣控制器的输出端直接连接着蜂鸣器,输出一个频率信号使得蜂鸣器按这个频率发出声响。在每个小时的59分50/52/54/56/58秒,按500hz发出声响。在每个小时的0分0秒,按1khz发出声响。在闹钟设定的时间,按1khz发出声响。在倒计时结束时,按500hz发出声响。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity xiang is
port(clk_500:in std_logic;
  clk:in std_logic;
  en:in std_logic;
  alarmlow,alarmhigh,alarmco:in std_logic;
  alarmbyalarm:in std_logic;
  alarmbycountdown:in std_logic;
  speaker:out std_logic);
end xiang;  
architecture sss_arc of xiang is
 begin
  process(clk)
  begin
    if en='1' then
      if (alarmlow='1' and alarmhigh='1' and alarmco='0') then
        speaker<=clk_500;
      end if;
      if alarmco='1' then
        speaker<=clk;
      end if;
      if alarmbyalarm='1' then
        speaker<=clk;
      end if;
      if alarmbycountdown='1' then
        speaker<=clk_500;
      end if;
    end if;
  end process;
end;

4.9动态扫描显示器

动态扫描显示器有多个输入,包括时钟信号、小时值、分钟值、秒值。是否正在置数、正在置哪一位数、是否正在置闹钟、是否想显示闹钟、是否在倒计时、显示倒计时等判断都被集成到了动态扫描显示器中。输出有位码和段码,在1khz的时钟信号下,能够正确的输出对应数字。

若当前正在置数,我们则可以设置一个计数器范围为01000,当该变量值为0500时,对应位置的段码数值为无效值。当该变量值为500~999时,该对应位置的值为当前置入的数值。利用这种做法,我们可以做到:当前正在设置的设置的位置的数在闪烁。

正常情况下,动态扫描显示模块会显示当前时间。当我们调整闹钟时,拨动开关,动态扫描模块显示闹钟时间。当我们调整倒计时时,拨动开关,动态扫描模块显示倒计时时间。闹钟的显示优先级高于倒计时,倒计时显示优先级高于正常时间。

将8位8421BCD码传送至7段显示译码器,然后动态地显示在相应的显示器上。显示器显示的内容受段码和位码的控制,这就是动态扫描显示的原理。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity seltime is
port(clk:in std_logic;
  h,m,s:in std_logic_vector(7 downto 0);
  sel:out std_logic_vector(2 downto 0);
  seg:out std_logic_vector(6 downto 0);
  isledagging:in std_logic;
  ledagpos:in std_logic_vector(2 downto 0);
  isledaggingalarm:in std_logic;
  alarmh,alarmm:in std_logic_vector(7 downto 0);
  iscountingdown:in std_logic;
  countdowns:in std_logic_vector(7 downto 0))
  ;
end seltime;
architecture beha of seltime is
  signal scan_count:std_logic_vector(2 downto 0);
  signal dat:std_logic_vector(3 downto 0);
  signal q1:integer range 0 to 999;
  begin
    scan:process(clk)
      begin
        if clk'event and clk='1' then
          scan_count<=scan_count+1;
          q1<=q1+1;
        end if;
      sel<=scan_count;
    if isledaggingalarm='1' then
      case scan_count is
        when "101"=>dat<=alarmm(3 downto 0);
        when "100"=>dat<=alarmm(7 downto 4);
        when "011"=>dat<=alarmh(3 downto 0);
        when "010"=>dat<=alarmh(7 downto 4);
        when others=>dat<="1100";
      end case;
    elsif iscountingdown='1' and isledagging='0' then
      case scan_count is
        when "111"=>dat<=countdowns(3 downto 0);
        when "110"=>dat<=countdowns(7 downto 4);
        when others=>dat<="1100";
      end case;
    else
      case scan_count is
        when "111"=>dat<=s(3 downto 0);
        when "110"=>dat<=s(7 downto 4);
        when "101"=>dat<=m(3 downto 0);
        when "100"=>dat<=m(7 downto 4);
        when "011"=>dat<=h(3 downto 0);
        when "010"=>dat<=h(7 downto 4);
        when others=>dat<="1100";
      end case;
    end if; 
    end process scan;
    decode:process(scan_count) begin
    if (isledagging='1' and scan_count=ledagpos and q1<500) then
        seg<="0000000";
      else
      case dat is
        when"0000"=>seg<="0111111";
        when"0001"=>seg<="0000110";
        when"0010"=>seg<="1011011";
        when"0011"=>seg<="1001111";
        when"0100"=>seg<="1100110";
        when"0101"=>seg<="1101101";
        when"0110"=>seg<="1111101";
        when"0111"=>seg<="0000111";
        when"1000"=>seg<="1111111";
        when"1001"=>seg<="1101111";
        when others=>seg<="0000000";
      end case;
    end if;
    end process decode;
end beha;

4.10 其他辅助模块

地址位码解释模块。我们在输入时,选择位置是按如下办法:一个开关选择调整小时还是分钟,一个开关选择调整十位还是个位。利用这一位码解释模块,我们便能将我们置数的位置解析成位码传给动态扫描显示模块。

library ieee;
use ieee.std_logic_1164.all;
entity flasher is
  port(inh,intt:in std_logic;
  dataout:out std_logic_vector(2 downto 0));
end flasher;
architecture one of flasher is
  begin
  process(inh,intt)
  begin
  if(inh='1' and intt='1') then--小时的十位
    dataout<="010";
  end if; 
  if(inh='1' and intt='0') then--小时的个位
    dataout<="011";
  end if; 
  if(inh='0' and intt='1') then--分钟的十位
    dataout<="100";
  end if;
  if(inh='0' and intt='0') then--分钟的个位
    dataout<="101";
  end if;
  end process;
  end;

输入合成模块,将4个二进制输入合成为一个8421BCD码

library ieee;
use ieee.std_logic_1164.all;
entity connector is
  port(in3,in2,in1,in0:in std_logic;
  dataout:out std_logic_vector(3 downto 0));
end connector;
architecture one of connector is
  begin
  dataout<=in3&in2&in1&in0;--将4位二进制数合成BCD码
  end;  

分配器,选择当前是在调整小时还是在调整分钟。

library ieee;
use ieee.std_logic_1164.all;
entity ledagger is
  port(data:in std_logic_vector(3 downto 0);
  posi:in std_logic;
  ison:in std_logic;
  datah:out std_logic_vector(3 downto 0);
  datam:out std_logic_vector(3 downto 0));
  end ledagger;
architecture one of ledagger is
  begin
  process(ison,posi)
  begin
  if (ison='1' and posi='1') then--调整小时
    datah<=data;
    datam<="0000";
  elsif (ison='1' and posi='0') then--调整分钟
    datam<=data;
    datah<="0000";
  else
    datam<="0000";
    datah<="0000";
  end if;
  end process;
end one;

五、结论实现效果

5.1 各模块仿真波形效果

对分频器模块进行波形仿真,我们可以看到:1khz的频率被分成了500hz的频率和1hz的频率。

对秒计数器模块进行波形仿真,我们可以看到:每分钟50/52/54/56/58秒输出报时信号,每分钟59秒给分计数器输出进位信号。

对分计数器进行波形仿真,我们可以看到:每小时59分输出报时信号,以与秒计数器的50/52/54/56/58秒输出500hz的蜂鸣声。每小时60分输出进位信号,以让小时计数器计数,并对蜂鸣器给出报时信号。

对小时计数器进行波形仿真。每记到23,便复位为0,并进位输出,表示一天已经过去了。

对闹钟判断器进行波形仿真。当闹钟设定时间与当前时间的小时与分都对应着相等时,输出信号1.

对倒计时器进行波形仿真。在秒数不为0时,正常往下递减秒数。在秒数为0时,对输出信号1,持续60秒。该信号连接蜂鸣器。如图,首先将倒计时置为11.在11秒后,输出信号1持续了60秒。这对应了倒计时结束时蜂鸣器响一分钟的功能。

对蜂鸣器进行波形仿真。可以看到蜂鸣器频率与其输入频率之间的关系。

5.2整体效果

在将编译完成的QuartusII工程文件下载到机箱后,多功能数字钟便开启运行。

将K1开关拨动到1,就可以看到电子钟开始正常的计时运行。点击S1按钮,便可以将时间重置成从0分0秒开始。

将K2开关拨动到1,就可以开启蜂鸣器。

在每个小时的59分的50/52/54/56/58秒,蜂鸣器按500hz响。在每个小时的0分0秒,蜂鸣器按1khz响。这就是整点报时功能。

将K3开关拨动到1,就开始了调整时间模式。K4开关可以控制用户调整的是小时还是分钟,K5开关可以控制用户调整的是个位数还是十位数。在调整时,相应位置的数字闪烁。K6/K7/K8/K9是从高到低的8421BCD码,通过K6~K9所表示的十进制数可以调节对应位置的时间。

K10开关可以显示闹钟。默认的闹钟时间是22:00。但是,将K3开关拨动到1时K10开关也拨动到1,就可以调整闹钟。调整闹钟的值的办法与上一段调整时间值的办法是一致的。当闹钟设置的时间就是当前时间时,响铃一分钟。

K11开关可以显示倒计时。默认从99秒开始倒计时。将K12开关拨动到1,就可以调整倒计时的时间,调整办法与上文一致。按S2按钮可以重置倒计时。当倒计时为0时,响铃一分钟。

目录
相关文章
数字逻辑电路设计课程设计(一)
数字逻辑电路设计课程设计
221 0
数字逻辑电路设计课程设计(一)
|
SQL 算法 Java
【Verilog刷题篇】硬件工程师从0到入门2|组合逻辑
硬件工程师近年来也开始慢慢吃香,校招进大厂年薪总包不下30-40w的人数一大把!而且大厂人数并没有饱和!
【Verilog刷题篇】硬件工程师从0到入门2|组合逻辑
|
存储 芯片 内存技术
基于单片机的数字万年历设计
基于单片机的数字万年历设计
335 0
基于单片机的数字万年历设计
数字逻辑电路设计实验:加法器
数字逻辑电路设计实验:加法器
109 0
数字逻辑电路实验:基本电子钟
数字逻辑电路实验:基本电子钟
110 0
|
Java
一款设计和模拟数字逻辑电路的LogiSim工具
Logisim是一种用于设计和模拟数字逻辑电路的教育工具。凭借其简单的工具栏界面和构建它们时的电路仿真,它非常简单,有助于学习与逻辑电路相关的最基本概念。由于能够从较小的子电路构建更大的电路,并通过鼠标拖动来绘制电线束。
361 0
|
测试技术 容器
《数字逻辑设计与计算机组成》一 2.10 硬件描述语言
本节书摘来自华章出版社《数字逻辑设计与计算机组成》一 书中的第2章,第2.10节,作者:[美]尼克罗斯·法拉菲,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1575 0
《数字逻辑设计与计算机组成》一3.2 算术函数
本节书摘来自华章出版社《数字逻辑设计与计算机组成》一 书中的第3章,第3.2节,作者:[美]尼克罗斯·法拉菲,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
958 0
|
算法
《数字逻辑设计与计算机组成》一 3.4 减法器
本节书摘来自华章出版社《数字逻辑设计与计算机组成》一 书中的第3章,第3.4节,作者:[美]尼克罗斯·法拉菲,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1998 0
|
算法 安全 测试技术
《数字逻辑设计与计算机组成》一练习
本节书摘来自华章出版社《数字逻辑设计与计算机组成》一 书中的第3章,练习章节,作者:[美]尼克罗斯·法拉菲,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1722 0