此处用到一个结构体和全局变量;
TYPE ModbusCmd : ( MODBUS_READ_COILS := 16#01, (* 读线圈 *) MODBUS_READ_DISCRETE_INPUTS := 16#02, (* 读输入线圈 *) MODBUS_READ_HOLDING_REGISTERS := 16#03, (* 读保持寄存器 *) MODBUS_READ_INPUT_REGISTERS := 16#04, (* 读输入寄存器 *) MODBUS_WRITE_SINGLE_COIL := 16#05, (* 写单个线圈 *) MODBUS_WRITE_SINGLE_REGISTER := 16#06, (* 写单个寄存器 *) MODBUS_READ_EXCEPTION_STATUS := 16#07, (* 读异常状态 *) MODBUS_WRITE_MULTIPLE_COILS := 16#0F, (* 写多个线圈 *) MODBUS_WRITE_MULTIPLE_REGISTERS := 16#10, (* 写多个寄存器 *) MODBUS_REPORT_SLAVE_ID := 16#11, (* 读从设备ID号 *) MODBUS_MASK_WRITE_REGISTER := 16#16, (* 写屏蔽寄存器 *) MODBUS_WRITE_AND_READ_REGISTERS := 16#17 (* 读/写多个寄存器 *) ); END_TYPE
(* 自主定义Modbus *) VAR_GLOBAL COIL_STAT_Auto: ARRAY[0..149] OF BOOL; //(读线圈)线圈状态寄存器 1位,最高150个,客户端只写,服务端只读 用法COIL_STAT[0] IN_STAT_Auto: ARRAY[0..149] OF BOOL; //(写线圈)输入状态寄存器1位,最高150个,客户端只读,服务端只写 用法IN_STAT[0] HOLD_REG_Auto: ARRAY[0..149] OF INT; //(读寄存器)保持寄存器 16位,最高150个,客户端只写,服务端只读 用法HOLD_REG[0] IN_REG_Auto: ARRAY[0..149] OF INT; //(写寄存器)输入寄存器16位,最高150个,客户端只读,服务端只写 用法IN_REG[0] //总切换按钮 GC_bTCP: BOOL; //RTU/TCP GC_bRTU: BOOL; //RTU/TCP GC_bRTU_MASTER: BOOL; //RTU 主站 GC_bRTU_Slave: BOOL; //RTU 从站 GC_bTCP_Server: BOOL; //TCP 服务端 GC_bTCP_Client: BOOL; //TCP 客户端 //MoGC_dbus TCP Server GC_wPortServerTCP: WORD:= 502; //端口 GC_udiNumServerTCP: INT:= 10;//64; //寄存器个数 GC_UnitIDServer: UINT:= 1; //ID //MoGC_dbus TCP Client GC_UnitIDClient: UINT:= 1; //ID GC_IPAddrClient: STRING:= '10.10.56.115'; //IPAddrClient GC_Address: DWORD:= 0; //起始地址 GC_wPortClientTCP: WORD:= 502; //端口 GC_udiNumClientTCP: INT:=10;//64; //寄存器个数50 //MoGC_dbus RTU Master GC_dwBaudRateMaster: WORD:= 9600; //波特率 GC_DeviceMaster: UINT:=0; //串口号 GC_udiNumMaster: INT:=10;//64; //寄存器个数 //MoGC_dbus RTU Slave GC_dwBaudRateSlave: WORD:= 9600; //波特率 GC_DeviceSlave: UINT:=0; //串口号 GC_udiNumSlave: INT:=10;//64; //寄存器个数 //Modbus通讯心跳 GC_bSwitchConnect: BOOL; //通讯开关 GC_bAlarmConnect: BOOL; //通讯报警---映射(任意) GC_bResetConnect: BOOL; //复位报警---映射(任意) GC_iDelayTimeConnect: INT; //延时时间 GC_HoldRegConnect: INT; //读取对方数据 一定时间内没变化就报警---映射(读取保持寄存器) GC_InputRegConnect: INT; //写给对方的 0<>1---映射 (写入寄存器) END_VAR
(* 1、V1.4.5UI界面化 (1)、Modbus TCP && RTU (2)、外部轴 ExtAxis 同步和非同步 *) PROGRAM ModbusAuto VAR //实例化 TCP ModbusTCP_Server: ModbusTCP_Server; ModbusTCP_Client: ModbusTCP_Client; //实例化 RTU ModbusRTU_Master: ModbusRTU_Master; ModbusRTU_Slave: ModbusRTU_Slave; iCounter: INT; BTEST: BOOL; ///////////////////////////// //配方变量定义 //配方定义变量 iRecipeStatus: INT:=0; //状态机 iDelay_Count: INT; //延时 bStart_E: BOOL; bReadRecipeBusy_Ex: BOOL; bReadRecipeDone_Ex: BOOL; dReadAndSaveAs: DWORD; //读取PLC并保存成文件形式 dLoadfromRecipe: DWORD; //从具体配方文件中载入PLC值 dReadAndSaveRecipe: DWORD; //将当前改变的PLC值保存到具体配方文件中 strDefiniRecipesName: STRING(10):='Recipes'; //配方定义名 strRecipesName: STRING(10):='Recipes'; //配方名 FileName_Ex: STRING(100):='/usr/codesys/CODESYSControl/Recipes.hst'; //配方路径 RecipeManCommands: RecipeManCommands; //配方函数 ExternalRecipe_RTRIG: R_TRIG; //上升沿 ExternalRecipe_FTRIG: F_TRIG; //下降沿 //文件保存变量 iFileStatus: INT; stParaFileName: STRING(100); FileName_Para: STRING:='ParVarSaveFile'; Fileopen: FILE.Open; //文件打开模块 FileSize: FILE.GetSize; //获取文件大小 FileWrite: FILE.Write; //文件写入模块 FileClose: FILE.Close; //文件关闭模块 FileRead: FILE.Read; //文件读取模块 ////////////////////////// bTest1: BOOL; END_VAR //TCP RTU GC_bTCP:= FALSE; GC_bRTU:= TRUE; IF GC_bTCP=TRUE AND GC_bRTU=FALSE THEN ACT_ModbusTCP(); ELSIF GC_bTCP=FALSE AND GC_bRTU=TRUE THEN ACT_ModbusRTU(); END_IF
//Modbus RTU GC_bRTU_MASTER:= FALSE; GC_bRTU_Slave:= true; IF GC_bRTU_MASTER=TRUE AND GC_bRTU_Slave=FALSE THEN //默认是主站 ModbusRTU_Master( dwBaudRate:= GC_dwBaudRateMaster, Device:= GC_DeviceMaster, NumBits:= GC_udiNumMaster, NumInputBits:= GC_udiNumMaster, NumRegisters:= GC_udiNumMaster, NumInputRegisters:= GC_udiNumMaster, tab_bits:= COIL_STAT_Auto, tab_inputbits:= IN_STAT_Auto, tab_regs:= HOLD_REG_Auto, tab_inputregs:= IN_REG_Auto); ELSIF GC_bRTU_MASTER=FALSE AND GC_bRTU_Slave=TRUE THEN //从站 ModbusRTU_Slave( dwBaudRate:= GC_dwBaudRateSlave, Device:= GC_DeviceSlave, NumBits:= GC_udiNumMaster, NumInputBits:= GC_udiNumSlave, NumRegisters:= GC_udiNumSlave, NumInputRegisters:= GC_udiNumSlave, tab_bits:= COIL_STAT_Auto, tab_inputbits:= IN_STAT_Auto, tab_regs:= HOLD_REG_Auto, tab_inputregs:= IN_REG_Auto, Status=> , errorID=> ); END_IF
//Modbus TCP GC_bTCP_Server:= FALSE; GC_bTCP_Client:= TRUE; IF GC_bTCP_Server=TRUE AND GC_bTCP_Client=FALSE THEN //默认是服务端 ModbusTCP_Server( UnitID:=GC_UnitIDServer, wPort:= GC_wPortServerTCP, NumBits:= GC_udiNumServerTCP, NumInputBits:= GC_udiNumServerTCP, NumRegisters:= GC_udiNumServerTCP, NumInputRegisters:= GC_udiNumServerTCP, tab_bits:= COIL_STAT_Auto, tab_inputbits:= IN_STAT_Auto, tab_regs:= HOLD_REG_Auto, tab_inputregs:= IN_REG_Auto, Status=> , error=> ); ELSIF GC_bTCP_Server=FALSE AND GC_bTCP_Client=TRUE THEN//客户端 ModbusTCP_Client( IPAddr:= GC_IPAddrClient, wPort:= GC_wPortClientTCP, UnitID:= GC_UnitIDClient, Address:= GC_Address, NumBits:= GC_udiNumClientTCP, NumInputBits:= GC_udiNumClientTCP, NumRegisters:= GC_udiNumClientTCP, NumInputRegisters:= GC_udiNumClientTCP, tab_bits:= COIL_STAT_Auto, tab_inputbits:= IN_STAT_Auto, tab_regs:= HOLD_REG_Auto, tab_inputregs:= IN_REG_Auto, Status=> , errorID=> ); END_IF