西门子Prodave5.5使用说明及VC示例

news/2024/7/4 9:58:58

         西门子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

Prodave简版驱动:http://download.csdn.net/source/228765

 





http://www.niftyadmin.cn/n/3655824.html

相关文章

2020-12-18 js 实现堆

堆是什么? 堆是一种特殊的完全二叉树所有的节点都大于等于(最大堆)或小于等于(最小堆)它的子节点。 js 中的堆 js 中通常用数组表示堆左侧子节点的位置是 2 * index 1右侧子节点的位置是2* index 2父节点位置是&am…

VB实现SHELL扩展之接口参数获取失败探析

前几天有位网友问我用VB实现SHELL扩展的问题,这个问题比较有意思,虽然VB较少使用了,但是用VB开发COM组件还是比较方便的(前几天用EVC开发COM组件,相比起来,用VB还是比较幸福的),所以…

js 排序学习

冒泡排序 Array.prototype.bubbleSort function() {// console.log(this)for (let i 0; i < this.length - 1; i) {for(let j 0;j<this.length -1 - i; j1){ // -1 可以用j1来获取 - i是为了缩小循环节省时间if(this[j] > this[j1]){const temp this[j] // …

16进制字符串转数字(C/C++,VB/VB.net,C#)

这个问题看是很简单&#xff0c;但是在不同语言中实现的方式却千差万别&#xff0c;如果不知道方法&#xff0c;还真是麻烦&#xff0c;我就是在C#中遇到该问题&#xff0c;让我费了很大的周折&#xff0c;才在msdn查到。一、16进制字符串转数字1、C/CI、最简单的办法&#xff…

面试题 ---快速排序的空间复杂度是多少?时间复杂度的最好最坏的情况是多少,有哪些优化方案?

Array.prototype.quickSort function() {const rec (arr) >{if(arr.length 1){return arr}// 分别存放 前后的数组const left []const right []// 设置一个基准const mid arr[0]//进行分区for(let i 1; i<arr.length; i1){if(arr[i] < mid){left.push(arr[i])}el…

如何加速XML反序列化(精简框架集2.0SP1,WinCE4.2) -- 寻求微软技术支持记

其实这个问题在2007/3/13 就提交到了微软技术支持&#xff0c;但直到今天&#xff0c;对这个问题还没有一个完美的结果&#xff08;他们最好的建议就是&#xff0c;自己解析XML文件&#xff09;&#xff0c;只好请求微软的技术支持把这个问题close掉。问题的关键在于&#xff1…

面试题---------简述 LRU 算法及其实现方式

简述 LRU 算法 一种比较常见的缓存算法&#xff0c;也是内存管理使用的一种算法。在内存满的时候&#xff0c;选择内存中最近最久未使用的页面予以淘汰。 实现方式 哈希表 双向链表 双向链表按照被使用的顺序存储了这些键值对&#xff0c;靠近头部的键值对是最近使用的&…