西门子S7-200 PPI协议获取及其通信控件研究

原文地址:http://www.e-automation.net.cn/Lib/ShowInfoCon.asp?id=6490
这篇文章是我在做PPI协议分析时看到的,写的还比较不错,与大家分享,可到原文阅读。
发表时间:
2008-4-2 作者:许其义,武玉强,初学导 摘要:
引言

    西门子S7-2OO CPU可支持多种通信协议,如点到点(Pojnt-to-point)的协议(即PPI)、多点协议(MPI),以及Prfibus协议等。其中PPI协 议是西门子公司专门为其产品S7-200开发的通信协议,使用PPI协议进行通信时,PLC可以不用编程,而且可读写所有数据区,快捷方便。但是,PPI 协议属内部协议对外不公开,用户如果想使用PPI协议监控,必须购买其监控产品或第三方厂家的组态软件(第三方厂家也是购买的该协议的驱动文件,他们同样 也看不到该协议)。这样给用户自主开发带来一定困难,特别是自行开发的现场设备就不能通过PPI协议接入PLC。其它通信方式编程也存在编程复杂,需要购 买软件和授权等局限性。基于上述原因我们尝试使用串口监视第三方软件和PLC的数据通信,获得它们的通信数据字,然后对大量的数据进行统计分析,得到通信 指令关键报文的格式,最后在自行开发的程序中逐一测试,总结得出PPI协议的内容,并开发出通信控件,使它在自主开发的总线控制系统中监控机与各子站 PLC的通信变得简单、灵活、经济,解决了PLC在现场总线控制系统中的通信难题。
    Borland C++ Builder作为一种新颖的可视化编程语言,自诞生以来,就以其在运行速度、实现的功能及开发应用程序界面方面的强大功能风靡于世,成为Windows 平台下最主要的应用开发系统之一。它继承TRAD(rapid application development)和VCL(visual component library)技术,这使得利用C++ Builder开发应用程序变得简单、快速、易于移植。因此,我们使用 C++ Builder开发通信控件。
一、S7-200 PPI协议 
1.1 协议获取方法
    获取协议的基本思路:西门子的Step7 Micro/ Win32是用于S7-200系列PLC的编程开发工具,它使用PC机上的COM口通过一条PC/PPI编程电缆连接到PLC的编程口上。这说明,PC实 际上是可以通过串口与S7-2OOCPU通信。通过截获PC机串口上的收发数据,对照Step7 Micro/Win32软件发出的指令,我们就有可能分析出有关指令的报文和通信方式;然后,直接通过串口向PLC发送报文,以验证这些指令报文是否正 确。昆仑公司开发的MCGS组态软件中有西门子S7-2OOPPI协议的驱动程序,我们可以利用它强大的监控能力更加方便地获取数据报文。
    获取协议需要的硬件条件:一台具有至少两个串行口的计算机,一条SIEMENSS7-2OO PC/PPI电缆,串口分支器(自行制作)等。
    软件条件:Step7 Micro/Win32软件,带PPI驱动程序的组态软件(如MCGS),C++ Builder开发环境,串口监视软件(可选)。
    制作一个串口的分支器,COM1的RX、TX分别接到COM2的TX、RX,即交叉接线,使得COM1发送的数据COM2能收到。PC/PPI编程电缆接在COM1上,这样,Step7 MiCro/Win32发给PLC的报文就可以在COM2上接收了。我们按S7-200系统手册设置两个串口,参数均为9600、8、偶校验、1位停止位,然后设置Step7软件,使之能与S7-200CPU正常通信。从Step7软件中发出一个明确指令,COM2上的监视软件就能显示这条报文了(用16进制显示)。通过类比组态软件与PLC通信中所得至的数据,我们即可以得到一些关键的报文。串口分支器原理如图1所示。
               西门子S7-200 PPI协议获取及其通信控件研究_第1张图片
1.2 协议分析
    编写串口监视程序,对计算机进行底层操作,使计算机的两个串口互不干扰。程序一开始执行就打开监视串□,监听并记录经过串口的所有数据,利用串口接收经过串口的数据,对接收到的大量数据进行分析。
    例如:通过Step7 Micro/Win32软件访司PLC寄存器VBl00,串口监视程序得到的另一串口发送和接收的数据为:
    68 1B lB 68 02 00 6C 32 01 00 00 00 00 00 0E 00 00 04 01 12 0A 10 02 00 01 00 01 84 00 03 20 8B 16
    68 16 16 68 00 02 08 32 03 00 00 00 00 00 02 00 05 00 00 04 01 FF 04 00 08 41 97 16
    通过Step7 Micro/Win32软件改写PTC寄存器 VD2O0,串口监视程序得到的另一串口发送和接收的数据为:
    68 20 20 68 02 00 7C 32 01 00 00 00 00 00 0E 00 05 05 01 12 0A 10 02 00 01 00 01 84 00 06 40 00 04 00 08 FF CF 16
    E5
    10 02 00 5C 5E 16
    68 12 12 68 00 02 08 32 03 00 00 00 00 00 02 00 01 00 00 05 0l FF 47 16
    上面仅给出两个读写操作的例子,实际中利用这种方法得到大量的数据,进行统计比较分析,总结出协议指令格式。 
1.3 协议指令测试
    根据上面分析总结出的协议指令,利用C++ Builder编写测试程序(实现与PLC的通信)逐一对操作进行测试,对测试过程进行详细的记录;然后分别利用组态软件MCGS,以及西门子开发的 OPC软件PC ACCESS(它们与S7-200通信都是使用PPI协议)再与PLC通信检验测试结果的正确性,进而检验所总结的协议指令的正确性。测试界面如图2所 示。
     
    下面给出测试部分用的关键程序段:
                //发送指令,其中数组rInstr存储的是指令字
Variant TxBuff;
               //声明一个OleVariant变量
TxBuff=VarArrayCreate(OPENARRAY(int,(0,32)),varByte);
                //重置它的大小,为0~n,int为n的类型
                //varByte 为TxBuff每一个元素的类型
for(int i=0;i<33;i++)
    TxbBuff.PutElement(rInstr[i],i);
               //填充元素其中str_read为定义的一个固定数组
                     //其中有要发的数据
MSComm1->Output=TxBuff;
               //接收返回数据,数据以整形表示
OleVariant BxBuff;
RxBuff=MSComm1->Input;
              //接收数据
int a=RxBuff.ArrayHighBound(1);
               //接收数据的字节数
for(int i=0;i<Len;i++)
             //提取接收到的数据到接收缓冲数组中得到有用数据
   rev_array[i]=RxBuff.GetElement(a-1-Len+i);
for(int i=0;i<Len;i++)
       dataTy=dataTy*16*16+rcv_array[i];
……
二、通信控件研究与开发
    C++ Builder中提供了相当多的控件供开发人员选用,控件可分为可视化控件与不可视化控件两种。可视化控件在使用时可以在设计阶段和运行阶段均见到其外 观;不可视控件则只能在设计阶段看到一个代表的图标,运行阶段是不可见的,但可以看到该控件所提供的服务。除了C++ Builder所提供的控件外,程序开发人员可以针对本身的需要自行组合现有的控件而创建一个新的控件,或是自行开发一个全新的控件,开发完成后便可加入 到C++ Builder的控件面板中,同C++ Builder中自身的控件一样使用,相当方便。
    根据上述对西门子PPI协议的解读及其测试利用C++ Builder开发PPI通信控件的详细说明如下。 
2.1 控件的创建步骤
    本文创建的控件属不可视控件;从Tcomponent类继承而来,可在设计期间见到代表的图标,运行期间见到控件实现的功能。设计步骤具体如下:
    ①在C++ Builder集成开发环境下,选择Filel New菜单,调出对象库,然后选择New选项卡中的 Component选项,输入适当的控件类,命名为TS7Comm,定义安装在自定义标签7e,如图3所示。
          
    ②窗体出现一个空白的控件单元文件,至此控件的基本架构结束,下面就是实际的程序代码编写。
    ③创建代表控件的代表图标。
    文章所要开发的控件属于执行期不可见的控件,需要一个代表的图标放在控件面板上,当在应用程序中使用该控件时,也要在窗口上显示代表图标。使用C++ Builder中的Image Edit程序,做一个24x24像素的Bitmap图像,该Bitmap的名称要和控件有相同的命名,这里命名为TS7Comm,使用ImageEdit 绘图工具画完图标后,保存为TS7Comm.dcr。 
2.2 控件的主要功能
    控件要完成的主要功能是读写S7-2OO PLC的寄存器(I、Q、M、V、S、SM等),控制S7-2OO PLC的状态(登录、启动、停止),强制I/O操作(强制读迸数字量输入和强制写数字量输出)。
    为了简化串口程序的设计,本文选用了Microsoft的MSCOmm控件。注册MSCOmm控件,C++ Builder中不像VB、VC本身提供串行通信控件MSComm,但是我们可以通过注册后像VB、VC那样使用它。启动C++ Builder后,选择主菜单中的Component菜单项,单击Import Active Control命令,弹出Import Active窗口,选择Microsoft Comm Control6.0,在选择Install按钮执行安装命令,系统会自动进行编译,编译完成后即完成了MSComm控件的注册,系统默认安装在 Active页,这里安装在标签7e下。接下来我们就可以像使用C++ Builder本身提供的控件那样使用新注册的MSComm控件了。这样就不用再像串口监视那样使用较复杂的API函数,而用MSComm控件可以省去不 少底层程序的编写,简单地实现串口通信,在开发控件的Unit文件的头文件中加入#include "MSCommLib_OCX.h"。
    下面给出部分重要属性、函数的声明
    class PACKAGE TS7Comm:public TComponent
{
PrlVate:
     TComPonNumber FConmmPonent;
     bool FPortOpen;
     void-fastcall SetCommPort ComPortNumber port);
                                   //设置通信端口
     void-fastcall SetBaudRate (TBaudRate Rate);
                                   //设置通信速率
     void-fastcall SetDataBits (TDataBits Num);
                                   //设置数据位数
     void-fastcall SetStopBits (TStopBits Num);
                                     //设置停止位
    void -fastcall SetParity (TParity p)
                                   //设置检验方式
    void -fastcall SetPortOpen (bool b)
                                 //打开通信端口
    void OpenPort( ) ;
    void ClosePort( ) ;
                               //关闭通信端口
......
protected
......
public
    -fastcall TS7Comm (TComponent* Owner) ;
                                                   //构造函数
    -property bool PortOpen = {read = FPortOpen, write=SetPortOpen, default=false};
                         //开关通信端口
    long-fastCall ReadData(int plcAddr,TRortOpen,write=SetPortOpen,default=false};
                        //读寄存器,plcAddr PLC的地址,默认为02,regTy寄存器地址
                        //regAddr是寄存器地址
    void-fastcall WriteData(int plcAddr,TRegType regTy,int regAddr,long data);
                        //写寄存器,最后一个参数为欲写入的数据
    bool-fastcall ForceRead(int plcAddr,int regAddr);
                       //强制读数字量输入
    bool-fastcall ForceWrite(int plcAddr,int regAddr);
                      //强制写数字量输出
    bool-fastcall PlC(int plcAddr);
                      //登录指定的PLC站
    bool-fastcall RunPlc(int plcAddr);
                      //启动
    bool-fastcall StopPlc(int plcAddr) ;
                      //停止
……
-published:
                     //加入属性
    -property TComPornNumber CommPort={read=FCommport,write=SetCommPort,default=pnComl}; 
    -property TBaudRate BaudRate = {read=FBaudRate,write=SetBaudRate,default=br9600};
    -property TDataBits DataBits = {read=FDataBits,write=SetDataBits,default=DB8};
    -Property TParity Parity={read=FParity,write=Setparity,default=None};
    -property TStopBits StopBits={read=FStopBits,write=SetStopBits,default=SB1';
......
......
2.3 控件的安装调试
     以上控件命名为TS7Comm,依照属性、事件、方法构建了控件的各种服务,也创建了控件的代表图标,编译控件的文件S7Comm.Cpp,通过编译后, 生成目标文件S7Comm.obj,这样就为控件的安装做好了准备。控件的安装过程:首先,将开发的控件文件加大到一个包中,这样才能把它放到控件面板 里。在菜单Component下选择Install Component;接下来在unit file name中选择控件的文件,必须指明完整的路径,再给定要安装的包文件名称(Package file name),然后,点击OK,在出现的'Package窗口中就包含了控件的名称和其所属单元文件的名称。接下来是进行编译(Compile)操作,由 C++ Builder的编译器看看所创建的控件是否可以通过编译,在Package窗口中点击左上方的Compile图标按钮后,即开始进行编译。编译过程中如 果出现问题,C++ Builder会提示程序的错误点或警告点。此时必须对程序进行修正,直到所有的错误点被更正为止。最后,所有的问题郡修正完毕后,程序即通过了编译,单 击install图标按钮,系统即为控件在控件面板上设置一个放置位置,这与空间文件中Register函数所指明的标签一致。一切安装操作完成后,在 C++ Builder的控件面板的7e控件页面中就出现了一个S7COmm控件。 
    至此,控件的安装已完成,接下来对控件迸行测试。笔者通过在应用程序中做了大量的测试,证明该控件各项功能都能正确实现,且稳定可靠。目前,该控件已经在THJ-2型高级过程控制系统实验装置的自主监控平台上使用,运行良好。
三、结束语
    本文利用计算机串口监视技术成功获得了西门子S7-2OOPPI协议的指令字,并加以解析、总结、测试,并在C++ Builder开发环境集成开发了PPI通信控件。实践证明,在不使用西门子通信驱动程序或者其它组态软件的情况下,利用所开发的PPI通信控件实现上位 机对PLC的监控该方法投资少,易于开发,运行稳定可靠,易于小型监控系统使用。另外,本文所述对通信端口进行监测、分析的方法对一些未知协议的测定和通 信错误的检查也具有一定的指导意义。

 C-2008-2


你可能感兴趣的:(编程,c,测试,Microsoft,import,Borland)