|
1、在库管理器中添加ModbusFB库
主要使用下面的FB功能块实现对各个数据区域的读写操作
2、下例为通过状态机循环轮询访问方式实现对保持寄存器的读写以及线圈的读写的操作 2.1FB功能块实例化以及相关变量定义 VAR // RTU 驱动 fbRTU : ModbusFB.ClientSerial; xConnect: BOOL := TRUE; xConnected : BOOL; // ================== 读保持寄存器 fbReadHolding : ModbusFB.ClientRequestReadHoldingRegisters; arReadData : ARRAY[0..9] OF WORD; // ================== 写保持寄存器 fbWriteHolding : ModbusFB.ClientRequestWriteMultipleRegisters; uiWriteValue : ARRAY[0..9] OF WORD ; // 要写入的值 // ================== 读线圈(0x) fbReadCoil : ModbusFB.ClientRequestReadCoils; bCoilValue : BOOL; // 读到的线圈状态 // ================== 写线圈 fbWriteCoil : ModbusFB.ClientRequestWriteSingleCoil; bSetCoil : BOOL := TRUE; // 要写的线圈状态 // 状态机 + 定时 tReadTimer : TON; eState : (IDLE, READ_HOLD, WRITE_HOLD, READ_COIL, WRITE_COIL) := IDLE; xExecute : BOOL; END_VAR 2.2程序实现 // RTU 驱动 fbRTU( xConnect:=xConnect , iPort:=2 , dwBaudrate:= SysCom.SYS_BR_115200, byDataBits:= 8, eParity:=SysCom.SYS_COM_PARITY.SYS_NOPARITY, eStopBits:=SysCom.SYS_COM_STOPBITS.SYS_ONESTOPBIT , eRtuAscii:=ModbusFB.RtuAscii.RTU ); // 1. 读保持寄存器 40001 fbReadHolding( rClient := fbRTU, xExecute := xExecute AND (eState = READ_HOLD), uiUnitId := 1, uiStartItem := 0, uiQuantity := 10, pData := ADR(arReadData) ); // 2. 写保持寄存器 40010 fbWriteHolding( rClient := fbRTU, xExecute := xExecute AND (eState = WRITE_HOLD), uiUnitId := 1, uiStartItem:=10 , uiQuantity:= 10, pData:=ADR(uiWriteValue)); // 3. 读线圈 00001 fbReadCoil( rClient := fbRTU, xExecute := xExecute AND (eState = READ_COIL), uiUnitId := 1, uiStartItem := 0, uiQuantity := 1, pData := ADR(bCoilValue) ); // 4. 写线圈 00001 fbWriteCoil( rClient := fbRTU, xExecute := xExecute AND (eState = WRITE_COIL), uiUnitId := 1, uiItem := 0, xValue := bSetCoil ); // RTU 专用稳定轮询 IF fbRTU.xConnected THEN CASE eState OF IDLE: eState := READ_HOLD; READ_HOLD: IF fbReadHolding.xDone OR fbReadHolding.xError THEN eState := WRITE_HOLD; END_IF; WRITE_HOLD: IF fbWriteHolding.xDone OR fbWriteHolding.xError THEN eState := READ_COIL; END_IF; READ_COIL: IF fbReadCoil.xDone OR fbReadCoil.xError THEN eState := WRITE_COIL; END_IF; WRITE_COIL: IF fbWriteCoil.xDone OR fbWriteCoil.xError THEN eState := READ_HOLD; END_IF; END_CASE; xExecute := TRUE; ELSE xExecute := FALSE; eState := IDLE; END_IF;
|