Cos function, Cos( a ) – Delta RMC151 User Manual
Page 364
RMC70/150 and RMCTools User Manual
The ADDR_OFS function can be used to calculate an address from a base address and an
offset. For example, if the first tag in the block is called MyFirstTag, then the address of a
tag located 4 registers after MyFirstTag can be calculated with:
ADDR_OFS( MyFirstTag, 4)
This is useful when copying from blocks of data that are not declared as arrays. However,
best programming practice is usually to set up the data in arrays, and use the COPY
function on those arrays, which makes the ADDR_OFS unnecessary.
Example: Simple
Consider a block of 30 miscellaneous parameters in the variable table, each as individual
tags. Suppose the user wants to load these parameters using a 14-register PROFIBUS
buffer. Therefore, on each subsequent cycle of receiving PROFIBUS data, the following
three copy commands would be issued:
COPY(ProfiData[2], MyFirstTag, 14);
COPY(ProfiData[2], MyFifteenthTag, 14);
COPY(ProfiData[2], MyTwentyNinthTag, 2);
This would be difficult to maintain if a tag is inserted. Consider how the following is more
maintainable:
COPY(ProfiData[2], ADDR_OFS(MyFirstTag,0), 14);
COPY(ProfiData[2], ADDR_OFS(MyFirstTag,14), 14);
COPY(ProfiData[2], ADDR_OFS(MyFirstTag,28), 2);
This method can also easily be used to make the length general and put in a loop.
Example: Looping from PROFIBUS Master
This example introduces an advanced and code-efficient manner of using the COPY and
ADDR_OFS functions to copy large amounts of data via a small PROFUBUS buffer.
Suppose the first data item of the PROFIBUS buffer contained length and offset
information, packed into the lower and upper 16 bits of the register. The PROFIBUS
master would control the offset and length of the writes. There would be no need to
implement looping logic in the RMC, and the handshaking would be reduced.
The code could look like similar to this:
CopyLen := DWORD_TO_DINT(SHR(ProfiData[1], 16));
CopyOffset := DWORD_TO_DINT(ProfiData[1] AND 0xFFFF);
COPY(ProfiData[2], ADDR_OFS(MyFirstReg, CopyOffset), CopyLen);
This example could be further improved to be more safe. For example:
CopyLen := DWORD_TO_DINT(SHR(ProfiData[1], 16));
If ( CopyLen > 0 ) Then
CopyOffset := DWORD_TO_DINT(ProfiData[1] AND 0xFFFF);
If ( CopyOffset < MaxOffset AND CopyOffset + CopyLen <= MaxOffset ) Then
COPY(ProfiData[2], ADDR_OFS(MyFirstReg, CopyOffset), CopyLen);
Else
LOG_EVENT(10, CopyOffset, CopyLen);
End If
End If
The Log_Event function would provide the user with some indication of the fault.
5.14.2.10. COS Function
344
Delta Computer Systems, Inc.