欣欣学习网,老工程师带你学习单片机技术,欢迎来坐坐。
首  页 | 学习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 实验板

PWM控制LED灯亮度程序


注:

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

通过PWM来控制实验板上的8个LED灯的亮度。按下S1键,LED灯的亮度逐渐增加;按下S0键,LED灯的亮度逐渐减弱。数码管上的16进制数表示亮度等级。

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_pwm IS
  PORT(
    clk     : IN STD_LOGIC;
    s0      : IN STD_LOGIC;
    s1      : IN STD_LOGIC;
    seg     : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
    sel     : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    leddrv  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
  );
END maxii_pwm;

ARCHITECTURE maxii_pwm OF maxii_pwm 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;

  SIGNAL click : STD_LOGIC;
  SIGNAL dig : STD_LOGIC_VECTOR(15 DOWNTO 0);
  SIGNAL regCmp : INTEGER RANGE 0 TO 255 :=0;
  SIGNAL regCnt : INTEGER RANGE 0 TO 255 :=0;
  SIGNAL pwmOut : STD_LOGIC;

  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")); 


BEGIN

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

  PROCESS(clk)
    VARIABLE cnt : INTEGER RANGE 0 TO 4999999 :=0;
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      IF cnt=4999999 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
        IF s0='1' THEN
          regCmp <= regCmp+1;
        ELSIF s1='1' THEN
          regCmp <= regCmp-1;
        ELSE
          regCmp <= regCmp;
        END IF;
      END IF;
    END IF;
  END PROCESS;

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

  pwmOut <= '1' WHEN regCnt <= regCmp ELSE
            '0';

  leddrv <= pwmOut&pwmOut&pwmOut&pwmOut&pwmOut&pwmOut&pwmOut&pwmOut;

  dig <= TAB(regCmp/16)&TAB(regCmp MOD 16);
  
END maxii_pwm;


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号