2.14.3 傳送與接收
PLC 可使用 SerialLinkSend 與 SerialLinkRecv 兩個握手的數據結構與 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;
}
}
...
}