老怪甲 发表于 2010-5-25 13:42:32

并口通讯代码(调试通过)

并口通讯代码(调试通过)

--该代码目前只能实现单个字节的收发
--从开发板向主机发送数据的时候,需要把--OE <= &#39;1&#39;变成OE <= &#39;1&#39;
--接受主机数据的时候,保持如下代码即可
--具体情况还要根据需要修改如下代码
--望高手指正
library ieee;
use ieee.std_logic_1164.all;
USE IEEE.Std_Logic_Unsigned.ALL;
USE IEEE.Std_Logic_Arith.ALL;

ENTITY MCU IS
PORT
(
nDataStrobe : IN Std_Logic;            --为低,表示数据传输
nAddrStrobe : IN Std_Logic;            --为低,表示地址传输
nWri    : IN Std_Logic;            --低:写;高:读
nReset   : IN Std_Logic;            --低:复位,上位机发的复位信号
Data    : INOUT Std_Logic_Vector(7 DOWNTO 0); --数据线
nWait    : OUT Std_Logic;            --低:等待(nWait)
nAck    : OUT Std_Logic;            --低:中断
SysClk   : in Std_Logic;
Reset    : in Std_Logic;            --系统复位
Led   : out std_logic_vector(3 downto 0)
);
END MCU;

ARCHITECTURE Action OF MCU IS

component lpmramdq IS
    PORT
    (
      address      : IN STD_LOGIC_VECTOR (4 DOWNTO 0);
      clock      : IN STD_LOGIC ;
      data      : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
      wren      : IN STD_LOGIC ;
      q      : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
    );
END component;

signal Rst : std_logic;
signal OE : std_logic;
signal SelIn : std_logic_vector(1 downto 0);
signal nDataStrobeLatch,nAddrStrobeLatch,nWriLatch,nResetLatch : std_logic;
signal RegDataTempIn : std_logic_vector(7 downto 0);
signal RegAddrTempIn : std_logic_vector(7 downto 0);
signal RegDataTempOut : std_logic_vector(7 downto 0);
signal RegAddrTempOut : std_logic_vector(7 downto 0);
signal wrDataClk : std_logic;
signal wrAddrClk : std_logic;
signal DataOutLatch: std_logic_vector(7 downto 0);

begin
--Rst <= Reset and nResetLatch;
Rst <= Reset;
process(Rst,SysClk)
begin
if Rst = &#39;0&#39; then
    OE <= &#39;0&#39;;
    SelIn <= "11";
    nWait <= &#39;0&#39;;      
elsif rising_edge(SysClk) then
    if (nWriLatch = &#39;0&#39; and nDataStrobeLatch = &#39;0&#39;) then-- data write:epp-->board
      OE <= &#39;0&#39;;
      SelIn <= "11";
      nWait <= &#39;1&#39;;
      Led <= "0001";
    elsif (nWriLatch = &#39;1&#39; and nDataStrobeLatch = &#39;0&#39;) then -- data read:board-->epp
      --OE <= &#39;1&#39;;
      SelIn <= "10";
      nWait <= &#39;1&#39;;
      Led <= "0010";
    elsif (nWriLatch = &#39;0&#39; and nAddrStrobeLatch = &#39;0&#39;) then -- addr write:epp-->board
      OE <= &#39;0&#39;;
      SelIn <= "11";
      nWait <= &#39;1&#39;;
      Led <= "0100";      
    elsif (nWriLatch = &#39;1&#39; and nAddrStrobeLatch = &#39;0&#39;) then -- addr read:board-->epp
      --OE <= &#39;1&#39;;
      SelIn <= "01";
      nWait <= &#39;1&#39;;
      Led <= "1000";
    else
      OE <= &#39;0&#39;;
      SelIn <= "11";
      nWait <= &#39;0&#39;;
      Led <= "1111";
    end if;
end if;
end process;

-- Creates the flipflops to latch ds_n_latch, as_n_latch, write_n_latch, reset_n_latch
process(SysClk, Rst)
begin
if Rst = &#39;0&#39; then   
    nDataStrobeLatch <= &#39;1&#39;;
    nAddrStrobeLatch <= &#39;1&#39;;   
    nWriLatch    <= &#39;1&#39;;
    nResetLatch   <= &#39;1&#39;;                  
elsif rising_edge (SysClk) then
    nDataStrobeLatch <= nDataStrobe;
    nAddrStrobeLatch <= nAddrStrobe;
    nWriLatch    <= nWri;
    nResetLatch   <= nReset;
end if;
end process;                        

-- Generating WrDataClk, WrAddrClk for an external device
process(SysClk, Rst)
begin
if Rst = &#39;0&#39; then
    wrDataClk <= &#39;1&#39;;
    wrAddrClk <= &#39;1&#39;;
elsif rising_edge (SysClk) then
    wrDataClk <= nDataStrobeLatch or nWriLatch;
    wrAddrClk <= nAddrStrobeLatch or nWriLatch;
end if;
end process;

-- Creates the flipflops to latch data at data out
process(SysClk, Rst) --epp-->board
begin
if Rst =&#39;0&#39; then
    RegDataTempIn <= "00000000"; -- reset data out
elsif rising_edge (SysClk) THEN
    if wrDataClk =&#39;0&#39; THEN
      RegDataTempIn <= DataOutLatch;
    else
    end if;
end if;
end process;

-- Creates the flipflops to latch address at address out
process(SysClk, Rst) --epp-->board
begin
if Rst =&#39;0&#39; then
    RegAddrTempIn <= "00000000"; -- reset addr out
elsif rising_edge (SysClk) then
    if wrAddrClk =&#39;0&#39; then
      RegAddrTempIn <= DataOutLatch;
    else
    end if;
end if;
end process;
   
-- Behavioral representation of tri-states.
process (OE, SelIn, Data)--, RegDataTempOut)
begin
if ( OE = &#39;0&#39;) then
    Data <= "ZZZZZZZZ"; -- Bidir_data use like input
    DataOutLatch <= Data; -- parralel port write to external device;epp-->board
else
    case SelIn is
      when "10" => Data <= "10101010"; -- board-->epp
      when "01" => Data <= "00001111"; -- board-->epp
      when others => Data <= (OTHERS => &#39;0&#39;);
    end case;
end if;
end process;
   
u1:lpmramdq port map
(
      address    => "00010",
      clock    => SysClk,
      data    => Data,
      wren    => &#39;1&#39;,
      q      => RegDataTempIn   
);

end Action;

Sunlife 发表于 2015-4-7 11:46:36

       很实用的东西
页: [1]
查看完整版本: 并口通讯代码(调试通过)