欣欣学习网,老工程师带你学习单片机技术,欢迎来坐坐。
首  页 | 学习NIOSII | 学习C51 | 学习CPLD | 51+CPLD实验板 | | | MY-RTOS

本栏目的实验需在 WinXp 上操作。建议在 Virtual Box 虚机上安装WinXp系统,使用更方便。

 MAXII学习板首页
 安装QuartusII6.0软件
 Quartus II 使用入门
 安装ModelSim6.0SE
 使用ModelSim仿真
 使用ModelSim做后仿真
 闪灯程序
 流水灯程序
 数码管计数程序
 计时秒表程序
 PWM控制LED灯亮度程序
 UART通信程序
 PS2口通信程序
 VGA信号发生器程序
 为单片机扩展UART
 相关软件与文档


MAXII CPLD 实验板

计时秒表程序


注:

本实验是针对 MC570/MC240 实验板 设计的,如选用其它开发板实现,部分内容需做调整。

用 CPLD 来实现一个计时秒表。实验板上的数码管来显示秒数,8个LED灯用BCD码来显示 1/10 秒和 1/100 秒。按一下按键,开始计时;再按一下,停止计时,保留计时结果;再按一下,清零;再按一下,又开始计时。

1.

点击 这里 下载示例工程。*.qar 是 QuartusII 的压缩文档,用 QuartusII6.0 打开。

程序代码如下:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;

ENTITY maxii_timer IS
  PORT(
    clk     : IN STD_LOGIC;
    s0      : IN STD_LOGIC;
    s1      : IN STD_LOGIC;
    leddrv  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
    seg     : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
    sel     : OUT STD_LOGIC_VECTOR(1 DOWNTO 0)
  );
END maxii_timer;

ARCHITECTURE maxii_timer OF maxii_timer IS

  COMPONENT digdrv
    PORT(
      clk   : IN STD_LOGIC;
      dig   : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
      seg   : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
      sel   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0)
    );
  END COMPONENT;

  TYPE TAB_TYPE IS ARRAY(0 TO 15) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
  CONSTANT TAB : TAB_TYPE := (("00111111"),
                              ("00000110"),
                              ("01011011"),
                              ("01001111"),
                              ("01100110"),
                              ("01101101"),
                              ("01111101"),
                              ("00100111"),
                              ("01111111"),
                              ("01101111"),
                              ("01110111"),
                              ("01111100"),
                              ("00111001"),
                              ("01011110"),
                              ("01111001"),
                              ("01110001")); 

  SIGNAL dig : STD_LOGIC_VECTOR(15 DOWNTO 0);
  SIGNAL P10MS : INTEGER RANGE 0 TO 9;
  SIGNAL P100MS : INTEGER RANGE 0 TO 9;
  SIGNAL PS : INTEGER RANGE 0 TO 9;
  SIGNAL P10S :INTEGER RANGE 0 TO 9;
  SIGNAL CP100MS, CP10MS, CPS : STD_LOGIC;
  SIGNAL keyPress : STD_LOGIC;
  SIGNAL s0Last, s1Last : STD_LOGIC;
  SIGNAL click : STD_LOGIC;
  SIGNAL mState : INTEGER RANGE 0 TO 3 :=0;
  CONSTANT RUN : INTEGER :=0;
  CONSTANT READY : INTEGER := 1;
  CONSTANT CHECK : INTEGER := 2;
 
BEGIN

  u1:digdrv
  PORT MAP(
    clk => clk,
    dig => dig,
    seg => seg,
    sel => sel
  ); 

  dig <= TAB(P10S)&TAB(PS);

  leddrv <= CONV_STD_LOGIC_VECTOR(P100MS,4)&CONV_STD_LOGIC_VECTOR(P10MS,4);

  PROCESS(clk)
    VARIABLE cnt : INTEGER RANGE 0 TO 499999 :=0;
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      IF cnt=499999 THEN
        cnt := 0;
        click <= '1';
      ELSE
        cnt := cnt+1;
        click <= '0';
      END IF;
    END IF;
  END PROCESS;

  PROCESS(clk)
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      IF click='1' THEN
        s0Last <= s0;
        s1Last <= s1;
        keyPress <= ((NOT s0Last) AND s0) OR ((NOT s1Last) AND s1);
      END IF;
    END IF;
  END PROCESS;


  PROCESS(clk)
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      IF click='1' THEN
        CASE mState IS
          WHEN READY =>
            IF keyPress='1' THEN 
              mState <= RUN;
            END IF;
          WHEN RUN =>
            IF keyPress='1' THEN
              mState <= CHECK;
            END IF;
          WHEN CHECK =>
            IF keyPress='1' THEN
              mState <= READY;
            END IF;        
          WHEN OTHERS => NULL;
        END CASE;
      END IF;
    END IF;
  END PROCESS;

  PROCESS(clk)
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      IF click='1' THEN
        CASE mState IS
          WHEN RUN =>
            IF P10MS=9 THEN
              P10MS <= 0;
            ELSE
              P10MS <= P10MS+1;  
            END IF;
          WHEN CHECK =>
            IF keyPress='1' THEN
              P10MS <= 0;
            END IF;
          WHEN OTHERS => NULL;
        END CASE;
      END IF;
    END IF;
  END PROCESS;

  CP10MS <= '1' WHEN P10MS=9 ELSE
            '0';
  
  PROCESS(clk)
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      IF click='1' THEN
        CASE mState IS
          WHEN RUN =>
            IF CP10MS='1' THEN
              IF P100MS=9 THEN
                P100MS <= 0;
              ELSE
                P100MS <= P100MS+1;
              END IF;  
            END IF;
          WHEN CHECK =>
            IF keyPress='1' THEN
              P100MS <= 0;
            END IF;
          WHEN OTHERS => NULL;
        END CASE;
      END IF;
    END IF;
  END PROCESS;

  CP100MS <= '1' WHEN P100MS=9 AND P10MS=9 ELSE
            '0';

  PROCESS(clk)
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      IF click='1' THEN
        CASE mState IS
          WHEN RUN =>
            IF CP100MS='1' THEN
              IF PS=9 THEN
                PS <= 0;
              ELSE
                PS <= PS+1;
              END IF;  
            END IF;
          WHEN CHECK =>
            IF keyPress='1' THEN
              PS <= 0;
            END IF;
          WHEN OTHERS => NULL;
        END CASE;
      END IF;
    END IF;
  END PROCESS;

  CPS <= '1' WHEN PS=9 AND P100MS=9 AND P10MS=9 ELSE
            '0';

  PROCESS(clk)
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      IF click='1' THEN
        CASE mState IS
          WHEN RUN =>
            IF CPS='1' THEN
              IF P10S=9 THEN
                P10S <= 0;
              ELSE
                P10S <= P10S+1;
              END IF;  
            END IF;
          WHEN CHECK =>
            IF keyPress='1' THEN
              P10S <= 0;
            END IF;
          WHEN OTHERS => NULL;
        END CASE;
      END IF;
    END IF;
  END PROCESS;

END maxii_timer;

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY digdrv IS
  PORT(
    clk   : IN STD_LOGIC;
    dig   : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
    seg   : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
    sel   : OUT STD_LOGIC_VECTOR(1 DOWNTO 0)
  );
END digdrv;

ARCHITECTURE digdrv OF digdrv IS
  SIGNAL cnt : STD_LOGIC_VECTOR(15 DOWNTO 0);
BEGIN

  PROCESS(clk)
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      cnt <= cnt + 1;
    END IF;
  END PROCESS;

  PROCESS(cnt)
  BEGIN
    CASE cnt(15 DOWNTO 12) IS
      WHEN "0000" => sel <= "00";
      WHEN "0001" => sel <= "01";
      WHEN "0010" => sel <= "01";
      WHEN "0011" => sel <= "01";
      WHEN "0100" => sel <= "01";
      WHEN "0101" => sel <= "01";
      WHEN "0110" => sel <= "01";
      WHEN "0111" => sel <= "00";
      WHEN "1000" => sel <= "00";
      WHEN "1001" => sel <= "10";
      WHEN "1010" => sel <= "10";
      WHEN "1011" => sel <= "10";
      WHEN "1100" => sel <= "10";
      WHEN "1101" => sel <= "10";
      WHEN "1110" => sel <= "10";
      WHEN "1111" => sel <= "00";
    END CASE; 
  END PROCESS;

  WITH cnt(15) SELECT
    seg <= dig(7 DOWNTO 0)  WHEN '0',
           dig(15 DOWNTO 8) WHEN '1'; 

END digdrv;
          




管理员信箱: stonewayqi@hotmail.com

欣 欣 学 习 网

粤ICP备2023138008号