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

UART通信程序


注:

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

实现一个波特率为115200bps的UART接口,通过该接口与PC机通信。由于拔码开关预设待发数据,按S1按键,发送给PC机;由PC机发来的数据显示在数码管上。LD1表示RI标志,LD2表示TI标志,按S2键可清除RI标志。

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_uart IS
  PORT(
    clk     : IN STD_LOGIC;
    s0      : IN STD_LOGIC;
    s1      : IN STD_LOGIC;
    sw      : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
    seg     : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
    sel     : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    txd     : OUT STD_LOGIC;
    rxd     : IN STD_LOGIC;
    ti      : OUT STD_LOGIC;
    ri      : OUT STD_LOGIC    
  );
END maxii_uart;

ARCHITECTURE maxii_uart OF maxii_uart IS

  COMPONENT uart
    PORT(
      clk   : IN STD_LOGIC;
      txd   : OUT STD_LOGIC;
      rxd   : IN STD_LOGIC;
      di    : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
      do    : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
      ttgr  : IN STD_LOGIC;
      ri    : OUT STD_LOGIC;
      ti    : OUT STD_LOGIC;
      cri   : IN STD_LOGIC    
    );
  END COMPONENT;

  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 do : STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL ttgr : STD_LOGIC;
  SIGNAL click : STD_LOGIC;

BEGIN

  u1:uart
  PORT MAP(
    clk => clk,
    txd => txd,
    rxd => rxd,
    di => sw,
    do => do,
    ttgr => ttgr,
    ri => ri,
    ti => ti,
    cri => s1
  );

  u2: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
        ttgr <= s0;
      END IF;
    END IF;
  END PROCESS;

  dig <= TAB(CONV_INTEGER(do(7 DOWNTO 4)))&TAB(CONV_INTEGER(do(3 DOWNTO 0)));
  
END maxii_uart;


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

ENTITY uart IS
  PORT(
    clk   : IN STD_LOGIC;
    txd   : OUT STD_LOGIC;
    rxd   : IN STD_LOGIC;
    di    : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
    do    : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
    ttgr  : IN STD_LOGIC;
    ri    : OUT STD_LOGIC;
    ti    : OUT STD_LOGIC;
    cri   : IN STD_LOGIC    
  );
END uart;

ARCHITECTURE uart OF Uart IS

  SIGNAL div : INTEGER := 0;
  SIGNAL rbuf : STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL rip : STD_LOGIC;

BEGIN

  PROCESS(clk)
  BEGIN
    IF clk'EVENT AND clk = '1' THEN
      IF div = 19 THEN
        div <= 0;
      ELSE
        div <= div + 1;
      END IF;
    END IF;
  END PROCESS;

  PROCESS(clk)
  BEGIN
    IF clk'EVENT AND clk = '1' THEN
      IF rip = '1' THEN
        ri <= '1';
      ELSIF cri = '1' THEN
        ri <= '0';
      END IF;
    END IF;
  END PROCESS;

  PROCESS(clk)

    VARIABLE rstate : INTEGER RANGE 0 TO 15 := 0;
    VARIABLE rcnt : INTEGER RANGE 0 TO 1024 := 0;
    VARIABLE rshift : STD_LOGIC_VECTOR(7 DOWNTO 0);

  BEGIN
    IF clk'EVENT AND clk = '1' THEN
      rcnt := rcnt + 1;
      CASE rstate IS
        WHEN 0 => 
          IF rxd = '0' THEN
            rcnt := 0;
            rstate := 1;
          END IF;
        WHEN 1 =>
          IF rcnt = 651 THEN
            rshift(7) := rxd;
            rcnt := 0;
            rstate := 2;
          END IF;
        WHEN 2 TO 8 =>
          IF rcnt = 434 THEN
            rshift := rxd & rshift(7 DOWNTO 1);
            rcnt := 0;
            rstate := rstate + 1;
          END IF;
        WHEN 9 =>
          IF rcnt = 434 THEN
            do <= rshift;
            rip <= '1';
            rstate := 10; 
          END IF;
        WHEN OTHERS => 
          rip <= '0';           
          rstate := 0;
      END CASE; 
    END IF;
  END PROCESS;

  PROCESS(clk)
  
    VARIABLE tstate : INTEGER RANGE 0 TO 15 := 0;
    VARIABLE tcnt : INTEGER RANGE 0 TO 511 := 0;
    VARIABLE tshift : STD_LOGIC_VECTOR(7 DOWNTO 0);

  BEGIN
    IF clk'EVENT AND clk = '1' THEN
      tcnt := tcnt + 1;
      CASE tstate IS
        WHEN 0 =>
          IF ttgr = '1' THEN
             tstate := 1; 
          END IF;
        WHEN 1 =>
          IF ttgr = '0' THEN
            ti <= '0';
            txd <= '0';
            tshift := di;
            tcnt := 0;
            tstate := 2;
          END IF;
        WHEN 2 TO 9 =>
          IF tcnt = 434 THEN
            txd <= tshift(0);
            tshift := '0' & tshift(7 DOWNTO 1);
            tcnt := 0;
            tstate := tstate + 1;
          END IF;
        WHEN 10 =>
          IF tcnt = 434 THEN
            txd <= '1';
            tcnt := 0;
            tstate := 11;
          END IF;
        WHEN 11 =>
          IF tcnt = 434 THEN
            ti <= '1';
            tstate := 0;
          END IF;
        WHEN OTHERS =>
          tstate := 0;
      END CASE;
    END IF;
  END PROCESS;

END uart;



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号