标题:
分享libnodave-0.8.5,西门子PLC通讯方法
[打印本页]
作者:
dennis22041
时间:
2018-9-6 18:01
标题:
分享libnodave-0.8.5,西门子PLC通讯方法
直接上附件。
0.png
(41.37 KB, 下载次数: 65)
下载附件
2018-9-13 04:42 上传
单片机源程序如下:
/*
Part of Libnodave, a free communication libray for Siemens S7 200/300/400 via
the MPI adapter 6ES7 972-0CA22-0XAC
or MPI adapter 6ES7 972-0CA23-0XAC
or TS adapter 6ES7 972-0CA33-0XAC
or MPI adapter 6ES7 972-0CA11-0XAC,
IBH/MHJ-NetLink or CPs 243, 343 and 443
(C) Thomas Hergenhahn (thomas.hergenhahn@web.de) 2002..2005
S5 basic communication parts (C) Andrew Rostovtsew 2004.
Libnodave is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Libnodave is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with Libnodave; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "nodave.h"
#include <stdio.h>
#include "log2.h"
#include <string.h>
#define DUMPLIMIT 11132
#define DAVE_HAVE_MEMCPY // normally we have
//#define DEBUG_CALLS // Define this and recompile to get parameters and results
// of each function call printed. I could have made this an
// option bit in daveDebug, but most applications will never,never
// need it. Still they would have to do the jumps...
// This option is just useful when developing bindings to new
// programming languages.
/**
Library specific:
**/
#ifdef LINUX
#define HAVE_UNISTD
#define HAVE_SELECT
#define DECL2
#include <time.h>
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD
#include <unistd.h>
#define daveWriteFile(a,b,c,d) d=write(a,b,c)
#endif
#ifdef AVR
#include <unistd.h>
#endif
int daveDebug=0;
#ifdef BCCWIN
#include <winsock2.h>
#include "openS7online.h" // We can use the Siemens transport dlls only on Windows
void setTimeOut(daveInterface * di, int tmo) {
COMMTIMEOUTS cto;
#ifdef DEBUG_CALLS
LOG3("setTimeOut(di:%p, time:%d)\n", di,tmo);
FLUSH;
#endif
// if(di->fd.connectionType==daveSerialConnection) {
GetCommTimeouts(di->fd.rfd, &cto);
cto.ReadIntervalTimeout=0;
cto.ReadTotalTimeoutMultiplier=0;
cto.ReadTotalTimeoutConstant=tmo/1000;
SetCommTimeouts(di->fd.rfd,&cto);
// } else if(di->fd.connectionType==daveTcpConnection) {
// }
}
#endif
#ifdef HAVE_SELECT
int DECL2 stdwrite(daveInterface * di, char * buffer, int length) {
if (daveDebug & daveDebugByte)
_daveDump("I send", (uc*)buffer, length);
return write(di->fd.wfd, buffer,length);
}
int DECL2 stdread(daveInterface * di, char * buffer, int length) {
fd_set FDS;
struct timeval t;
int i;
t.tv_sec = di->timeout / 1000000;
t.tv_usec = (di->timeout % 1000000);
FD_ZERO(&FDS);
FD_SET(di->fd.rfd, &FDS);
i=0;
if(select(di->fd.rfd + 1, &FDS, NULL, NULL, &t)>0) {
i=read(di->fd.rfd, buffer, length);
}
// if (daveDebug & daveDebugByte)
// _daveDump("got",buffer,i);
return i;
}
#endif
#ifdef BCCWIN
int DECL2 stdread(daveInterface * di,
char * buffer,
int length) {
unsigned long i;
ReadFile(di->fd.rfd, buffer, length, &i, NULL);
// if (daveDebug & daveDebugByte)
// _daveDump("got",buffer,i);
return i;
}
int DECL2 stdwrite(daveInterface * di, char * buffer, int length) {
unsigned long i;
if (daveDebug & daveDebugByte)
_daveDump("I send",buffer,length);
// EscapeCommFunction(di->fd.rfd, CLRRTS); // patch from Keith Harris. He says:
//******* this is what microwin does (needed for usb-serial)
WriteFile(di->fd.rfd, buffer, length, &i,NULL);
// patch from Andrea. He says:
// In this way the PC Adapter connected to CPU313C hangs waiting for RTS line before answering back.
// Added the following to regain answers:
// EscapeCommFunction(di->fd.rfd, SETRTS);
return i;
}
#endif
/*
Setup a new interface structure from an initialized serial interface's handle and a name.
*/
daveInterface * DECL2 daveNewInterface(_daveOSserialType nfd, char * nname, int localMPI, int protocol, int speed){
daveInterface * di=(daveInterface *) calloc(1, sizeof(daveInterface));
#ifdef DEBUG_CALLS
LOG7("daveNewInterface(fd.rfd:%d fd.wfd:%d name:%s local MPI:%d protocol:%d PB speed:%d)\n",
nfd.rfd,nfd.wfd,nname, localMPI, protocol, speed);
FLUSH;
#endif
if (di) {
// di->name=nname;
strncpy(di->realName,nname,20);
di->name=di->realName;
di->fd=nfd;
di->localMPI=localMPI;
di->protocol=protocol;
di->timeout=1000000; /* 1 second */
di->nextConnection=0x14;
di->speed=speed;
di->getResponse=_daveGetResponseISO_TCP;
di->ifread=stdread;
di->ifwrite=stdwrite;
di->initAdapter=_daveReturnOkDummy;
di->connectPLC=_daveReturnOkDummy2;
di->disconnectPLC=_daveReturnOkDummy2;
di->disconnectAdapter=_daveReturnOkDummy;
di->listReachablePartners=_daveListReachablePartnersDummy;
switch (protocol) {
case daveProtoMPI:
di->initAdapter=_daveInitAdapterMPI1;
di->connectPLC=_daveConnectPLCMPI1;
di->disconnectPLC=_daveDisconnectPLCMPI;
di->disconnectAdapter=_daveDisconnectAdapterMPI;
di->exchange=_daveExchangeMPI;
di->sendMessage=_daveSendMessageMPI;
di->getResponse=_daveGetResponseMPI;
di->listReachablePartners=_daveListReachablePartnersMPI;
break;
case daveProtoMPI2:
case daveProtoMPI4:
di->initAdapter=_daveInitAdapterMPI2;
di->connectPLC=_daveConnectPLCMPI2;
di->disconnectPLC=_daveDisconnectPLCMPI;
di->disconnectAdapter=_daveDisconnectAdapterMPI;
di->exchange=_daveExchangeMPI;
di->sendMessage=_daveSendMessageMPI;
di->getResponse=_daveGetResponseMPI;
di->listReachablePartners=_daveListReachablePartnersMPI;
di->nextConnection=0x3;
break;
case daveProtoMPI3:
di->initAdapter=_daveInitAdapterMPI3;
di->connectPLC=_daveConnectPLCMPI3;
di->disconnectPLC=_daveDisconnectPLCMPI3;
di->disconnectAdapter=_daveDisconnectAdapterMPI3;
di->exchange=_daveExchangeMPI3;
di->sendMessage=_daveSendMessageMPI3;
di->getResponse=_daveGetResponseMPI3;
di->listReachablePartners=_daveListReachablePartnersMPI3;
di->nextConnection=0x3;
break;
case daveProtoISOTCP:
case daveProtoISOTCP243:
di->getResponse=_daveGetResponseISO_TCP;
di->connectPLC=_daveConnectPLCTCP;
di->exchange=_daveExchangeTCP;
break;
case daveProtoPPI:
di->getResponse=_daveGetResponsePPI;
di->exchange=_daveExchangePPI;
di->connectPLC=_daveConnectPLCPPI;
di->timeout=150000; /* 0.15 seconds */
break;
case daveProtoMPI_IBH:
di->exchange=_daveExchangeIBH;
di->connectPLC=_daveConnectPLC_IBH;
di->disconnectPLC=_daveDisconnectPLC_IBH;
di->sendMessage=_daveSendMessageMPI_IBH;
di->getResponse=_daveGetResponseMPI_IBH;
di->listReachablePartners=_daveListReachablePartnersMPI_IBH;
break;
case daveProtoPPI_IBH:
di->exchange=_daveExchangePPI_IBH;
di->connectPLC=_daveConnectPLCPPI;
di->sendMessage=_daveSendMessageMPI_IBH;
di->getResponse=_daveGetResponsePPI_IBH;
di->listReachablePartners=_daveListReachablePartnersMPI_IBH;
break;
case daveProtoS7online:
di->exchange=_daveExchangeS7online;
di->connectPLC=_daveConnectPLCS7online;
di->sendMessage=_daveSendMessageS7online;
di->getResponse=_daveGetResponseS7online;
di->listReachablePartners=_daveListReachablePartnersS7online;
di->disconnectPLC=_daveDisconnectPLCS7online;
// di->disconnectAdapter=_daveDisconnectAdapterS7online;
break;
case daveProtoAS511:
di->connectPLC=_daveConnectPLCAS511;
di->disconnectPLC=_daveDisconnectPLCAS511;
di->exchange=_daveFakeExchangeAS511;
di->sendMessage=_daveFakeExchangeAS511;
break;
case daveProtoNLpro:
di->initAdapter=_daveInitAdapterNLpro;
di->connectPLC=_daveConnectPLCNLpro;
di->disconnectPLC=_daveDisconnectPLCNLpro;
di->disconnectAdapter=_daveDisconnectAdapterNLpro;
di->exchange=_daveExchangeNLpro;
di->sendMessage=_daveSendMessageNLpro;
di->getResponse=_daveGetResponseNLpro;
di->listReachablePartners=_daveListReachablePartnersNLpro;
break;
}
#ifdef BCCWIN
setTimeOut(di, di->timeout);
#endif
}
return di;
}
daveInterface * DECL2 davePascalNewInterface(_daveOSserialType* nfd, char * nname, int localMPI, int protocol, int speed){
#ifdef DEBUG_CALLS
LOG7("davePascalNewInterface(fd.rfd:%d fd.wfd:%d name:%s local MPI:%d protocol:%d PB speed:%d)\n",
nfd->rfd,nfd->wfd,nname, localMPI, protocol, speed);
FLUSH;
#endif
return daveNewInterface(*nfd,nname, localMPI, protocol, speed);
}
/*
debugging:
set debug level by setting variable daveDebug. Debugging is split into
several topics. Output goes to stderr.
The file descriptor is written after the module name, so you may
distinguish messages from multiple connections.
naming: all stuff begins with dave... to avoid conflicts with other
namespaces. Things beginning with _dave.. are not intended for
public use.
*/
void DECL2 daveSetDebug(int nDebug) {
#ifdef DEBUG_CALLS
LOG2("daveSetDebug(%d)\n",nDebug);
FLUSH;
#endif
daveDebug=nDebug;
}
int DECL2 daveGetDebug() {
#ifdef DEBUG_CALLS
LOG1("daveGetDebug()\n");
FLUSH;
#endif
return daveDebug;
}
/**
C# interoperability:
**/
void DECL2 daveSetTimeout(daveInterface * di, int tmo) {
#ifdef DEBUG_CALLS
LOG3("daveSetTimeOut(di:%p, time:%d)\n", di,tmo);
#endif
di->timeout=tmo;
#ifdef BCCWIN
setTimeOut(di,tmo);
#endif
}
int DECL2 daveGetTimeout(daveInterface * di) {
#ifdef DEBUG_CALLS
LOG2("daveGetTimeOut(di:%p)\n",di);
FLUSH;
#endif
return di->timeout;
}
char * DECL2 daveGetName(daveInterface * di) {
#ifdef DEBUG_CALLS
LOG2("daveGetName(di:%p)\n",di);
FLUSH;
#endif
return di->name;
}
int DECL2 daveGetMPIAdr(daveConnection * dc) {
#ifdef DEBUG_CALLS
LOG2("daveGetMPIAdr(dc:%p)\n",dc);
FLUSH;
#endif
return dc->MPIAdr;
}
int DECL2 daveGetAnswLen(daveConnection * dc) {
#ifdef DEBUG_CALLS
LOG2("daveGetAnswLen(dc:%p)\n",dc);
FLUSH;
#endif
return dc->AnswLen;
}
int DECL2 daveGetMaxPDULen(daveConnection * dc) {
#ifdef DEBUG_CALLS
LOG2("daveGetMaxPDULen(dc:%p)\n",dc);
FLUSH;
#endif
return dc->maxPDUlength;
}
/**
PDU handling:
**/
/*
set up the header. Needs valid header pointer
*/
void DECL2 _daveInitPDUheader(PDU * p, int type) {
memset(p->header, 0, sizeof(PDUHeader));
if (type==2 || type==3)
p->hlen=12;
else
p->hlen=10;
p->param=p->header+p->hlen;
((PDUHeader*)p->header)->P=0x32;
((PDUHeader*)p->header)->type=type;
p->dlen=0;
p->plen=0;
p->udlen=0;
p->data=NULL;
p->udata=NULL;
}
/*
add parameters after header, adjust pointer to data.
needs valid header
*/
void DECL2 _daveAddParam(PDU * p,uc * param,us len) {
#ifdef DEBUG_CALLS
LOG4("_daveAddParam(PDU:%p, param %p, len:%d)\n", p, param, len);
FLUSH;
#endif
p->plen=len;
#ifdef DAVE_HAVE_MEMCPY
memcpy(p->param, param, len);
#else
int i;
for (i=0;i<len;i++) p->param[i]=param[i];
#endif
((PDUHeader2*)p->header)->plenHi=len/256;
((PDUHeader2*)p->header)->plenLo=len%256;
// ((PDUHeader*)p->header)->plen=daveSwapIed_16(len);
p->data=p->param+len;
p->dlen=0;
}
/*
add data after parameters, set dlen
needs valid header,parameters
*/
void DECL2 _daveAddData(PDU * p,void * data,int len) {
#ifdef DEBUG_CALLS
LOG4("_daveAddData(PDU:%p, data %p, len:%d)\n", p, data, len);
// _daveDumpPDU(p);
FLUSH;
#endif
uc * dn= p->data+p->dlen;
p->dlen+=len;
#ifdef DAVE_HAVE_MEMCPY
memcpy(dn, data, len);
#else
int i; uc * d=(uc*)data;
for (i=0;i<len;i++) p->data[p->dlen+i]=d[i];
#endif
((PDUHeader2*)p->header)->dlenHi=p->dlen/256;
((PDUHeader2*)p->header)->dlenLo=p->dlen%256;
// ((PDUHeader*)p->header)->dlen=daveSwapIed_16(p->dlen);
}
/*
add values after value header in data, adjust dlen and data count.
needs valid header,parameters,data,dlen
*/
void DECL2 _daveAddValue(PDU * p,void * data,int len) {
us dCount;
uc * dtype;
#ifdef DEBUG_CALLS
LOG4("_daveAddValue(PDU:%p, data %p, len:%d)\n", p, data, len);
_daveDumpPDU(p);
FLUSH;
#endif
dtype=p->data+p->dlen-4+1; /* position of first byte in the 4 byte sequence */
dCount= p->data[p->dlen-4+2+1];
dCount+= 256*p->data[p->dlen-4+2];
if (daveDebug & daveDebugPDU)
LOG2("dCount: %d\n", dCount);
if (*dtype==4) { /* bit data, length is in bits */
dCount+=8*len;
} else if (*dtype==9) { /* byte data, length is in bytes */
dCount+=len;
} else if (* dtype==3) { /* bit data, length is in bits */
dCount+=len;
} else {
if (daveDebug & daveDebugPDU)
LOG2("unknown data type/length: %d\n", *dtype);
}
if (p->udata==NULL) p->udata=p->data+4;
p->udlen+=len;
…………
…………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
libnodave-0.8.5.rar
(3.26 MB, 下载次数: 11)
2018-9-6 18:01 上传
点击文件名下载附件
西门子通讯方法
下载积分: 黑币 -5
作者:
dennis22041
时间:
2018-9-6 18:04
自己顶
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1