<< 点击显示目录 >> 主页 ModbusTCP库使用说明 > 例程与用例 > ST > MBclient应用Demo > MbTCPMaster.st |
(*!
* @file MbTCPMaster.st
* @brief ModbusTCP Master端示例代码
* @date 创建于:2021.01.18;最后修改日期:2021.12.31
* @version V1.00.4
* @author YZY
* @copyright B&R
*)
(*! History
*****************************************************************************
* 2021.01.18 V1.00.1 YZY
* (new) 初步实现
* 2021.11.24 V1.00.2 YZY
* (new) 进行调整,增加master 的unit id
* 2021.12.30 V1.00.3 YZY
* (new) 增加大索引的测试
* 2021.12.31 V1.00.4 YZY
* (new) 增加对04读80个数据命令进行测试
******************************************************************************
*)
(*! Description
*****************************************************************************
* 可观察 t_bCheckDataFromSlave 是否为TRUE来判断此本地仿真通讯是否正常
* 可观察 GetVarChangeSpeed 数据结构体 来判断数据更新整体速率情况
******************************************************************************
*)
PROGRAM _INIT
(************************************************************)
(* 连接Slave IP | 端口号设定 *)
(************************************************************)
Ctrl.Para.sIP := '127.0.0.1';
Ctrl.Para.uServPort := 502;
//uUsePort需注意可请求的端口资源。
Ctrl.Para.uUsePort := Ctrl.Para.uServPort + 50;
(************************************************************)
(* ModbusTCP Function Code 04 *)
(* Read Input Registers *)
(************************************************************)
Para_MbTCP.action_enable[0].cyclic := 1; //循环执行
Para_MbTCP.action_enable[0].single := 0; //单次执行
Para_MbTCP.action_param[0].type := 4; //指令类型
Para_MbTCP.action_param[0].start_addr := 0; //起始地址
Para_MbTCP.action_param[0].quantity := 80; //长度 (Quantity数量上限为120)
Para_MbTCP.action_param[0].p_pv := ADR(Ctrl.Status.Data.Slave_AI_Data[Para_MbTCP.action_param[0].start_addr]); //目标变量
Para_MbTCP.action_param[0].timer := 10; //命令执行时间等待间隔,单位ms
(************************************************************)
(* ModbusTCP Function Code 03 *)
(* Read Holding Registers *)
(************************************************************)
Para_MbTCP.action_enable[1].cyclic := 1; //循环执行
Para_MbTCP.action_enable[1].single := 0; //单次执行
Para_MbTCP.action_param[1].type := 3; //指令类型
Para_MbTCP.action_param[1].start_addr := 1998; //起始地址
Para_MbTCP.action_param[1].quantity := 1; // Quantity数量上限为120。
Para_MbTCP.action_param[1].p_pv := ADR(Ctrl.Status.Data.Slave_AO_Data[Para_MbTCP.action_param[1].start_addr]); //目标变量
Para_MbTCP.action_param[1].timer := 10; //命令执行时间等待间隔,单位ms
(************************************************************)
(* ModbusTCP Function Code 02 *)
(* Read Input Status *)
(************************************************************)
Para_MbTCP.action_enable[2].cyclic := 1; //循环执行
Para_MbTCP.action_enable[2].single := 0; //单次执行
Para_MbTCP.action_param[2].type := 2; //指令类型
Para_MbTCP.action_param[2].start_addr := 0; //起始地址
Para_MbTCP.action_param[2].quantity := 1; // Quantity数量上限为120。
Para_MbTCP.action_param[2].p_pv := ADR(Ctrl.Status.Data.Slave_DI_Data[Para_MbTCP.action_param[2].start_addr]);
Para_MbTCP.action_param[2].timer := 10; //命令执行时间等待间隔,单位ms
(************************************************************)
(* ModbusTCP Function Code 03 *)
(* Read Holding Registers *)
(************************************************************)
Para_MbTCP.action_enable[3].cyclic := 1; //循环执行
Para_MbTCP.action_enable[3].single := 0; //单次执行
Para_MbTCP.action_param[3].type := 3; //指令类型
Para_MbTCP.action_param[3].start_addr := 0; //起始地址
Para_MbTCP.action_param[3].quantity := 120; // Quantity数量上限为120。
Para_MbTCP.action_param[3].p_pv := ADR(Ctrl.Status.Data.Slave_AO_Data[Para_MbTCP.action_param[3].start_addr]);
Para_MbTCP.action_param[3].timer := 10; //命令执行时间等待间隔,单位ms
(************************************************************)
(* ModbusTCP Function Code 03 *)
(* Read Holding Registers *)
(************************************************************)
Para_MbTCP.action_enable[4].cyclic := 1; //循环执行
Para_MbTCP.action_enable[4].single := 0; //单次执行
Para_MbTCP.action_param[4].type := 3; //指令类型
Para_MbTCP.action_param[4].start_addr := 0; //起始地址
Para_MbTCP.action_param[4].quantity := 1; // Quantity数量上限为120。
Para_MbTCP.action_param[4].p_pv := ADR(Ctrl.Status.Data.Slave_AO_Data[Para_MbTCP.action_param[4].start_addr]);
Para_MbTCP.action_param[4].timer := 10; //命令执行时间等待间隔,单位ms
(************************************************************)
(* ModbusTCP Function Code 01 *)
(* Read Coils *)
(************************************************************)
Para_MbTCP.action_enable[5].cyclic := 1; //循环执行
Para_MbTCP.action_enable[5].single := 0; //单次执行
Para_MbTCP.action_param[5].type := 1; //指令类型
Para_MbTCP.action_param[5].start_addr := 49996; //起始地址
Para_MbTCP.action_param[5].quantity := 1; // Quantity数量上限为120。
Para_MbTCP.action_param[5].p_pv := ADR(Ctrl.Status.Data.Slave_DO_Data[Para_MbTCP.action_param[5].start_addr]);//目标变量
Para_MbTCP.action_param[5].timer := 10; //命令执行时间等待间隔,单位ms
(************************************************************)
(* ModbusTCP Function Code 02 *)
(* Read Input *)
(************************************************************)
Para_MbTCP.action_enable[6].cyclic := 1; //循环执行
Para_MbTCP.action_enable[6].single := 0; //单次执行
Para_MbTCP.action_param[6].type := 2; //指令类型
Para_MbTCP.action_param[6].start_addr := 49996; //起始地址
Para_MbTCP.action_param[6].quantity := 1; // Quantity数量上限为120。
Para_MbTCP.action_param[6].p_pv := ADR(Ctrl.Status.Data.Slave_DI_Data[Para_MbTCP.action_param[6].start_addr]);//目标变量
Para_MbTCP.action_param[6].timer := 10; //命令执行时间等待间隔,单位ms
(************************************************************)
(* ModbusTCP Function Code 03 *)
(* Read Holding Registers *)
(************************************************************)
Para_MbTCP.action_enable[7].cyclic := 1; //循环执行
Para_MbTCP.action_enable[7].single := 0; //单次执行
Para_MbTCP.action_param[7].type := 3; //指令类型
Para_MbTCP.action_param[7].start_addr := 49996; //起始地址
Para_MbTCP.action_param[7].quantity := 1; // Quantity数量上限为120。
Para_MbTCP.action_param[7].p_pv := ADR(Ctrl.Status.Data.Slave_AO_Data[Para_MbTCP.action_param[7].start_addr]);//目标变量
Para_MbTCP.action_param[7].timer := 10; //命令执行时间等待间隔,单位ms
(************************************************************)
(* ModbusTCP Function Code 04 *)
(* Read Input Registers *)
(************************************************************)
Para_MbTCP.action_enable[8].cyclic := 1; //循环执行
Para_MbTCP.action_enable[8].single := 0; //单次执行
Para_MbTCP.action_param[8].type := 4; //指令类型
Para_MbTCP.action_param[8].start_addr := 49996; //起始地址
Para_MbTCP.action_param[8].quantity := 1; // Quantity数量上限为120。
Para_MbTCP.action_param[8].p_pv := ADR(Ctrl.Status.Data.Slave_AI_Data[Para_MbTCP.action_param[8].start_addr]);//目标变量
Para_MbTCP.action_param[8].timer := 10; //命令执行时间等待间隔,单位ms
// (************************************************************)
// (* 单独单条指令测试 *)
// (* ModbusTCP Function Code 03 *)
// (* Read Holding Registers *)
// (************************************************************)
// Para_MbTCP.action_enable[0].cyclic := 1;
// Para_MbTCP.action_enable[0].single := 0;
// Para_MbTCP.action_param[0].type := 3;
// Para_MbTCP.action_param[0].start_addr := 0;
// Para_MbTCP.action_param[0].quantity := 1; // Quantity数量上限为120。
// Para_MbTCP.action_param[0].p_pv := ADR(Ctrl.Status.Data.Slave_AO_Data[Para_MbTCP.action_param[0].start_addr]);
// Para_MbTCP.action_param[0].timer := 10; //命令执行时间等待间隔,单位ms
(**************************************************************)
(* 测试通过观察值 *)
(**************************************************************)
t_bCheckDataFromSlave := FALSE;
t_bCheckDataFromSlaveLargeIndex := FALSE;
END_PROGRAM
PROGRAM _CYCLIC
(************************************************************************)
(* Master核心调用库 *)
(************************************************************************)
FB_MBclient_0.enable := TRUE;
(* ↓↓↓此端口为Client/Master本地占用端口,无实际约束↓↓↓ *)
FB_MBclient_0.port := Ctrl.Para.uUsePort;
FB_MBclient_0.serverPort := Ctrl.Para.uServPort;
FB_MBclient_0.p_cfg := ADR(Para_MbTCP);
FB_MBclient_0.receive_timeout := 2000;
FB_MBclient_0.server_ip_addr := Ctrl.Para.sIP;
FB_MBclient_0.unit_id;
FB_MBclient_0();
Ctrl.Status.bRunOK := NOT(UINT_TO_BOOL(FB_MBclient_0.status));
(************************************************************)
(* 测试验证部分代码 *)
(************************************************************)
IF Ctrl.Status.Data.Slave_AI_Data[5] = 123 AND Ctrl.Status.Data.Slave_AI_Data[6] = 456 AND Ctrl.Status.Data.Slave_AI_Data[79] = 79 AND
Ctrl.Status.Data.Slave_AO_Data[1998] = 789 AND Ctrl.Status.Data.Slave_DI_Data[0] = TRUE THEN
t_bCheckDataFromSlave := TRUE; //此变量为TRUE 说明测试正常。
END_IF;
IF t_bCheckDataFromSlave = TRUE THEN
Ctrl.Status.Data.Slave_AI_Data[5] := 0;
Ctrl.Status.Data.Slave_AI_Data[6] := 0;
Ctrl.Status.Data.Slave_AI_Data[79] := 79;
Ctrl.Status.Data.Slave_AO_Data[1998] := 0;
Ctrl.Status.Data.Slave_DI_Data[0] := FALSE ;
END_IF;
(*-----------------------大索引数据刷新-----------------------*)
IF Ctrl.Status.Data.Slave_AI_Data[49996] = 1234 AND Ctrl.Status.Data.Slave_DO_Data[49996] = TRUE AND
Ctrl.Status.Data.Slave_AO_Data[49996] = 4321 AND Ctrl.Status.Data.Slave_DI_Data[49996] = TRUE THEN
t_bCheckDataFromSlaveLargeIndex := TRUE; //此变量为TRUE 说明测试正常。
END_IF;
IF t_bCheckDataFromSlaveLargeIndex = TRUE THEN
Ctrl.Status.Data.Slave_AI_Data[49996] := 0;
Ctrl.Status.Data.Slave_DO_Data[49996] := FALSE;
Ctrl.Status.Data.Slave_AO_Data[49996] := 0;
Ctrl.Status.Data.Slave_DI_Data[49996] := FALSE ;
END_IF;
(******************************************************************************************)
(*** 统计数据刷新频率 ***)
(******************************************************************************************)
IF Ctrl.Status.Data.Slave_AO_Data[0] <> UINT_TO_INT(t_uLastDataVar) THEN
IF Ctrl.Status.Data.Slave_AO_Data[0] < UINT_TO_INT(t_uLastDataVar) THEN
t_uGetVarChangeSpeed := 32767 - t_uLastDataVar + Ctrl.Status.Data.Slave_AO_Data[0];
ELSE
t_uGetVarChangeSpeed := Ctrl.Status.Data.Slave_AO_Data[0] - t_uLastDataVar;
END_IF;
t_uLastDataVar := Ctrl.Status.Data.Slave_AO_Data[0];
(*--触发计数--*)
uDataChangeCount := uDataChangeCount + 1;
IF uDataChangeCount >= 4294967295 THEN
uDataChangeCount := 4294967295;
END_IF;
(*--统计数据变化情况--*)
IF uDataChangeCount >= 5 THEN //为避免第一次,历史缓存数据为0的情况出现,影响了Max数值的计算
GetVarChangeSpeed.uCurrentSpeed := t_uGetVarChangeSpeed;
MTDataMean_0(Enable := TRUE, In := t_uGetVarChangeSpeed);
GetVarChangeSpeed.uMean := REAL_TO_UINT(MTDataMean_0.Out);
MTDataMinMax_0(Enable := TRUE, In := t_uGetVarChangeSpeed);
GetVarChangeSpeed.uMax := REAL_TO_UINT(MTDataMinMax_0.MaxValue);
GetVarChangeSpeed.uMin := REAL_TO_UINT(MTDataMinMax_0.MinValue);
END_IF;
END_IF;
END_PROGRAM
PROGRAM _EXIT
END_PROGRAM