[西门子] 西门子的Modbus_TCP/IP

[复制链接]
查看123 | 回复0 | 2025-4-13 18:56:46 | 显示全部楼层 |阅读模式
西门子的Modbus_TCP/IP FB(功能块)封装主要用于实现与支持Modbus TCP/IP协议的设备之间的通信。这种通信方式基于以太网,能够有效集成不同制造商生产的设备进入一个统一的自动化系统中,增强了系统的互操作性和扩展性。一、主要应用场合
  1. 工业自动化:在制造业中,不同类型的设备需要进行数据交换和控制命令传递。通过使用Modbus TCP/IP FB块,可以方便地将各种支持该协议的设备连接到PLC(可编程逻辑控制器),如西门子S7系列,实现对生产流程的监控和管理。

  2. 楼宇自动化:用于HVAC(暖通空调)、照明系统、安防系统等的集中管理和控制,提高能效和居住舒适度。

  3. 能源管理系统:监测和控制系统中的电表、水表、气表等计量装置,帮助用户优化能源使用效率,降低运营成本。

  4. 环境监测:收集温度、湿度、空气质量等环境参数的数据,适用于温室、实验室等需要精确控制环境条件的场所。

二、意义

  • 简化开发过程:开发者无需深入了解Modbus TCP/IP协议的具体细节,只需调用相应的FB块即可快速实现通信功能,节省了开发时间和成本。

  • 增强兼容性:由于Modbus TCP/IP是一种开放的标准协议,广泛应用于多种设备和系统中,因此采用这一协议有助于构建更加开放和灵活的自动化解决方案。

  • 提高可靠性:通过标准化的通信机制,确保了数据传输的准确性和稳定性,减少了因通信故障导致的生产中断风险。

  • 便于维护和升级:模块化的程序设计使得系统更容易维护,并且可以根据需求方便地添加或更换设备,提升了系统的可扩展性。

三、FB块封装

//初始化连接参数

#s_TCON_Param.InterfaceId := #i_InterfaceId;  //硬件标识符

#s_TCON_Param.ID := #i_ID;                   //引用该连接(值范围: 1 - 4095)。

#s_TCON_Param.ConnectionType := b#16#11;     //B#16#11:TCP 19=UDP

#s_TCON_Param.ActiveEstablished := #i_Active;    //FALSE:被动建立;TRUE:主动建立

//远程IP=电脑IP地址

#s_TCON_Param.RemoteAddress.ADDR[1] := #i_RemoteIP1;

#s_TCON_Param.RemoteAddress.ADDR[2] := #i_RemoteIP2;

#s_TCON_Param.RemoteAddress.ADDR[3] := #i_RemoteIP3;

#s_TCON_Param.RemoteAddress.ADDR[4] := #i_RemoteIP4;

//远程端口

//PLC客户端需要远程端口;PLC服务器远程端口必须为0,PLC变更模式CPU需要重启

IF #i_Active THEN

    #s_TCON_Param.RemotePort := #i_RemotePort;

ELSE

    #s_TCON_Param.RemotePort := 0;

END_IF;

//本地端口

#s_TCON_Param.LocalPort := #i_LocalPort;


//======================== 连接判断 =============================

IF #s_TCON_Ok = false AND #s_EndConnect = false AND #i_Connect THEN       //开始连接准备信号 与 断开连接信号

    #s_StartConnect := true;                              //启动连接

    IF #TCON_Instance.DONE OR #TCON_Instance.ERROR THEN  //连接ok后 false连接信号

        #s_StartConnect := false;

        #s_TCON_Ok := true;

    END_IF;

END_IF;


//重复连接信号启动

#s_ConnectOnline(IN := #s_TCON_Ok AND #s_StartConnect = false

                 AND (#TRCV_Instance.ERROR OR #TDIAG_Param.State <> 16#04),

                 PT := T#1S);

//延时启动连接 

IF #s_ConnectOnline.Q THEN

    #s_StartConnect := true;

END_IF;


//重复连接信号停止

#s_ConnectOffline(IN := #s_StartConnect,

                  PT := T#1S);

//延时断开

IF #s_ConnectOffline.Q THEN

    #s_StartConnect := FALSE;

END_IF;


//断开连接重新链接判断 //(远程IP)或(远程端口)变更 就执行 断开连接 

#r_trigDisconnect(CLK := NOT #i_Connect);


IF (#s_LastIP1 <> #i_RemoteIP1 OR #s_LastIP2 <> #i_RemoteIP2 OR

    #s_LastIP3 <> #i_RemoteIP3 OR #s_LastIP4 <> #i_RemoteIP4 OR #s_LastRemPort <> #i_RemotePort

    OR #r_trigDisconnect.Q)

THEN

    #s_TCON_Ok := false;     //开始连接准备信号 

    #s_StartConnect := false;//开始连接信号

    #s_EndConnect := true;   //断开连接信号

END_IF;

IF #TDISCON_Instance.DONE OR #TDISCON_Instance.ERROR THEN  //完成信号 与 错误

    #s_EndConnect := false;

    #s_LastIP1 := #i_RemoteIP1;

    #s_LastIP2 := #i_RemoteIP2;

    #s_LastIP3 := #i_RemoteIP3;

    #s_LastIP4 := #i_RemoteIP4;

    #s_LastRemPort := #i_RemotePort;


END_IF;

//#s_EndConnect := false;

//开始连接 =====================================================================

#TCON_Instance(REQ := #s_StartConnect  // IN: BOOL

               ,

               ID := #i_ID  // IN: WORD

               ,

               CONNECT := #s_TCON_Param  // INOUT: ANY

);


//断开连接 =====================================================================

#TDISCON_Instance(REQ := #s_EndConnect  // IN: BOOL

                  ,

                  ID := #i_ID  // IN: WORD

);


//接收数据 =====================================================================

#TRCV_Instance(EN_R := #i_Recv // IN: BOOL  

               ,

               ID := #i_ID  // IN: WORD

               ,

               LEN := #i_RecvNum  // IN: INT

               ,

               ADHOC := TRUE

               ,

               DATA := #io_RBuff // INOUT: ANY

);


//发送数据 =====================================================================

#TSEND_Instance(REQ := #i_Send  // IN: BOOL

                ,

                ID := #i_ID  // IN: WORD

                ,

                LEN := #i_SendNum  // IN: INT

                ,

                DATA := #io_SBuff  // INOUT: ANY

);


//检查连接 =====================================================================

#TDIAG_Instance(REQ := #s_TdiagReq  // IN: BOOL

                ,

                ID := #i_ID  // IN: WORD

                ,

                RESULT := #TDIAG_Param  // INOUT: ANY

);

// 0.5S 延时检查连接

#s_ConnectCheckOn(IN := #s_TdiagReq = FALSE,

                  PT := T#500MS);


IF #s_ConnectCheckOn.Q THEN

    #s_TdiagReq := TRUE;

END_IF;


#s_ConnectCheckOff(IN := #s_TdiagReq,

                   PT := T#500MS);


IF #s_ConnectCheckOff.Q THEN

    #s_TdiagReq := FALSE;

END_IF;


// 接收错误

IF #TRCV_Instance.ERROR OR #TDIAG_Param.State <> 16#04 OR NOT #i_Connect THEN

    #o_Connected := false;

ELSE

    #o_Connected := true;

END_IF;


#o_SendEnd := #TSEND_Instance.DONE;

#o_RecvEnd := #TRCV_Instance.NDR;

//接收数据

IF #TRCV_Instance.NDR THEN

    #o_RecvNum := UDINT_TO_INT(#TRCV_Instance.RCVD_LEN);

END_IF;

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则