2.14.3 傳送與接收


PLC 可使用 SerialLinkSendSerialLinkRecv 兩個握手的數據結構與 NC 溝通,完成透過 INCON-M84/M86/M86R 的 RS485 連接器與外界裝置溝通的動作。


  • PLC 傳送接收的握手資料結構如下:

length 為長度,buffer 為資料暫存區,finish 為溝通完成的 flag

struct SerialLinkHandShake {

 int length;

 unsigned char buffer[SERIALLINK_BUFFER_LENGTH];

 int finish;

};


  • 就傳送(Transmit)而言,PLC 必須準備好 buffer[ ] 內的資料字元,寫入 length 要傳送的字數,NC 即開始傳送資料出去。直到全部字元都傳送完畢後,NC 會將 finish 設成 1,PLC 知道傳送完畢後,將 length 設成 0,完成整個傳送的握手動作,範例如下 PLC 程式:

下例 M68 規劃為傳送資料的 M 碼。

void plcRun(Status &sts, PlcBlock &plc)

{

 ....


 if( plc.mCode.flag ) {

   switch( plc.mCode.data ) {

     case 68:

       // length is none zero and finish is 1 were true (send finish)

       if( plc.serialLinkSend->length && plc.serialLinkSend->finish ) {

         plc.serialLinkSend->length = 0;

         plc.mCode.finish = 1;

       } else if( plc.serialLinkSend->length == 0 ) { // length is zero send data

         plc.serialLinkSend->buffer[0] = 'T';

         plc.serialLinkSend->buffer[1] = 'e';

         plc.serialLinkSend->buffer[2] = 's';

         plc.serialLinkSend->buffer[3] = 't';

         plc.serialLinkSend->buffer[4] = '\r';

         plc.serialLinkSend->buffer[5] = '\n';

         plc.serialLinkSend->length = 6;

       }

       break;

   }

 }


 ...

}


  • 就接收(Receive)而言,當外部裝置傳送字元進來,NC 會將字元寫入 buffer[ ] 內,並將 length 寫入已傳送的字元數,PLC 可將字元讀入,並將 finish 設成 1,表示完成讀入的動作。另外,PLC 可檢視 buffer[ ] 內的資料,不先將 finish 設成 1,NC 會將後續的資料繼續送入 buffer[ ] 內,更新 length 的數字,PLC 可視需要將 finish 設成 1,但要注意 buffer[ ] 所能容納字元最多為 256 個。範例如下 PLC 程式:

static char *strCopy( char *Dest, char *Source, int MaxLen )

{

 int i;

 for( i=0; i<MaxLen; i++ ) {

   Dest[i] = Source[i];

   if( !Dest[i] )

     return Dest;

 }

 Dest[i+1] = 0;

 return Dest;

}


static char serialLinkMsg[SERIALLINK_BUFFER_LENGTH+1];


void plcRun(Status &sts, PlcBlock &plc)

{

 ...


 if( plc.serialLinkRecv ) {  // check if function available

   if( plc.serialLinkRecv->length ) {

     if( plc.serialLinkRecv->length == SERIALLINK_BUFFER_LENGTH ) { // receive length equal buffer length.

       strCopy( serialLinkMsg, plc.serialLinkRecv->buffer, SERIALLINK_BUFFER_LENGTH ); // call strCopy to serialLinkRecv.

       plc.errorMessage = serialLinkMsg;

       plc.serialLinkRecv->finish = 1;

     } else {

       int c = plc.serialLinkRecv->buffer[plc.serialLinkRecv->length-1];

       if( c == '\n' ) {       // if C is line feed, call strCopy than shows message.

         strCopy( serialLinkMsg, plc.serialLinkRecv->buffer, plc.serialLinkRecv->length );

         plc.errorMessage = serialLinkMsg;

         plc.serialLinkRecv->finish = 1;

       }

     }

   } else {

     plc.serialLinkRecv->finish = 0;

   }

 }


 ...

}