西门子PLC的通信协议主要是PPI、MPI、Profibus、CP243/CP343/CP443 网络协议,prodave是早期完成的程序接口,除了网络协议外其它的主要协议都支持,SoftNet是西门子最新推出的通信协议接口,稳定,并且大而全,目前西门子所有主流的协议都支持(我的blog文章西门子Softnet驱动的成功开发已经做了简单介绍),由于好多朋友对prodave都比较关注,所以我这里专门写篇blog来简单介绍一下。

我所知道的最新的Prodave的版本是V5.5,完整版的要45兆左右,由于出的比较早,所以动态库“W95_s7.dll”的名称保留至今,我最早接触是在01~02年,不过当时版本好像不到V5.5,与S7-200通信很不稳定,并且访问周期比较长。给我的感觉Prodave好像专门为S7-300制作的(从库函数的声明可以看出),连S7-300相对而言比较顺利。

组态王、力控好多主流工控软件访问西门子PLC都是通过Prodave或Softnet的,可以在驱动程序中看到熟悉的W95_s7.dll,所以通信能力大家还是应该放心的。

题外话,对嵌入式系统,如WinCE,由于不能直接使用Prodave和Softnet,所以要实现与西门子PLC通信,一般只有破解了(西门子的通信协议都是保密的,并且也是加密的,一般不公开给客户),目前实现的较好的主要有PPI,MPI(需要MPI适配器,不同适配器通信协议有一定区别),CP243,CP343/CP443。

下面是我在开发相关西门子通信程序时,做的一个VC测试程序,仅供参考(Prodave简版驱动和相关测试代码,我已经上传,文章后面附下载连接)。

void CTestDlg::OnProdave() 
{
    int iRes;
    CString myStr;
    signed char Buffer[2048];

WORD *Buffer_int = (WORD *)Buffer;
    unsigned char *Buffer_byte = (unsigned char *)Buffer;    //WORD wValue;

//m_field_read MB200
    iRes=m_field_read(200,1,Buffer);

if(iRes==0)
    {
        m_Dis.SetSel(100000,100000);
        m_Dis.ReplaceSel(" ");

myStr.Format("MB200=%3d",Buffer_byte[0]);
        m_Dis.ReplaceSel(myStr);

UpdateData(false);
    }
    else
    {
        //myStr.Format("m_field_read error no:%d",iRes);
        AfxMessageBox(ErrString(iRes));        
    }

//m_field_read
    iRes=m_field_read(100,1,Buffer);

if(iRes==0)
    {
        m_Dis.SetSel(100000,100000);
        m_Dis.ReplaceSel(" ");
        myStr.Format("MB100=%3d",Buffer_byte[0]);

m_Dis.ReplaceSel(myStr);

UpdateData(false);
    }
    else
    {
        AfxMessageBox(ErrString(iRes));        
    }

//m_field_read
    iRes=a_field_read(0,1,Buffer);

if(iRes==0)
    {
        m_Dis.SetSel(100000,100000);
        m_Dis.ReplaceSel(" ");
        myStr.Format("QB0=%3d",Buffer_byte[0]);

m_Dis.ReplaceSel(myStr);

UpdateData(false);
    }
    else
    {
        AfxMessageBox(ErrString(iRes));        
    }

//写数据 MB110
    unsigned long value;
    value=100;
    memcpy(Buffer,&value,4);

iRes=m_field_write(111,1,Buffer);
    if(iRes==0)
    {
        m_Dis.SetSel(100000,100000);
        m_Dis.ReplaceSel(" ");
        myStr.Format("MB110=%3d",Buffer[0]);
        m_Dis.ReplaceSel(myStr);
        UpdateData(false);
    }
    else
    {
        AfxMessageBox(ErrString(iRes));        
    }

//写数据 MB4
    BYTE value1;
    value1=33;
    memcpy(Buffer,&value,1);
    iRes=m_field_write(4,1,Buffer);
    if(iRes==0)
    {
        m_Dis.SetSel(100000,100000);
        m_Dis.ReplaceSel(" ");
        myStr.Format("MD4=%3d",Buffer[0]);
        m_Dis.ReplaceSel(myStr);
        UpdateData(false);
    }
    else
    {
        AfxMessageBox(ErrString(iRes));        
    }
}

void CTestDlg::OnLoad() 
{
    adr_table_type myTable[2];
    myTable[0].adr=3;
    myTable[0].segmentid=0;
    myTable[0].slotno=2;
    myTable[0].rackno=0;
    myTable[1].adr=0;
    myTable[1].segmentid=0;
    myTable[1].slotno=2;
    myTable[1].rackno=0;
    int iRes;
    CString myStr;
    //初始化ProDave300
    iRes=load_tool(1,"S7ONLINE",myTable);
    if(iRes==0)
    {
        m_Dis.SetSel(30000,30000);
        m_Dis.ReplaceSel(" ");
        m_Dis.ReplaceSel("load_tool ok!");
        UpdateData(false);
    }
    else
    {
        AfxMessageBox(ErrString(iRes));
        unload_tool();
        return;        
    }    
}

void CTestDlg::OnUnloadtool() 
{
    int iRes;
    CString myStr;
    iRes=unload_tool();
    if(iRes==0)
    {
        m_Dis.SetSel(30000,30000);
        m_Dis.ReplaceSel(" ");
        m_Dis.ReplaceSel("unload_tool ok!");
        m_Dis.ReplaceSel(" ");
        UpdateData(false);
    }
    else
    {
        AfxMessageBox(ErrString(iRes));        
    }    
}

void CTestDlg::OnStatus() 
{
    int iRes;
    CString myStr;
    char  myInfo[512];
    iRes=ag_zustand(myInfo);
    if(iRes==0)
    {
        m_Dis.SetSel(30000,30000);
        m_Dis.ReplaceSel(" ");
        m_Dis.ReplaceSel("ag_zustand ok!");
        UpdateData(false);
        if(myInfo[0]==0)
        {
            m_Dis.ReplaceSel(" ");
            m_Dis.ReplaceSel("RUN");
        }
        else
        {
            m_Dis.ReplaceSel(" ");
            m_Dis.ReplaceSel("STOP");
        }
        UpdateData(false);
    }
    else
    {
        AfxMessageBox(ErrString(iRes));        
    }    
}
LPSTR CTestDlg::ErrString(WORD wErrCode)
{
    LPSTR myStr1;
    switch(wErrCode)
    {
    case 517:
        {
            return "PRODAVE not initialized.";
            break;
        }
    case 787:
        {
            return "Incorrect rate/Interrupt vector.";
            break;
        }
    case 789:
        {
            return "MPI Address error.";
            break;
        }
    case 800:
    case 818:
        {
            return "hardware fault.";
            break;
        }
    case 820:
        {
            return "com not avaliable.";
            break;
        }
    case 898:
    case 900:
        {
            return "no driver or device found.";
            break;
        }
    case 16386:
        {
            return "Connection not established.";
            break;
        }
    default:
        {
            CString myStr;
            myStr.Format("%d",wErrCode);
            myStr1=myStr.GetBuffer(0);
            myStr.ReleaseBuffer();
            return myStr1;
        }
    }
}

void CTestDlg::OnNewss() 
{
    //激活连接
    int iRes;
    iRes=new_ss(1);
    if(iRes==0)
    {
        m_Dis.SetSel(100000,100000);
        m_Dis.ReplaceSel(" ");
        m_Dis.ReplaceSel("new_ss ok!");
        UpdateData(false);
    }
    else
    {
        AfxMessageBox(ErrString(iRes));
        unload_tool();
        return;
    }    
}

void CTestDlg::OnAginfo() 
{
    //读PLC信息
    int iRes;
    char  myInfo[512];
    iRes=ag_info(&myInfo[0] );
    if(iRes==0)
    {
        m_Dis.SetSel(100000,100000);
        m_Dis.ReplaceSel(" ");
        m_Dis.ReplaceSel("ag_info ok!");
        UpdateData(false);

m_Dis.ReplaceSel(" ");
        m_Dis.ReplaceSel(&myInfo[4]);

UpdateData(false);
    }
    else
    {
        AfxMessageBox(ErrString(iRes));
        unload_tool();
        return;
    }    
}

prodave 测试程序:http://download.csdn.net/source/228758

西门子Prodave5.5使用说明及VC示例的更多相关文章

  1. 各种开发语言示例调用WebService接口

    ASP示例: <% uid="账号"pwd="密码"tos="13900041123"msg="你们好"url = ...

  2. VC操作MPP文件

    1.背景简介 因需要对Office系列进行程序操作,特需要使用COM编程. Microsoft Project生成进度计划,office家族软件,文件后缀为.mpp. 具体信息见维基百科http:// ...

  3. QT皮肤框架-TQUI

    本皮肤框架的相关文档,请在附件中下载,包括测试程序源码,帮助文档.相关文档可到我的百度网盘中下载,或者在本贴附件中下载. 百度网盘地址:TQUI-V1.0项目说明及测试程序源码 项目更新说明:---- ...

  4. JQ 报表插件 jquery.jqplot 使用

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  5. web前端开发——css

    一.css介绍 1.css是什么? Cascading Style Sheets缩写,层叠样式表.样式定义如何显示HTML元素,样式通常又会存在于样式表中. 2.为什么需要css? 使HTML页面变得 ...

  6. API Hook基本原理和实现

    API Hook基本原理和实现 2009-03-14 20:09 windows系统下的编程,消息message的传递是贯穿其始终的.这个消息我们可以简单理解为一个有特定意义的整数,正如我们看过的老故 ...

  7. Python + Selenium 自动发布文章(一):开源中国

    https://blog.csdn.net/qq_28804275/article/details/80891949 https://blog.csdn.net/qq_28804275/article ...

  8. MyBatis Generator 自动生成的POJO对象的使用(二)

    四.Example Class使用说明 示例类指定如何构建动态where子句. 表中的每个非BLOB列都可以选择包含在where子句中. 示例是演示此类用法的最佳方法. 示例类可用于生成几乎无限制的w ...

  9. OkHttp 优雅封装 HttpUtils 之 气海雪山初探

    曾经在代码里放荡不羁,如今在博文中日夜兼行,只为今天与你分享成果.如果觉得本文有用,记得关注我,我将带给你更多. 介绍 HttpUtils 是近期开源的对 OkHttp 轻量封装的框架,它独创的异步预 ...

随机推荐

  1. 数据结构与算法(1)支线任务8——Find Median from Data Stream

    题目如下:(https://leetcode.com/problems/find-median-from-data-stream/) Median is the middle value in an ...

  2. Dictionary的几种遍历方法

    Dictionary<string, int> list = new Dictionary<string, int>(); list.Add("d", 1) ...

  3. xcode:关于Other Linker Flags

    一.关于Other Linker Flags xcode中,在“Targets”选项下有Other Linker Flags选项,在这里可以填写xcode链接器的参数,如:-ObjC.-all_loa ...

  4. 创建一个List获取数据的lookup

    第一步,在类:syslookup中新建方法 public static client void lookupList(FormStringControl _formStringControl, Lis ...

  5. session management

    The session does not created until the HttpServletRequest.getSession() method is called.

  6. (Hibernate进阶)Hibernate映射——一对多关联映射(七)

    一对多关联映射 映射原理 一对多关联映射和多对一关联映射的映射原理是一致的,都是在多的一端加入一个外键,指向一的一端.关联关系都是由多端维护,只是在写映射时发生了变化. 多对一和一对多的区别 多对一和 ...

  7. C语言实现GPT头和分区表的读取(gcc)

    #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h&g ...

  8. JUC.Lock(锁机制)学习笔记[附详细源码解析]

    锁机制学习笔记 目录: CAS的意义 锁的一些基本原理 ReentrantLock的相关代码结构 两个重要的状态 I.AQS的state(int类型,32位) II.Node的waitStatus 获 ...

  9. MySQL 第八天(核心优化二)

    一.昨天内容回顾 存储引擎 保存数据的格式(技术),不同格式体现特性不一样 myisam ① 结构.数据.索引 文件单独存储 ② 存入数据顺序(不考虑主键顺序) ,写入数据速度快 ③ 并发性,低,锁整 ...

  10. adb常用命令

    adb命令的主要用途  1. 运行android设备的shell(命令行).  2.管理模拟器或android设备的映射端口.  3. 安装和卸载应用程序.  4.计算机和android设备之间的上传 ...