并口即个人电脑并行接口是从简单的打印机接口发展而来。早期的并口是单向口,它只是简单的把数据 从计算机传送到打印机。随着双向并口的出现,并口的用途也越来越广泛。相较于串口它有传输快、可靠 性高,编程简单的特点。在近距离通信方面正在逐步取代串口。
由于双向并口是各制造商独自设计没有一个统一的规范。逐渐形成了如下的并口模式: 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 
|