并口即个人电脑并行接口是从简单的打印机接口发展而来。早期的并口是单向口,它只是简单的把数据
从计算机传送到打印机。随着双向并口的出现,并口的用途也越来越广泛。相较于串口它有传输快、可靠
性高,编程简单的特点。在近距离通信方面正在逐步取代串口。
由于双向并口是各制造商独自设计没有一个统一的规范。逐渐形成了如下的并口模式:
1、原始并口SPP 单向8位+双向4位
2、简单双向PS/2 双向8位
3、增强并口EPP 高速双向
4、扩展并口ECP 高速双向可靠
5、多模式口ECP+EPP 可工作于多种模式
25针接口管脚分布图
2-9 数据 D0-D7 双向
1 选通 /STB
14 自动换行 /AFD 输出
16 初始化 INIT
17 选中 /SIN
10 应答 ACK
11 忙 /BUSY
12 页尽 PE 输入
13 联机 SLCT
15 出错 ERROR
18-25 接地 GND 回线
端口地址:
3BCH-3BEH
378H-37AH
278H-27AH
其中第一个地址是基地址,即数据寄存器,第二个是状态,第三个是命令寄存器。
EPP寄存器是基址+3到+7共附加5个寄存器,ECP是基址+400H到+402H之间的寄存器
端口位分配:
状态: D7 D6 D5 D4 D3 D2 D1 D0
- - ? IRQ SIN INIT AFD STB
命令 BUSY ACK PE SLCT ERROR - - -
注意:一些早期的并口以及现在所有的并口将"?"置1可以输入数据
访问端口:主要有直接I/O及间接I/O。其中间接I/O包括BIOS,API,VXD,控件等。
直接I/O:
unsigned char InPort(unsigned short Addr)
{
unsigned char Data
asm{
mov dx,Addr
in dx,al
mov Data,al
}
return Data;
}
void OutPort(unsigned short Addr,unsigned char Data)
{
asm{
mov dx,addr
mov al,Data
out dx,al
}
}
间接I/O在此从略。
通信握手:一般使用SIN,SLCT进行联络。
从并口输出数据:
PC检测BUSY是否忙,忙则等待。发数据,置STB,检测ACK是否响应,是则清STB否则等待。
外设检测STB是否选通,是则置BUSY否则等待。读数据,处理后发ACK清忙。
从并口输入数据:将"?"置1设为输入数据的模式。
外设检测STB是否忙,忙则等待。发数据,置ACK,检测AFD是否响应,是则清ACK否则等待。
PC检测ACK是否选通,是则置STB否则等待。读数据,处理后发AFD清忙。
以下是计算机收数据的一个类:
//---------------------------------------------------------------------------
//start Paralle.h#ifndef ParallelH
#define ParallelH
//---------------------------------------------------------------------------
class TParaComm
{
private:
short DataAddr;
short StatusAddr;
short CommandAddr;
unsigned __fastcall InPort(short Addr);
void __fastcall OutPort(unsigned char Data,short Addr);
public:
__fastcall TParaComm(int PortAddr);
void __fastcall InitComm(void);
bool __fastcall GetConect(bool Wait);
bool __fastcall ReadPort(unsigned char *Data,int Time);};
extern TParaComm *Para;
#endif
//end Paralle.h //start Paralle.cpp
#include "Paralle.h"
TParaComm *Para;
unsigned __fastcall TParaComm::InPort(short Addr)
{
unsigned char Temp; asm{
MOV DX,Addr
in AL,DX
MOV Temp,AL
}
return Temp;
}
//---------------------------------------------------------------------------
void __fastcall TParaComm::OutPort(unsigned char Data,short Addr)
{
asm{
MOV DX,Addr
MOV AL,Data
out DX,AL
}
}
//---------------------------------------------------------------------------
__fastcall TParaComm::TParaComm(int PortAddr)
{
DataAddr=PortAddr;
StatusAddr=DataAddr+1;
CommandAddr=StatusAddr+1;
}
//---------------------------------------------------------------------------
void __fastcall TParaComm::InitComm(void)
{
OutPort(0xEC,CommandAddr);
}
//---------------------------------------------------------------------------
bool __fastcall TParaComm::GetConect(bool Wait)
{
unsigned char Temp;
do
{
Temp=InPort(StatusAddr);
if(!(Temp&0x10)) return true;
}while(Wait);
return false;
}
//---------------------------------------------------------------------------
bool __fastcall TParaComm::ReadPort(unsigned char *Data,int Time)
{
extern void __fastcall Sleep(int ms);//call API
unsigned char Temp,Ch;
Temp=InPort(CommandAddr);
OutPort(Temp|0x01,CommandAddr);
do
{
Ch=InPort(StatusAddr);
if(!(Ch&0x40))
{
OutPort(Temp&0xFE,CommandAddr);
*Data=InPort(DataAddr);
return true;
}
Sleep(1);
}while(--Time!=0);
OutPort(Temp&0xFE,CommandAddr);
return false;
}
//---------------------------------------------------------------------------
//end Paralle.cpp