FPGA|CPLD|ASIC论坛
直播中

李娟

7年用户 1340经验值
私信 关注
[经验]

FPGA如何结合EPP(增强并行口)

(1)什么是EPP?

EPP是IEEE 1284标准(并行口标准)下的一个接口,该标准下还有SPP和ECP,但是EPP结合了两者的优势——速度和简便。

EPP的主要特性有:
1.在一个并行口上提供双相连接。
2.不存在数据溢出,你可以发送1byte或100万byte,只要在PC上使用一个软件循环就行。

EPP支持“地址”和“数据”的传输。
换句话说,PC可以发送4种EPP的传输指令:
1.写地址
2.读地址
3.写数据
4.读数据

我们此处将把FPGA和EPP接口连接起来。当PC“写地址”(或是“写数据”)的时候,他会发送8bit的数据给FPGA,并指示出这是“地址”或“数据”。FPGA能对这些“地址”或“数据”为所欲为。FPGA可以实现一个寄存器组(包含256个寄存器),或是用“地址”来使LED闪烁,用“数据”来发出声音等。而PC是无法分辨的。

读取也是一样,FPGA会像PC传输任意8bit数据。

(2)软件
EPP的软件支持非常简单。我们接下来看一下。

BIOS
首先进入PC的BIOS设置并开启EPP

并行口地址
从软件角度来看,EPP的传输需要IO的读取和写入。
最常用的EPP地址是0x378。你可以在windows的控制面板中找到。
1.png

C写的函数
首先是EPP_init()函数。(初始化)
  1. #define EPP_port_addr 0x378        // 你的并行口地址

  2. void EPP_init()
  3. {
  4.         IO_WRITE(EPP_port_addr+2, 0x04);
  5. }
很简单吧。
事实上,如果你的编译器不提供IO函数的话,你可能得自己写。
  1. void IO_WRITE(WORD addr, BYTE data)
  2. {
  3.         _asm
  4.         {
  5.                 mov dx, addr
  6.                 mov al, data
  7.                 out dx, al
  8.         }        
  9. }

  10. BYTE IO_READ(WORD addr)
  11. {
  12.         _asm
  13.         {
  14.                 mov dx, addr
  15.                 in al, dx
  16.         }
  17. }
现在我们看到EPP支持了4种传输。我们来为其中的每个都写一个函数。
  1. void EPP_write_addr(BYTE address)
  2. {
  3.         IO_WRITE(EPP_port_addr+3, address);
  4. }

  5. void EPP_write_data(BYTE data)
  6. {
  7.         IO_WRITE(EPP_port_addr+4, data);
  8. }

  9. BYTE EPP_read_addr()
  10. {
  11.         return IO_READ(EPP_port_addr+3);
  12. }

  13. BYTE EPP_read_data()
  14. {
  15.         return IO_READ(EPP_port_addr+4);
  16. }

这就是全部内容了。
EPP软件可以处理所有EPP的协议细节,所以软件上不要花多大的心思。

(3)硬件协议
以下是PC上的DB25打印接口。
2.png
其中的2到9引脚为8bit数据的传输通道。在EPP模式下,这个8bit通道是双向的。
其他比较重要的引脚有。
17 地址选通 PC到FPGA 低电平有效 地址传输
14 数据选通 PC到FPGA 低电平有效 数据传输
11 等待 FPGA到PC 低电平有效 响应选通
1 写入 PC到FPGA 低电平有效 0位写入传输,1位读取传输

你会发现一共有2个“选通”信号加上一个“等待”信号。其中的“选通”信号来源于PC,而“等待”信号则是传输进PC的。

其原理是这样的:每次传输中,PC都会插入一种选通,然后FPGA以等待信号响应。

我们选一个选通信号(一次只有一个有效),然后看看EPP的传输吧。
3.png

原理解释:
1.PC想要发起传输。它会插入某个选通信号。如果该传输为写入,那么“写入”信号为低电平,然后驱动8bit通道。不然的话“写入”信号为高电平,而8bit通道悬空。

2.FPGA检测到其中搞得一个选通信号,并以“等待”信号响应,解除有效信号。如果该传输为读取,那么FPGA才开始驱动8bit通道。

3.PC发现等待信号在解除有效信号,所以它会解除选通有效信号。如果传输为写入的话,那么PC会停止驱动8bit通道。

4.FPGA检测到选通信号被解除有效状态,就再度插入“等待信号”。如果传输为读取的话,那么FPGA就停止驱动8bit通道。

这些都是在硬件上实现的;PC软件除了开始传输外不会参与这个过程。

(4)HDL程序
我们来看一下在FPGA中实现EPP有多容易。首先我们创建几个来自并行口的信号。我们使得这些信号都是高电平有效。
  1. wire EPP_write = ~PP[1];
  2. wire EPP_addr_strobe = ~PP[17];
  3. wire EPP_data_strobe = ~PP[14];
  4. wire [7:0] EPP_datain = PP[9:2];

  5. // now for the EPP inputs
  6. wire EPP_wait;                        assign PP[11] = EPP_wait;
  7. wire [7:0] EPP_dataout;                assign PP[9:2] = EPP_dataout;
如今大部分的FPGA设计都使用自己的时钟。所以我们将自己的时钟命名为“clk”并将选通信号与其同步。
  1. wire EPP_strobe = EPP_data_strobe | EPP_addr_strobe;
  2. reg [2:0] EPP_strobe_reg;
  3. always @(posedge clk) EPP_strobe_reg <= {EPP_strobe_reg[1:0], EPP_strobe};

  4. wire EPP_strobe_edge1 = (EPP_strobe_reg[2:1]==2'b01);
  5. wire EPP_strobe_edge2 = (EPP_strobe_reg[2:1]==2'b10);

  6. assign EPP_wait = EPP_strobe_reg[1];
现在我们可以处理EPP的写入了。我们来讲一些收到的值存入寄存器中。
  1. reg [7:0] addr_reg, data_reg;
  2. always @(posedge clk) if(EPP_strobe_edge1 & EPP_write & EPP_addr_strobe) addr_reg <= EPP_datain;
  3. always @(posedge clk) if(EPP_strobe_edge1 & EPP_write & EPP_data_strobe) data_reg <= EPP_datain;
然后再使用EPP读取,看下寄存器里存储的数据。
  1. wire EPP_read = ~EPP_write;
  2. wire [7:0] EPP_data_mux = EPP_addr_strobe ? addr_reg : data_reg;
  3. assign EPP_dataout = (EPP_read & EPP_wait) ? EPP_data_mux : 8'hZZ;


以上就是FPGA与EPP连接的全部内容了。

回帖(1)

必过源码

2019-8-6 20:16:32
在Altera FPGA中实现epp模式的并口通信程序
在Altera FPGA中实现epp模式的并口通信程序.rar (915.22 KB)
(下载次数: 2, 2019-8-6 20:17 上传)

举报

更多回帖

发帖
×
20
完善资料,
赚取积分