パソコンとのパラレル通信接続  


【パソコンと接続】

PICとパソコンを接続して通信が出来るようになれば、いろいろな
応用範囲が考えられ、楽しさも倍増します。
ここでは、パソコンとプリンタインターフェースにより接続する方法
を説明します。
この送受信には
ハンドシェイク通信方式という方法もありますが、
ここではもう少し簡単な方法を使っています。

【プリンタインターフェース接続】

パソコンのプリンタインターフェースは、DOS/V機の場合、パラレル
の双方向通信が出来るようになっています。(最近のPC98xxNXも)
そこで、このプリンタインターフェースを使って8ビットパラレルでPIC
と双方向通信をする方法を説明します。


まずパソコン側のプリンタインターフェースの詳細については、別の
ハンドシェイクのプリンタインターフェースに詳細があるのでそちらを
参照して下さい。
ここで注意が必要なことは、STROBEとBUSYの論理反転に関する
ことで、

  パソコン側はSTROBEは正論理で出力され、BUSYは負論理
  で入力されるが、PIC側の信号はいずれも正論理でそのまま
  入出力される。

ということです。

従って、下図の様にPICとパソコンを接続した時には、この論理の
正負を意識して考えなければなりません。


【信号とタイミング】

上記接続での信号のタイミングは下図のようにします。
パソコンからデータを送信するときには、8ビットデータをまず出力
してから、STROBE信号を「1」にします。
そして、PIC側からのBUSY信号(PICのSTROBE出力)を待ち、BUSY
がもとに戻ったらSTOROBEも「0」に戻して完了し、次のデータに移り
ます。




パソコンが受信するときには、PICからのBUSY信号(PICのSTROBE
出力)を先に待ちます。
そして、BUSYを受け付けたら、STROBEを「1」にしてからデータを入力
し、続いてSTROBEを「0」に戻します。そしてPIC側からのBUSYが元に
戻ったのを確認して完了です。


【パソコン側プログラム】

パソコン側のパラレル入出力のプログラムは直接入出力命令を実行
するため、Visual C++を使ってDynamic Link Library(DLL)形式とします。
このDLLプログラムのつかり方の詳細は、「
DLLプログラムの作り方
のページを参照して下さい。

プログラムは上記タイムチャートをそのままフローにした形になって
います。


/*************************************************
* Parallel Interface Drive Program.
* This Driver includes below function by Dynamic Link
* Library(DLL) Program.
* 1. RecvD  Input one Byte data by handshake protocol
* 2. SendD  Output one Byte data by handshake protocol
***************************************************/

#define DllExport _declspec(dllexport)    //DLL宣言
#define NOERR 0
#define BUSY -1

//Input Function by Handshake Protocol (RecvD)
DllExport short _stdcall RecvD(unsigned short port)
{unsigned databyte; unsigned state_busy;
  while(state_busy !=0) {      //STROBE待ち
    state_busy = _inp(port+1) & 0x80;
  }
  
  _outp(port+2,0x21);        //ビジー出力,入力モード
  databyte = _inp(port);      //データ入力(Dumy)
  databyte = _inp(port);      //データ入力
  _outp(port+2,0);         //ビジー解除、出力モード
   
  while(state_busy ==0) {      //STROBE reset待ち
    state_busy = _inp(port+1) & 0x80;
  }
  return databyte;         //入力データ返し
}


//Output Function by HandShake Protocol (SendD)
DllExport short _stdcall SendD(unsigned short port, unsigned short databyte)
{unsigned state_busy; unsigned i;
  for (i=0;i<1000;i++) {      //レディー待ち
    state_busy = _inp(port+1) & 0x80;
    if (state_busy != 0){
      break;
    }
  }
  if (state_busy == 0){       //タイムアウトエラー
    return(BUSY);
  }
  _outp(port, databyte);         //データ出力
  _outp(port+2,1);            //ストローブ出力
  while(state_busy != 0) {        //ビジー待ち
    state_busy = _inp(port+1) & 0x80;
  }
  while(state_busy ==0) {         //ビジー解除待ち
    state_busy = _inp(port+1) & 0x80;
  }
  _outp(port+2,0);            //ストローブ解除
  return(NOERR);
}




【PIC側プログラム】

このパソコンと接続して通信するためのPIC側のプログラムも、上記
のフローチャートのままの流れとなっています。
送信と受信に判れていますが、基本的なことは、すべてパソコン側が
主導権をもっているということです。
つまり、パソコン側から、コマンドを受信してからしか、PIC側からは
データを送信することが出来ないということです。

(1)ポート初期化
  まずはポートの入出力の設定です。

;**************************************
; ポート初期化部分
;  PORT A RA3 :STROBE output
;      RA4 :BUSY input
;  PORT B all input/output changable
;**************************************
INITA
    BSF   STATUS,RP0   ;Set Page 1
    MOVLW  017H      ;Set PortA to receive mode
    MOVWF  TRISA
    MOVLW  0FFH
    MOVWF  TRISB      ;Set Portb to all input
    BCF   STATUS,RP0   ;Set Page 0
  このあとの処理へ


(2)受信プログラム
  パソコン側からのコマンドの受信部分で、このコマンドを受信
  してから次の処理に移り、送信することが出来ます。


;********************************
; 受信サブルーチンプログラム
; データはCMNDに格納されて戻る
;********************************
RCVSUB
    BSF   STATUS,RP0   ;Set Page 1
    MOVLW  0FFH      ;get FF
    MOVWF  TRISB      ;Set Portb to all input
    BCF   STATUS,RP0   ;Set Page 0
    BCF   PORTA,3     ;reset STROB
;***** BUSY待ち ****
RCVLP
    BTFSC  PORTA,4     ;RA4 BUSY input
    GOTO  RCVLP
    BTFSC  PORTA,4     ;確認のため再入力
    GOTO  RCVLP
    BSF   PORTA,3     ;set STROB as BUSY on
    MOVF  PORTB,W     ;get command data
    MOVWF  CMND      ;COMMAND save
    NOP           ;パルス幅の確保用
    NOP
    BCF   PORTA,3     ;reset STROB as BUSY off
    RETURN


(3)送信プログラム
  1バイトのデータをパソコンへ送信するためのプログラム
  です。


;************************************
; 1バイト送信サブルーチンプログラム
; During send mode RA3=STORBE output
; and RA4=BUSY input,PORTB is output
;************************************
SNDSUB
    MOVWF  TEMP      ;save send data
    BSF   STATUS,RP0   ;Set Page 1
    CLRF  TRISB      ;Set PORTB to all output
    BCF   STATUS,RP0   ;Set Page 0
;**** check busy ******
CKBSY
    BTFSS  PORTA,4     ;Test BUSY
    GOTO  CKBSY      ;busy case
;*** Send data ***
    MOVF  TEMP,W     ;get send data
    MOVWF  PORTB      ;data out
    NOP           ;delay
    BSF   PORTA,3     ;set STROB
;**** wait PC input ****
WTBSY
    BTFSC  PORTA,4     ;wait BUSY on
    GOTO  WTBSY

WTRDY
    BTFSS  PORTA,4     ;wait BUSY off
    GOTO  WTRDY
    BCF   PORTA,3     ;reset STROB
    RETURN





    目次ページへ