meta data for this page
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| automation:direct_indirect_addressing [2026/01/15 15:37] – created vamsan | automation:direct_indirect_addressing [2026/01/16 17:24] (current) – vamsan | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | === Direct / indirect addressing === | + | === Direct/ |
| Addressing methods are mostly tied to variable types, not areas, so the following procedures apply to both DB and Tag variables. | Addressing methods are mostly tied to variable types, not areas, so the following procedures apply to both DB and Tag variables. | ||
| + | |||
| + | == Direct addressing == | ||
| + | {{anchor: | ||
| + | Direct addressing in Simatic is typically symbolic addressing, meaning in the simplest case we correspond two variables of the same type to each other: | ||
| + | |||
| + | <code pascal> | ||
| + | fromReal : Real; | ||
| + | fromInt : Int; | ||
| + | toReal : Real; | ||
| + | toInt : Int; | ||
| + | … | ||
| + | |||
| + | #toInt := #fromInt; | ||
| + | #toReal := #fromReal; | ||
| + | </ | ||
| + | |||
| + | If the types do not match, conversion will help us: | ||
| + | |||
| + | <code pascal> | ||
| + | #toInt := REAL_TO_INT(IN := #fromReal); | ||
| + | </ | ||
| + | |||
| + | <WRAP center round important 100%> | ||
| + | It is crucial to understand that conversion can lead to data loss. In the example above, the [[# | ||
| + | </ | ||
| + | |||
| + | Direct addressing is also applicable to [[# | ||
| + | |||
| + | Another approach is direct addressing, which involves referring to a variable' | ||
| + | |||
| + | == Slice addressing == | ||
| + | {{anchor: | ||
| + | Slice addressing involves dividing a memory region, such as a byte or a word, into smaller segments, such as booleans. With S7-1200 and S7-1500, you can target specific parts within declared variables (**only by byte, word, dword**) and access segments of 1, 8, 16, or 32 bits. | ||
| + | |||
| + | {{: | ||
| + | |||
| + | The following example is a SPLIT function that splits a WORD Input variable into bits: | ||
| + | |||
| + | <code pascal> | ||
| + | // FC Input : inWord (Word) | ||
| + | // FC output: 16 variable bit0..bit15 (Bool) | ||
| + | // splitting | ||
| + | #bit0 := # | ||
| + | #bit1 := # | ||
| + | #bit2 := # | ||
| + | #bit3 := # | ||
| + | #bit4 := # | ||
| + | #bit5 := # | ||
| + | #bit6 := # | ||
| + | #bit7 := # | ||
| + | #bit8 := # | ||
| + | #bit9 := # | ||
| + | #bitA := # | ||
| + | #bitB := # | ||
| + | #bitC := # | ||
| + | #bitD := # | ||
| + | #bitE := # | ||
| + | #bitF := # | ||
| + | </ | ||
| + | |||
| + | == Pointer; indirect addressing == | ||
| + | {{anchor: | ||
| + | In the TIA Portal, there are two ways to perform indirect addressing or pointer referencing: | ||
| + | Using a pointer essentially involves moving a data block of a specific size to a memory area of the same size. This operation ignores the structure and variables within the data area, making it a quick and useful method when applied carefully. **However, careless use of this tool can be very risky.** | ||
| + | |||
| + | A key issue is that it doesn' | ||
| + | |||
| + | == ANY type == | ||
| + | {{anchor: | ||
| + | Structure of the ANY Pointer (**10 Bytes**): | ||
| + | |||
| + | |< 100% 20% 20% 60%> | ||
| + | ^Name^Length^Description| | ||
| + | ^Syntax ID|1 byte|Always 16#10 for S7| | ||
| + | ^Data Type|1 byte|Code for the type of data being pointed to (e.g., 16#02 for Byte; see below in the table "TIA Coding of data types" | ||
| + | ^Repetition Factor|2 bytes|Number of elements of the specified data type| | ||
| + | ^DB Numbe|2 bytes|The number of the data block (0 if not in a DB)| | ||
| + | ^Memory Area|1 byte|Code for the memory area (e.g., 16#84 for DB; see below in the table "TIA Coding of the memory area" | ||
| + | ^Address|3 bytes|The start address of the data (bit and byte address)| | ||
| + | |||
| + | {{page> | ||
| + | |||
| + | {{page> | ||
| + | |||
| + | == Example of using the ANY type == | ||
| + | |||
| + | The pointer with the ANY type is most frequently used with the [[# | ||
| + | |||
| + | <code pascal> | ||
| + | CASE " | ||
| + | 1: // ASS1 data to disp 1 | ||
| + | #state := BLKMOV(SRCBLK := P# | ||
| + | 2: // ASS1 data to disp 2 | ||
| + | #state := BLKMOV(SRCBLK := P# | ||
| + | 3: // ASS1 data to disp 3 | ||
| + | #state := BLKMOV(SRCBLK := P# | ||
| + | ELSE // Statement section ELSE | ||
| + | ; | ||
| + | END_CASE; | ||
| + | </ | ||
| + | == VARIANT versus ANY == | ||
| + | |||
| + | * **ANY** is a fixed 10-byte structure that references an absolute memory address. | ||
| + | * **VARIANT** is a type-safe pointer that preserves the original data type information and enables symbolic addressing without the need for fixed memory location overhead. | ||
| + | * The **ANY** is an older type, already available in the S300 / 400 series. | ||
| + | * The **ANY** can only be used with the S7-1500, whereas **VARIANT** are accessible on all S7 models. | ||
| + | |||
| + | |||
| + | == VARIANT type == | ||
| + | {{anchor: | ||
| + | A VARIANT type parameter is a pointer that can reference various data types beyond a simple instance. This pointer can be an object of a basic data type like [[# | ||
| + | |||
| + | <WRAP center round important 80%> | ||
| + | * Directly assigning a tag to a VARIANT, like //myVARIANT := # | ||
| + | * Direct reading or writing of a signal from an I/O input or output is only possible with an S7-1500 module. | ||
| + | * You can only reference a complete data block if it was originally created from a user-defined data type ([[# | ||
| + | </ | ||