MbTCPMaster.st

<< 点击显示目录 >>

主页  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