倒计时控制器设计VHDL代码VIVADO basys3开发板

名称:倒计时控制器设计VHDL代码VIVADO  basys3开发板(文末获取)

软件:VIVADO

语言:VHDL

代码功能:

倒计时控制器

1、可以通过按键切换倒计时状态、设置状态

2、在设置状态下设计倒计时的时间,通过上下两个按键控制时间加减

3、时间设置好后,通过按键切换到倒计时状态,从设置的时间开始倒计时

本代码已在basys3开发板验证,basys3开发板如下,其他开发板可以修改管脚适配:

basys3开发板.png

1. 工程文件

2. 程序文件

3. 程序编译

4. 仿真图

4.1 main1_one_digit模块仿真

Testbench

仿真图

4.2 main2_four_digits模块仿真

Testbench

仿真图

4.3 整体仿真

Testbench

仿真图

部分代码展示:

LIBRARY ieee;
   USE ieee.std_logic_1164.all;
   USE ieee.std_logic_unsigned.all;
--计时模块
ENTITY downcnt_time IS
   PORT (
      clk        : IN STD_LOGIC;--100MHz
      clk_5KHz   : OUT STD_LOGIC;--输出5KHz,用于控制数码管切换
      btnU       : IN STD_LOGIC;--按键
      btnD       : IN STD_LOGIC;--按键
      btnC       : IN STD_LOGIC;--按键
      d3         : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--分钟十位
      d2         : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--分钟个位
      d1         : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--秒钟十位
      d0         : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)--秒钟十位
   );
END downcnt_time;
ARCHITECTURE Behavioral OF downcnt_time IS
--定义信号
   TYPE State_type IS (s_timing, s_set, s_setting, s_time);  -- 定义状态
   SIGNAL state : State_Type;    -- 创建信号
   SIGNAL clk_1Hz    : STD_LOGIC;--1hz,用于计时
   SIGNAL clk_5K     : STD_LOGIC := '0';
   SIGNAL count_1Hz      : integer := 0;
   SIGNAL count_5KHz     : integer := 0;  
   SIGNAL btnU_dff1  : STD_LOGIC;
   SIGNAL btnU_dff2  : STD_LOGIC;
   SIGNAL btnD_dff1  : STD_LOGIC;
   SIGNAL btnD_dff2  : STD_LOGIC;
   SIGNAL btnU_push    : STD_LOGIC;
   SIGNAL btnD_push    : STD_LOGIC;
   SIGNAL Min_10 : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";--分钟十位
   SIGNAL Min_1 : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";--分钟个位
   SIGNAL Sec_10 : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";--秒钟十位
   SIGNAL Sec_1 : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";--秒钟十位
BEGIN
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         IF (count_5KHz >= 100) THEN--100MHz计数10000后翻转得到5KHz的信号,仿真时将10000改小为100
            count_5KHz <= 0;
            clk_5K <= NOT(clk_5K);--翻转,得到5Khz
         ELSE
            count_5KHz <= count_5KHz + 1;--计数
         END IF;
      END IF;
   END PROCESS;
   
   clk_5KHz <= clk_5K;--输出5KHz
   
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         IF (count_1Hz >= 1000) THEN--100MHz分频到1Hz,计数100000000,仿真时减小为1000
            count_1Hz <= 0;
clk_1Hz <= '1';--得到1Hz信号脉冲
         ELSE
            count_1Hz <= count_1Hz + 1;--计数
clk_1Hz <= '0';
         END IF;
      END IF;
   END PROCESS;
   
   --状态控制
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         CASE state IS
            WHEN s_timing =>--计时状态
               IF (btnC = '1') THEN--btnC按下
                  state <= s_set;
               ELSE
                  state <= s_timing;
               END IF;
            WHEN s_set =>--btnC按键按下
               IF (btnC = '0') THEN--btnC按键松开
                  state <= s_setting;--进入设置状态
               ELSE
                  state <= s_set;
               END IF;
            WHEN s_setting =>--设置状态
               IF (btnC = '1') THEN--btnC按下
                  state <= s_time;
               ELSE
                  state <= s_setting;
               END IF;
            WHEN s_time =>--btnC按下
               IF (btnC = '0') THEN--btnC按键松开
                  state <= s_timing;--进入计时状态
               ELSE
                  state <= s_time;
               END IF;
            WHEN OTHERS =>
         END CASE;
      END IF;
   END PROCESS;
   
   --使用D触发器将btnU和btnD缓存
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         btnU_dff1 <= btnU;
         btnU_dff2 <= btnU_dff1;
         btnD_dff1 <= btnD;
         btnD_dff2 <= btnD_dff1;
      END IF;
   END PROCESS;
   
   --得到btnU和btnD的按键上升沿,只保持一个时钟周期的高电平
   btnU_push <= btnU_dff1 AND NOT(btnU_dff2);
   btnD_push <= btnD_dff1 AND NOT(btnD_dff2);
   
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         IF (state = s_setting) THEN--设置时间状态
            IF (btnU_push = '1') THEN--btnU按键按下,控制分钟时间加
               IF (Min_10 = "1001" AND Min_1 = "1001") THEN--分钟为99时,不再增加
                  Min_10 <= "1001";
                  Min_1 <= "1001";
               ELSIF (Min_1 = "1001") THEN--分钟个位是9
                  Min_10 <= Min_10 + "0001";--十位加1
                  Min_1 <= "0000";
               ELSE
                  Min_10 <= Min_10;
                  Min_1 <= Min_1 + "0001";--个位加1
               END IF;
            ELSIF (btnD_push = '1') THEN--btnU按键按下,控制分钟时间减
               IF (Min_10 = "0000" AND Min_1 = "0000") THEN--时间减到0,不再减
                  Min_10 <= "0000";
                  Min_1 <= "0000";
               ELSIF (Min_1 = "0000") THEN--个位为0
                  Min_10 <= Min_10 - "0001";--十位减1
                  Min_1 <= "1001";
               ELSE
                  Min_10 <= Min_10;
                  Min_1 <= Min_1 - "0001";--个位减1
               END IF;
            END IF;
         ELSIF (state = s_timing) THEN--倒计时状态
            IF (clk_1Hz = '1') THEN
               IF (Min_10 = "0000" AND Min_1 = "0000" AND Sec_10 = "0000" AND Sec_1 = "0000") THEN--减到0,倒计时结束
                  Min_10 <= "0000";
                  Min_1 <= "0000";
               ELSIF (Min_1 = "0000" AND Sec_10 = "0000" AND Sec_1 = "0000") THEN--
                  Min_10 <= Min_10 - "0001";--分钟十位减1
                  Min_1 <= "1001";
               ELSIF (Sec_10 = "0000" AND Sec_1 = "0000") THEN
                  Min_10 <= Min_10;
                  Min_1 <= Min_1 - "0001";--分钟个位减1
               ELSE
                  Min_10 <= Min_10;
                  Min_1 <= Min_1;
               END IF;
            END IF;
         END IF;
      END IF;
   END PROCESS;
源代码

点击下方的公众号卡片获取

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值