数字竞赛抢答器

一  设计任务及要求

设计一个可容纳四组参赛者同时抢答的数字抢答器。

  (1)能判断第一抢答者并报警指示抢答成功,其他组抢答均无效;

  (2)设计倒计时时钟,若提前抢答则对相应的抢答组发出警报。

二、设计原理简介

2.1 数字式竞赛抢答器工作流程:

73a88ad133cd422c92a77d6d816667a7.png

图1.1 数字式竞赛抢答器工作流程

2.2 状态控制模块原理

     状态控制模块的目标是区分提前抢答和正常抢答两个不同状态,并且确保第一抢答者并报警指示抢答成功,其他组抢答均无效。基于此目标,状态控制控制模块的设计原则便是,依据数字抢答器的工作原理逻辑,定义不同的状态,以及确定不同状态之间进行切换的控制条件。

     数字抢答器应当包括两层状态,更加基本的三个状分别是闲置状态、倒计时状态以及正常抢答状态。其中,倒计时状态又引申出各组参赛者提前抢答状态,而正常抢答状态引申出各组参赛者首先抢答状态。

     考虑基本的三个状态之间切换的限制条件,引入一个开始信号,将闲置状态改变为倒计时状态;倒计时自然结束后,状态改变为正常抢答状态;此外,引入一个复位信号,不论当时处于什么状态,接收到复位信号后,均恢复为闲置状态。

      考虑倒计时引申出的状态,在倒计时还未归零前,4个参赛组分别对应的key1到key4信号任意有一个被接收时,即进入对应组别的提前抢答状态,除复位信号可以使得这四个状态回到闲置状态以外,不再设置其它可以改变状态的信号,这样就可以确保判断第一抢答组的组别。

      考虑正常抢答状态引申出的状态,分别对应4个组别的抢答成功状态,同样,不设置复位按键以外可以切换这四个状态的信号,以确保可以判断第一抢答组的组别。

     综上所述,一共有11个状态,包括三个基本状态:闲置、倒计时以及正常抢答;八个引申状态,1-4号提前抢答状态以及1-4号正常抢答状态。逻辑如下图:

ca55d7cb95ba489da80feb5aa9f1c93b.png

图1.2 状态切换流程图

2.3 倒计时显示模块原理

        倒计时功能是配合倒计时状态的功能,基本而言,倒计时时间没有归0时,处于倒计时状态,归0后处于正常抢答状态。为实现其对状态切换的控制功能,需要一个信号倒计时来赋值处理,引入一个downtime信号,使用10秒倒计时,为方便后续使用经典的七段数码管驱动电路来实现显示,采用四位二进制存储,最后效果要求从10秒倒计时到0.我们已经知道,系统提供的时钟信号是50MHz,引入一个clk_1Hz,对clk信号的高低电平切换进行计数,每有一次,i加一,当i记录到50M时,将clk计数清0,同时clk_1Hz赋值为高电平,i不等于50M时令clk_1Hz等于0.每当clk_1Hz等于1时,令倒计时信号减一。当然,倒计时在接收到开始信号时从9开始减少。逻辑如下图。

dacb8e0a477944f49dc6a8ee7b3b6387.png

图1.3 倒计时秒钟信号发生器

对于数码管显示,将对应4位二进制码转换为8位数码管对应码(如下表)即可完成数码管显示。

表1 七位数码管对应图

e629c78ccc39413b9773090251ef756f.jpeg

2.4 抢答对应提示与报警功能模块原理

      这一模块分为正常抢答的提示部分和提前抢答的警告部分,可以利用对应的8个引申状态为前提,来控制对应的提示和警报功能。该代码以led灯长亮与蜂鸣器长鸣作为提示信号,以led灯闪烁和蜂鸣器间断发出鸣叫来作为警报信号。对于长亮和长鸣,只要分别赋予led灯和蜂鸣器以低电平,令其在对应正常抢答状态正常工作即可,对于闪烁和间断,受1Hz时钟信号的启发,采用同样的方法,使得1秒50M分为4个12.5M令clk_2Hz信号反转4次,利用非1=0,非0=1,即可实现2Hz的时钟信号。

       然后在1组正常抢答状态下,令1号led灯常亮,蜂鸣器长鸣;2组正常抢答状态下,令2号led灯常亮,蜂鸣器长鸣;3组正常抢答状态下,令3号led灯常亮,蜂鸣器长鸣;4组正常抢答状态下,令4号led灯常亮,蜂鸣器长鸣;

      在1组提前抢答状态下,令1号led灯闪烁,蜂鸣器间断发出声响;在2组提前抢答状态下,令2号led灯闪烁,蜂鸣器间断发出声响;在3组提前抢答状态下,令3号led灯闪烁,蜂鸣器间断发出声响;在4组提前抢答状态下,令4号led灯闪烁,蜂鸣器间断发出声响;

2af007d294da4ef485b0da3a1ddfd9e9.png

图1.4  2Hz时钟信号发生器

三、设计方案与实现

3.1 设计软件环境搭建

       本设计使用软件QUARTUS II 13.0开发,使用VHDL语言编写,采用ModelSi Altera进行仿真。新建工程文件命名为qiangdaqi,并新建control.vhd、div.vhd、LED7S.vhd等文件。

       之后按照Processing--Start--Start Test Bench Template Writer运行,编写好.tbh仿真模板的文件,进入Assignments--setting导入仿真模板。

  注:设置仿真工具路径:Tools--options--EDA Tool Options

3.2  仿真效果

63d4e65260ff4b92896ecf106f23fd4c.jpeg

图2.3 key1组提前抢答

       分析:可以看到,可以看到7位数码管输出(10011001)对应的倒计时为4,不为0,key1按下,导致led1闪烁,beep间断性鸣叫

adf560edf49341e59e9a4dda7345c628.jpeg

图2.4 key3组正常抢答

       分析:可以看到7位数码管输出(11000000)对应的倒计时为0,即在正常抢答状态下,第三组先抢答成功,led3亮起(低电平)且beep正常鸣叫(低电平),且随后第四组抢答已经无效。

3.3管脚

37ed73d82f594272aeb49cd76f9faf00.png

图2.5 管脚图 

四、仿真结果分析

4.1 调试流程

       调试流程:我们使用的芯片是EDA MAXII EPM 240T100C5,通过下载相关芯片库并存放于quartus的bin文件夹中,选择正确的芯片进行编程,代码编译成功后。将开发板的电源线与JIAG接口与电脑相连,之后首先在设备管理器-通用串行总线控制器中将usb-blaster的数字驱动进行更新,随后在programmer中检测到usb0接口,加入编译生成的.pof文件后,勾选program/configure,点击开始,加载到100%后烧录成功。


LIBRARY ieee;
   USE ieee.std_logic_1164.all;
   USE ieee.std_logic_unsigned.all;
--控制模块
ENTITY control IS
   PORT (
      clk          : IN STD_LOGIC;--时钟
      rst_n        : IN STD_LOGIC;--复位
      start_n      : IN STD_LOGIC;--开始
      key_1        : IN STD_LOGIC;--按键1
      key_2        : IN STD_LOGIC;--按键2
      key_3        : IN STD_LOGIC;--按键3
      key_4        : IN STD_LOGIC;--按键4
      clk_1Hz      : IN STD_LOGIC;---1Hz信号
      clk_2Hz      : IN STD_LOGIC;--2Hz信号
      LED1         : OUT STD_LOGIC;--LED1
      LED2         : OUT STD_LOGIC;--LED2
      LED3         : OUT STD_LOGIC;--LED3
      LED4         : OUT STD_LOGIC;--LED4
      beep         : OUT STD_LOGIC;--蜂鸣器
      down_time    : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)--倒计时
   );
END control;

ARCHITECTURE behave OF control IS
   type state_type is(s_idle,s_downcnt,s_start,s_qiangda_1,s_qiangda_2,s_qiangda_3,s_qiangda_4,s_early_1,s_early_2,s_early_3,s_early_4);
   SIGNAL state : state_type;
   SIGNAL time_cnt : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";
BEGIN
--状态机
   PROCESS (clk, rst_n)
   BEGIN
      IF (rst_n = '0') THEN
         state <= s_idle;--复位
      ELSIF (clk'EVENT AND clk = '1') THEN
         CASE state IS
            WHEN s_idle =>--空闲状态
               IF (start_n = '0') THEN
                  state <= s_downcnt;
               ELSE
                  state <= s_idle;
               END IF;
            WHEN s_downcnt =>--倒计时状态
               IF (key_1 = '0') THEN
                  state <= s_early_1;--提前抢答1
               ELSIF (key_2 = '0') THEN
                  state <= s_early_2;--提前抢答2
               ELSIF (key_3 = '0') THEN
                  state <= s_early_3;--提前抢答3
               ELSIF (key_4 = '0') THEN
                  state <= s_early_4;--提前抢答4
               ELSIF (time_cnt = "0000") THEN
                  state <= s_start;
               ELSE
                  state <= s_downcnt;
               END IF;
            WHEN s_start =>--开始抢答
               IF (key_1 = '0') THEN
                  state <= s_qiangda_1;--正常抢答1
               ELSIF (key_2 = '0') THEN
                  state <= s_qiangda_2;--正常抢答2
               ELSIF (key_3 = '0') THEN
                  state <= s_qiangda_3;--正常抢答3
               ELSIF (key_4 = '0') THEN
                  state <= s_qiangda_4;--正常抢答4
               ELSE
                  state <= s_start;
               END IF;
            WHEN OTHERS =>
               state <= state;
         END CASE;
      END IF;
   END PROCESS;
   
   --倒计时
   PROCESS (clk, rst_n)
   BEGIN
      IF (rst_n = '0') THEN
         time_cnt <= "1001";--9开始
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (state = s_downcnt) THEN
            IF (clk_1Hz = '1') THEN--1Hz
               time_cnt <= time_cnt - "0001";--倒计时
            ELSE
               time_cnt <= time_cnt;
            END IF;
         ELSE
            time_cnt <= time_cnt;
         END IF;
      END IF;
   END PROCESS;
   
   
   down_time <= time_cnt;--输出倒计时
   
   --LED1
   PROCESS (clk, rst_n)
   BEGIN
      IF (rst_n = '0') THEN
         LED1 <= '1';
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (state = s_qiangda_1) THEN
            LED1 <= '0';--正常抢答亮
         ELSIF (state = s_early_1) THEN
            LED1 <= clk_2Hz;--提前抢答闪烁
         ELSE
            LED1 <= '1';
         END IF;
      END IF;
   END PROCESS;
   
   
   PROCESS (clk, rst_n)
   BEGIN
      IF (rst_n = '0') THEN
         LED2 <= '1';
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (state = s_qiangda_2) THEN
            LED2 <= '0';--正常抢答亮
         ELSIF (state = s_early_2) THEN
            LED2 <= clk_2Hz;--提前抢答闪烁
         ELSE
            LED2 <= '1';
         END IF;
      END IF;
   END PROCESS;
   
   
   PROCESS (clk, rst_n)
   BEGIN
      IF (rst_n = '0') THEN
         LED3 <= '1';
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (state = s_qiangda_3) THEN
            LED3 <= '0';--正常抢答亮
         ELSIF (state = s_early_3) THEN
            LED3 <= clk_2Hz;--提前抢答闪烁
         ELSE
            LED3 <= '1';
         END IF;
      END IF;
   END PROCESS;
   
   
   PROCESS (clk, rst_n)
   BEGIN
      IF (rst_n = '0') THEN
         LED4 <= '1';
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (state = s_qiangda_4) THEN
            LED4 <= '0';--正常抢答亮
         ELSIF (state = s_early_4) THEN
            LED4 <= clk_2Hz;--提前抢答闪烁
         ELSE
            LED4 <= '1';
         END IF;
      END IF;
   END PROCESS;
   
   
   PROCESS (clk, rst_n)
   BEGIN
      IF (rst_n = '0') THEN
         beep <= '1';
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (state = s_qiangda_1 OR state = s_qiangda_2 OR state = s_qiangda_3 OR state = s_qiangda_4) THEN
            beep <= '0';--正常抢答蜂鸣器提示
         ELSIF (state = s_early_1 OR state = s_early_2 OR state = s_early_3 OR state = s_early_4) THEN
            beep <= clk_2Hz;--提前抢答蜂鸣器间断提示
         ELSE
            beep <= '1';
         END IF;
      END IF;
   END PROCESS;
   
   
END behave;





LIBRARY ieee;
   USE ieee.std_logic_1164.all;
   USE ieee.std_logic_unsigned.all;
--分频器
ENTITY div IS
   PORT (
      clk      : IN STD_LOGIC;--50M
      clk_1Hz  : OUT STD_LOGIC;--1Hz
      clk_2Hz  : OUT STD_LOGIC--2Hz
   );
END div;

ARCHITECTURE behave OF div IS
   
   SIGNAL i     : INTEGER := 0;
   SIGNAL clk_2 : STD_LOGIC := '0';
   SIGNAL j     : INTEGER := 0;
BEGIN
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         IF (i >= 50000000) THEN--计数50000000
            i <= 0;
            clk_1Hz <= '1';--分频产生1Hz脉冲信号
         ELSE
            i <= i + 1;
            clk_1Hz <= '0';
         END IF;
      END IF;
   END PROCESS;
   
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         IF (j = 12500000) THEN--计数12500000
            j <= 0;
            clk_2 <= NOT(clk_2);--分频产生2Hz信号
         ELSE
            j <= j + 1;
         END IF;
      END IF;
   END PROCESS;
   
   
   clk_2Hz <= clk_2;
   
END behave;





library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
--数码管译码
entity LED7S is
Port(din: in std_logic_vector(3 downto 0);
	 y: out std_logic_vector(7 downto 0));
end LED7S;
architecture one of LED7S is
begin
    process(din)
    begin 
      case din is
		 when "0000" => y<="11000000";		--- Display "0"
		 when "0001" => y<="11111001";		--- Display "1"
		 when "0010" => y<="10100100";		--- Display "2"
		 when "0011" => y<="10110000";		--- Display "3"
		 when "0100" => y<="10011001";		--- Display "4"
		 when "0101" => y<="10010010";		--- Display "5"
		 when "0110" => y<="10000010";		--- Display "6"
		 when "0111" => y<="11111000";		--- Display "7"
		 when "1000" => y<="10000000";		--- Display "8"
		 when "1001" => y<="10010000";		--- Display "9"
		 when "1010" => y<="10001000";		--- Display "A"
		 when "1011" => y<="10000011";		--- Display "B"
		 when "1100" => y<="11000110";		--- Display "C"
		 when "1101" => y<="10100001";		--- Display "D"
		 when "1110" => y<="10000110";		--- Display "E"
		 when "1111" => y<="10001110";		--- Display "F"
		 when others => NULL;
      end case;
    end process;
end one;


LIBRARY ieee;                                               
USE ieee.std_logic_1164.all;                                

ENTITY qiangdaqi_vhd_tst IS
END qiangdaqi_vhd_tst;
ARCHITECTURE qiangdaqi_arch OF qiangdaqi_vhd_tst IS
-- constants                                                 
-- signals                                                   
SIGNAL beep : STD_LOGIC;
SIGNAL clk : STD_LOGIC;
SIGNAL en : STD_LOGIC;
SIGNAL HEX : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL key_1 : STD_LOGIC;
SIGNAL key_2 : STD_LOGIC;
SIGNAL key_3 : STD_LOGIC;
SIGNAL key_4 : STD_LOGIC;
SIGNAL LED1 : STD_LOGIC;
SIGNAL LED2 : STD_LOGIC;
SIGNAL LED3 : STD_LOGIC;
SIGNAL LED4 : STD_LOGIC;
SIGNAL rst_n : STD_LOGIC;
SIGNAL start_n : STD_LOGIC;
COMPONENT qiangdaqi
	PORT (
	beep : OUT STD_LOGIC;
	clk : IN STD_LOGIC;
	en : OUT STD_LOGIC;
	HEX : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
	key_1 : IN STD_LOGIC;
	key_2 : IN STD_LOGIC;
	key_3 : IN STD_LOGIC;
	key_4 : IN STD_LOGIC;
	LED1 : OUT STD_LOGIC;
	LED2 : OUT STD_LOGIC;
	LED3 : OUT STD_LOGIC;
	LED4 : OUT STD_LOGIC;
	rst_n : IN STD_LOGIC;
	start_n : IN STD_LOGIC
	);
END COMPONENT;
BEGIN
	i1 : qiangdaqi
	PORT MAP (
-- list connections between master ports and signals
	beep => beep,
	clk => clk,
	en => en,
	HEX => HEX,
	key_1 => key_1,
	key_2 => key_2,
	key_3 => key_3,
	key_4 => key_4,
	LED1 => LED1,
	LED2 => LED2,
	LED3 => LED3,
	LED4 => LED4,
	rst_n => rst_n,
	start_n => start_n
	);
	
init : PROCESS                                                                           
BEGIN                                                        
rst_n<='0';    
start_n <='1';        
key_1<='1';    --按键1
key_2<='1';    --按键2
key_3<='1';    --按键3
key_4<='1';    --按键4     
WAIT FOR 100 ns;     
rst_n<='1';    
WAIT FOR 1000 ns;  
start_n <='0';
WAIT FOR 1000 ns;  
start_n <='1';
WAIT FOR 50000 ns;
key_1<='0';    --按键1  提前抢答
WAIT FOR 100 ns;
key_1<='1';    --按键1  
WAIT FOR 50000 ns;
rst_n<='0';    
WAIT FOR 100 ns;     
rst_n<='1';  
WAIT FOR 1000 ns;  
start_n <='0';
WAIT FOR 1000 ns;  
start_n <='1';

WAIT FOR 150000 ns;
key_3<='0';    --按键3
WAIT FOR 100 ns;
key_3<='1';    --按键3  
WAIT FOR 5000 ns;
WAIT FOR 5000 ns;
key_4<='0';    --按键4
WAIT FOR 100 ns;
key_4<='1';    --按键4
WAIT FOR 5000 ns;
WAIT;                                                       
END PROCESS init;
                                           
always : PROCESS                                                                                  
BEGIN                                                         
clk<='0';
WAIT FOR 10 ns;      
clk<='1';
WAIT FOR 10 ns;                                                   
END PROCESS always;                                          
END qiangdaqi_arch;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值