西门子S7200PPI协议.docx
《西门子S7200PPI协议.docx》由会员分享,可在线阅读,更多相关《西门子S7200PPI协议.docx(22页珍藏版)》请在冰豆网上搜索。
西门子S7200PPI协议
PC(上位机)与PLC串行通讯协议与串口DLL之一……西门子S7-200PPI协议
作者:
wjun7610,2008-2-2611:
15:
00发表于:
《PLC论坛》共有6人回复,312次点击 加为好友留言
西门子S7-200系列PLCPPI协议及PPI动态链接库DLL(需VB、DelphiDEMO程序请回贴并留下Emial地址)
一、西门子S7-200系列PLCPPI协议动态链接库DLL(以下简称DLL),是为满足工业通信需要,针对工业领域要求上位机对西门子S7-200系列
PLC实时采集与控制的组态编程而设计。
本DLL是采用Delphi语言开发的标准串口通讯库,具有以下特点:
1)、实时性、可靠性好,可根据通信数据量自行调整通信时间;
2)、适用于多PLC联网和上位机通信,满足多方面的需要;
3)、函数接口功能全,操作简单;
4)、附加实用转换与读取函数,易于快速开发(VC等非RAD开发环境的开发);
5)、支持USB、PC扩展卡等扩展串口号;
6)、支持多种操作系统win9x/win2000/winXP(标注Win32DLL);
7)、可在多种编程环境下使用,例如VB、VC、Delphi等开发环境。
二、PPI协议简介及S7-200CPU内存地址范围介绍
2.1西门子PPI通讯协议
通过硬件和软件侦听的方法,分析PLC内部固有的PPI通讯协议,然后采用上位机编程,遵循PPI通讯协议,读写PLC数据,实现人机操作
任务。
这种通讯方法,与一般的自由通讯协议相比,省略了PLC的通讯程序编写,只需编写上位机的通讯程序资源S7-226的编程口物理层为
RS-485结构,SIEMENS提供MicroWin软件,采用的是PPI(PointtoPoint)协议,可以用来传输、调试PLC程序。
在现场应用中,当需要PLC
与上位机通讯时,较多的使用自定义协议与上位机通讯。
在这种通讯方式中,需要编程者首先定义自己的自由通讯格式,在PLC中编写代码,
利用中断方式控制通讯端口的数据收发。
采用这种方式,PLC编程调试较为烦琐,占用PLC的软件中断和代码资源,而且当PLC的通讯口定义
为自由通讯口时,PLC的编程软件无法对PLC进行监控,给PLC程序调试带来不便。
SIEMENSS7-200PLC的编程通讯接口,内部固化的通讯协议为PPI协议,如果上位机遵循PPI协议来读写PLC,就可以省略编写PLC的通讯
代码。
如何获得PPI协议?
可以在PLC的编程软件读写PLC数据时,利用第三个串口侦听PLC的通讯数据,或者利用软件方法,截取已经打开
且正在通讯的端口的数据,然后归纳总结,解析出PPI协议的数据读写报文。
这样,上位机遵循PPI协议,就可以便利的读写PLC内部的数据,
实现上位机的人机操作功能。
西门子的PPI(PointtoPoint)通讯协议采用主从式的通讯方式,一次读写操作的步骤包括:
首先上位机发出读写命令,PLC作出接收正确
的响应,上位机接到此响应则发出确认申请命令,PLC则完成正确的读写响应,回应给上位机数据。
这样收发两次数据,完成一次数据的读写
(从这里可以看出PPI协议的通讯效率并不好,一次读写需收发两次数据^_^)。
其通讯数据报文格式大致有以下几类:
1)、读写申请的数据格式如下:
SDLELERSDDASAFCDASPSSAPDUFCSED
SD:
(StartDelimiter)开始定界符(68H)
LE:
(Length)报文数据长度
LER:
(RepeatedLength)重复数据长度
SD:
(StartDelimiter)开始定界符(68H)
SA:
(SourceAddress)源地址,指该地址;
DA:
(DestinationAddress)目标地址,指该地址;
FC:
(FunctionCode)功能码
DSAP:
(DestinationServiceAccessPoint)目的服务存取点
SSAP:
(SourceServiceAccessPoint)源服务存取点
DU:
(DataUnit)数据单元
FCS:
(FrameCheckSequence)校验码
ED:
(EndDelimiter)结束分界符(16H)
报文数据长度和重复数据长度为自DA至DU的数据长度,校验码为DA至DU数据的和校验,只取其中的末字节值。
读写一般数据的功能码为6CH,读CT数据、置位、复位、强制等的功能码为7CH,确认命令功能码5CH。
2)、PLC接收到读写命令,校验后正确,返回的数据格式为E5H
3)、确认读写命令的数据格式为:
SDSADAFCFCSED
其中SD为起始符,为10H
SA为数据源地址
DA为目的地址
FC为功能码,取5CH
FCS为SA+DA+FC的和的末字节
ED为结束符,取16H
4)、数据类型码
04:
S
05:
SM
06:
AI
07:
AQ
1E:
C
81:
I
82:
Q
83:
M
84:
V
1F:
T
5)、读写功能数据命令实例
1、给写VW3值1200
6821216802006C320100000000000E00060501120A100200020001840000180004001004B05016
2、读取IB0的数据值
681B1B6802006C320100000000000E00000401120A100200010000810000006416
感兴趣的朋友给你根据上述例子用串口精灵测试一下,当发送命令成功PLC返回E5,你再发送1002005C5E16,就可以完成一次读写命令。
(记得接收和发送采用16进制方式o(∩_∩)o...哈哈)
2.2S7-200PLCCPU内存地址范围(DLL所能寻址的范围)
被存取:
类型CPU221CPU222CPU224CPU226
位(字节.位)V0.0-2047.70.0-2047.70.0-5119.7V1.220.0-5119.7V1.23
0.0-8191.7V2.000.0-10239.7V2.00
0.0-10239.7XP
I0.0-15.70.0-15.70.0-15.70.0-15.7
Q0.0-15.70.0-15.70.0-15.70.0-15.7
M0.0-31.70.0-31.70.0-31.70.0-31.7
S0.0-31.70.0-31.70.0-31.70.0-31.7
SM0.0-179.70.0-299.70.0-549.70.0-549.7
字节VB0-20470-20470-5119V1.220-5119V1.23
0-8191V2.000-10239V2.00
0-10239XP
IB0-150-150-150-15
QB0-150-150-150-15
MB0-310-310-310-31
SB0-310-310-310-31
SMB0-1790-2990-5490-549
字VW0-20460-20460-5118V1.220-5118V1.23
0-8190V2.000-10230V2.00
0-10230XP
T0-2550-2550-2550-255
C0-2550-2550-2550-255
AIW0-300-300-620-62
AQW0-300-300-620-62
双字VD0-20440-20440-5116V1.220-5116V1.23
0-8188V2.000-10236V2.00
0-10236XP
说明:
S7-200PLC的字、双字地址和字节地址实际上是重叠的,下面做个说明如:
VB0VB1VB2VB3VB4VB5VB6VB7VB8VB9VB10VB11VB12VB13VB14VB15
————————————————————————————————
VW0VW2VW4VW6VW8VW10VW12VW14
——————————————————————————————————————
VD0VD4VD8VD12
从上例可以看出PLC中字节、字与双字寻址的关系,当然如果你想使用VW1(VB1VB2)、VD3(VB3VB4VB5VB6)等寻址方式也是可以的,
但为了减少不必要的寻址错误造成程序的非法执行建议:
字寻址时使用(V、I、Q、M等等)0、2、4、6、8、10……,(这从PLC的模拟量输入/输出(AIW/AQW)的寻址就可以看出奇数地址是不允许的)
双字寻址时使用(V、I、Q、M等等)0、4、8、12、16、20、24…………………………,同时还要注意字节地址寻址最好也能不重叠;
C、T区当前值读取时的地址按实际地址0~255来。
三、DLL函数说明
1、打开串口
FunctionComOpen(nport,BaudRate,DataBits,Parity,StopBits:
longint;User:
Pchar):
longint;stdcall;
参数:
nport:
打开串口号,取值为1~8,代表COM1~COM8;
BaudRate:
波特率,取值为:
1200、2400、4800、9600、19200、38400;
DataBits:
数据位,取值为5、6、7、8;
Parity:
校验位,取值1(代表Even)、取值2(代表Odd)、取值3(代表Mark)、取值4(代表Space)、取值5(代表None);
StopBits:
停止位,取值1(代表1位停止位)、取值2(代表2位停止位)、取值3(代表1.5位停止位);
User:
DLL授权用户名;
返回值:
长整型,操作成功返回“1”或“2”;1表示注册授权用户,2表示用户未注册;
操作不成功返回为“0”时的原因:
1)、串口不存在或被占用;2)、DLL注册授权不正确。
注:
本DLL用户不注册除了下面说明的功能限制外没有其他限制,未注册用户请使用特定用户名:
wangjun。
注册用户功能上无任何限制,且将得到永久的软件使用和更新升级服务;
使用举例:
Delphi:
ComOpen(1,9600,8,1,1,Pchar('wangjun')),打开COM1口。
VB:
ComOpen(1,9600,8,1,1,"wangjun"),打开COM1口。
2、关闭串口
FunctionComClose(nport:
longint):
longint;stdcall;
参数:
nport:
串口号,取值为1~8,代表COM1~COM8;
返回值:
长整型,操作成功返回“1”,否则返回“0”;
使用举例:
ComClose
(1),关闭打开的COM1口。
3、PLC内部元件读取功能函数
注:
PLC内部元件与数字的对应关系(DLL中的所有函数都遵循此规定):
0:
I
1:
Q
2:
M
3:
V
4:
S
5:
SM
6:
AI
7:
AQ
8:
C
9:
T
注:
下面的读写等PLC操作函数使用举例都是按VB调用函数形式给出。
1)、字节元件数据读取
FunctionFcnBread(nport,purpose,source,name,address,Count:
longint):
Pchar;stdcall;
参数:
nport:
串口号,取值为1~8,代表COM1~COM8;
purpose:
目标地址,取值0~126;
source:
源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的)
name:
取值0(代表I)、取值1(代表Q)、取值2(代表M)、取值3(代表V)、取值4(代表S)、取值5(代表SM);
address:
元件地址,取值为请参照2.2S7-200PLCCPU内存地址范围;
Count:
读取的字节个数,最多读取128个但不能超出寻址范围;
返回值:
字符串数据,字符串数据的终止符为"@";
使用举例:
FcnBread(1,0,2,0,2,4),由COM1读取PPI2号站数据到0号站(计算机)IB2~IB5四个字节的值,如返回值为“01FF6403@”,
则表示IB2=01,IB3=FF,IB4=64,IB5=03;
------------
字符串返回序列:
|01|FF|64|03|@|
------------
返回值为16进制字符串,将返回值如上2位一组,可转换成“0~255”间的整数值。
在读取错误或不能读取的情况下返回“Error@”
注:
没有注册用户不能读取S、SM区字节值,可寻址范围IB0~IB1、QB0~QB1、MB0~MB1、VB0~VB1;
2)、字元件数据读取
FunctionFcnWread(nport,purpose,source,name,address,Count:
longint):
Pchar;stdcall;
参数:
nport:
串口号,取值为1~8,代表COM1~COM8;
purpose:
目标地址,取值0~126;
source:
源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的)
name:
取值3(代表V)、取值6(代表AI)、取值8(代表C)、取值9(代表T);
address:
元件地址,取值为请参照2.2S7-200PLCCPU内存地址范围;
Count:
读取的字个数,最多读取64个但不能超出寻址范围,T区读取时不超过44个;
返回值:
字符串数据,字符串数据的终止符为"@";
使用举例:
FcnWread(1,0,2,3,0,4),由COM1读取PPI2号站数据到0号站(计算机)VW0~VW6四个字的值,如返回值为“006403E804B00010@”,
则表示VW0=0064,VW2=03E8,VW4=04B0,VW6=0010;
-----------------
字符串返回序列:
|0064|03E8|04B0|0010|@|
-----------------
返回值为16进制字符串,将返回值如上4位一组,可转换成无符号“0~65535”或有符号“-32768~+32767”间的整数值。
如果你从PLC中读取的是有符号的数时,这个值小于等于32767,就得到你读的实际值,例如读到一个值“5EEE”转换成整数24302,
则实际值=+(24302-0)=+24302;如果大于32767,例如我读到一个值“8FC0”先转换成整数36800,那实际值=-(36800-32768)=-4032。
在读取错误或不能读取的情况下返回“Error@”
注:
没有注册用户不能读取C、T区字当前值,可寻址范围VW0~VW8、AIW0~AIW2;
3)、双字元件数据读取
FunctionFcnDWread(nport,purpose,source,name,address,Count:
longint):
Pchar;stdcall;
参数:
nport:
串口号,取值为1~8,代表COM1~COM8;
purpose:
目标地址,取值0~126;
source:
源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的)
name:
取值3(代表V);
address:
元件地址,取值为请参照2.2S7-200PLCCPU内存地址范围;
Count:
读取的双字个数,最多读取32个但不能超出寻址范围;
返回值:
字符串数据,字符串数据的终止符为"@";
使用举例:
FcnDWread(1,0,2,3,0,2),由COM1读取PPI2号站数据到0号站(计算机)VW0~VW6四个字的值,如返回值为“006403E804B00010@”,
则表示VD0=006403E8,VD4=04B00010;
--------------
字符串返回序列:
|006403E8|04B00010|@|
--------------
返回值为16进制字符串,将返回值如上8位一组,可转换成无符号“0~4294967295”或有符号“-2147483648~+2147483647”间的整数值。
如果你从PLC中读取的是有符号的数时,这个值小于等于2147483647,就得到你读的实际值,例如读到一个值“5EEE8000”转换成整数
为1592688640,则实际值=+(1592688640-0)=+1592688640;如果大于2147483647,例如我读到一个值“8FEFC000”先转换成整数2414854144,
那实际值=-(2414854144-2147483648)=-267370496。
在读取错误或不能读取的情况下返回“Error@”
注:
没有注册用户可寻址范围VD0~VD4;
4)、位元件的状态读取
FunctionFcnBitread(nport,purpose,source,name,address,Bit:
longint):
longint;stdcall;
参数:
nport:
串口号,取值为1~8,代表COM1~COM8;
purpose:
目标地址,取值0~126;
source:
源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的)
name:
取值0(代表I)、取值1(代表Q)、取值2(代表M)、取值3(代表V)、取值4(代表S)、取值5(代表SM);
address:
元件地址,取值为请参照2.2S7-200PLCCPU内存地址范围;
Bit:
读取的字节元件的位地址如I1.0指I1字节元件的第0位;
返回值:
长整数,返回为0表示状态为OFF,返回为1表示状态为ON,返回为-1表示读取错误或不能读取;
使用举例:
FcnBitread(1,0,2,0,1,7),由COM1读取PPI2号站数据到0号站(计算机)I1.7,如返回值为1,则表示I1.7=1;
注:
没有注册用户不可以读取S、SM区状态,可寻址范围I0.0~I1.7、Q0.0~Q1.7、M0.0~M1.7、V0.0~V1.7;
4、PLC内部元件写数据功能函数
1)、字节元件数据写入
FunctionFcnBwrite(nport,purpose,source,name,address,Count:
longint;Sendstr:
Pchar):
longint;stdcall;
参数:
nport:
串口号,取值为1~8,代表COM1~COM8;
purpose:
目标地址,取值0~126;
source:
源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的)
name:
取值0(代表I)、取值1(代表Q)、取值2(代表M)、取值3(代表V)、取值4(代表S);
address:
元件地址,取值为请参照2.2S7-200PLCCPU内存地址范围;
Count:
写入字节个数,这里1字节应写入2位16进制字符串;
Sendstr:
给字节写入的值,该值为2个一组的16进制字符串组其取值为00~FF(整数值为0~255);
返回值:
长整数,操作成功返回1,不能写入或操作错误返回0;
当要写入多个字节值时依次排列即可。
如给MB0与MB1写值100和80,先将100转成16进制字符串64、80
转成16进制字符串50,则sendstr=6450;一次最多写128个字节即字符串长应小于等于256;
-----------~-------
写字符串序列如:
|00|FF|10|64|~|08|04|
-----------~-------
实际字符串与位地址的数值应如下表:
(将上例的字节MB0'、MB1'转换为位地址M0.0~M1.7由下表对应,此对应也可以应用于字节读取)
M:
0.70.60.50.40.30.20.10.01.71.61.51.41.31.21.11.0
---------------------------------
位地址:
|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
---------------------------------
各位赋值:
|0|1|1|0|0|1|0|0|0|1|0|1|0|0|0|0|
---------------------------------
16进制串:
|6|4|5|0|
---------------------------------
使用举例:
FcnBwrite(1,0,2,2,0,2,"6450")由COM10号站(计算机)写入PPI2号站数据MB0=64(10进制100)、MB1=50(10进制80),操作成功返回1;
注:
没有注册用户不能写S区字节值,可寻址范围IB0、QB0、MB0、VB0;
2)、字元件数据写入
FunctionFcnWwrite(nport,purpose,source,name,address,Count:
longint;Sendstr:
Pchar):
longint;stdcall;
参数:
nport:
串口号,取值为1~8,代表COM1~COM8;
purpose:
目标地址,取值0~126;
source:
源地址,取值0~126;(这里是PLC的相应端口的PPI站地址,PLC的地址实际是从2开始的)
name:
取值3(代表V)、取值7(代表AQ);
address:
元件地址,取值为请参照2.2S7-200PLCCPU内存地址范围;
Count:
写入字个数,这里1字应写入4位16进制字符串;
Sendstr:
给字节写入的值,该值为4个一组的16进制字符串组其取值为0000~FFFF(整数值为0~65535);
返回值:
长整数,操作成功返回1,不能写入或操作错误返回0;
当要写入多个字节值时依次排列即可。
如给VW2与VW4写值100和1000,先将100转成16进制字符串0064、1000转成16进制字符串03E8,
则sendstr=006403E8;