Udało się. Na forum Siemensa kolega Piotr.M naskrobał piękny fragment kodu który działa.
---
Function which converts
I0.0 to I999.7 --> 10000..19997
Q0.0..Q999.7 --> 00000..09997
M0.0..M999.7 --> 20000..29997
DBX0.0..999.7-->30000..39997
DIX0.0..999.7 -->40000..49997
// Inputs
I_ADDRESS : Bool;
// Temp
Point : DWord;
Area : Int;
Address : Int;
Ret_Val : DInt // Result
ENO=1 when OK otherwise ENO=0
//Convert I/Q/M/DB/DI Address to x0000..x9997 (x=0..4)
Outputs: 00000 - 09997; inputs: 10000-19997; memory: 20000-29997;
Data Block: 30000 - 39997; Instance: 40000-49997
// NW1 - extract area & address
L P##I_ADDRESS // Pointer to the address
T #Point // Store in local variable
SRD 24 // Extract Area
AW W#16#7 // flter 8
T #Area // 1: DI; 2: DQ; 3: M; 4: DBX; 5: DIX; 6: N/A;
// 7: INVALID (const or DBxxx.DBXyyy.z)
L 7 // invalid?
==I
JC ERR // jump to ERROR - return 0 & ENO=False
L #Point // Pointer
AD DW#16#FFFFFF // Filter Area - extract address
SRD 3 // Extract Byte Address
L 10 // and mul by 10
*I
T #Address // for I123.4 this will be 1230
L #Point // Pointer
AD DW#16#7 // Extract Bit Number (last 3 bits)
L #Address
+I
T #Address // Final Byte Address 0000..9997
// NW2: Select Area
L #Area // Area
JL LSTX // List of Jumps
JU ERR // 0 = Error
JU AR_I // 1 = Inputs
JU AR_Q // 2 = Outputs
JU AR_M // 3 = Memory
JU ARDB // 4 = DBX
JU ARDI // 5 = DIX
LSTX: JU ERR // ELSE = ERROR
// NW3: Inputs
AR_I: L #Address
L 10000
+I
T #RET_VAL
SET
SAVE
BE
// NW4: Outputs
AR_Q: L #Address
T #RET_VAL
SET
SAVE
BE
// NW5: Memory Bits
AR_M: L #Address
L 20000
+I
T #RET_VAL
SET
SAVE
BE
// NW6: DBX
ARDB: L #Address
L 30000
+D
T #RET_VAL
SET
SAVE
BE
// NW7: DIX
ARDI: L #Address
L L#40000
+D
T #RET_VAL
SET
SAVE
BE
// NW8: ERROR
ERR: L L#0
T #RET_VAL
CLR
SAVE
!!!! BEWARE !!!!!
call it in STL. do NOT call it in LAD because it will see a TEMP variable!
the LAD call
------------|FC |
I123.4-| |-MD30
in STL looks like
A I 123.4
= L 20.0
BLD 103
CALL "FC"
I_ADDRESS:=L20.0 // function see L20.0 instead of I123.4!!!!!!!
RET_VAL :=MD70
NOP 0