並口與程式設計 (轉)

gugu99發表於2008-01-09
並口與程式設計 (轉)[@more@]

  並口即個人並行介面是從簡單的印表機介面發展而來。早期的並口是單向口,它只是簡單的把資料
從傳送到印表機。隨著雙向並口的出現,並口的用途也越來越廣泛。相較於串列埠它有傳輸快、可靠
性高,簡單的特點。在近距離通訊方面正在逐步取代串列埠。

  由於雙向並口是各製造商獨自設計沒有一個統一的規範。逐漸形成了如下的並口:
  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包括,,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 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-996960/,如需轉載,請註明出處,否則將追究法律責任。

相關文章