Overview: SCL in the TIA Portal Environment
SCL (Structured Control Language) is the IEC 61131-3 ST (Structured Text) compliant high-level language for SIMATIC S7-300, S7-400, S7-1200, S7-1500, ET 200SP CPUs, and WinAC RTX. Within TIA Portal, SCL replaces the classic STEP 7 SCL/STL editor pair, providing syntax-driven editing, integrated cross-reference, online watch, and full symbolic plus absolute addressing.
For engineers migrating from classic STEP 7, the most common question is how to read PIW 256 and write PQW 272 in SCL. This reference consolidates the syntax for every supported CPU family, distinguishes image-table access from peripheral-direct access, and covers the related indirect-addressing primitives (PEEK, POKE, VARIANT tags, and DB-Any pointers) that replace the legacy STL L PIW/T PQW patterns.
Prerequisites and Version Matrix
Before writing a single line of SCL, lock down three variables. The behavior of I/O accessors, the supported data types, and the presence of certain compiler optimizations depend on all three.
| Variable | Required Detail | Example |
|---|---|---|
| CPU family | S7-1200, S7-1500, S7-300/400, ET 200SP CPU, IPC, or WinAC | 6ES7515-2AM02-0AB0 (S7-1500), 6ES7215-1AG40-0XB0 (S7-1200) |
| CPU firmware | Firmware version affects the supported data types and instruction set | V2.9.x for S7-1500, V4.5.x for S7-1200 |
| TIA Portal | Major version plus update level | V17 Update 4, V18 Update 2, V19 |
Inside TIA Portal, open the project tree, select the PLC, and confirm the firmware under PLC > Properties > General > Identification. The order number (MLFB) and firmware version appear in the identification panel. Cross-reference this against the TIA Portal release notes for the installed version.
Direct I/O Access Syntax in SCL: %I, %Q, %IW, %QW, %ID, %QD
SCL in TIA Portal uses the IEC 61131-3 standardized absolute address notation. The percent sign (%) prefixes the location, followed by size, area, and offset.
| Legacy STEP 7 (STL/LAD/FBD) | SCL under TIA Portal | Size | Process Image |
|---|---|---|---|
E 0.0 |
%I0.0 |
1 bit | Input image (I) |
EB 1 |
%IB1 |
1 byte | Input image |
EW 2 |
%IW2 |
1 word (16 bit) | Input image |
ED 4 |
%ID4 |
1 double word (32 bit) | Input image |
A 8.0 |
%Q8.0 |
1 bit | Output image (Q) |
AB 10 |
%QB10 |
1 byte | Output image |
AW 12 |
%QW12 |
1 word | Output image |
AD 16 |
%QD16 |
1 double word | Output image |
M 20.0 |
%M20.0 |
1 bit | Bit memory |
DB10.DBW 0 |
"myDB".myWord or %DB10.DBW0
|
1 word | Data block |
The TIA Portal compiler warns if the size of the operand does not match the surrounding expression. A %IW256 read into an INT tag is valid; assigning it to a BOOL triggers a type-mismatch error during the consistency check.
Example reads and writes in an SCL source file:
// SCL example: read input word, branch, and write output word
FUNCTION_BLOCK fb_IO_Access
VAR
iRawAI : INT; // mapped to %IW256
qRawAO : INT; // mapped to %QW272
bEnable : BOOL; // mapped to %I0.0
bFaultAck : BOOL; // mapped to %Q8.0
rScaled : REAL;
END_VAR
BEGIN
// Read process image of inputs
IF bEnable THEN
iRawAI := %IW256;
rScaled := INT_TO_REAL(iRawAI) * 0.1;
qRawAO := REAL_TO_INT(rScaled);
ELSE
qRawAO := 0;
END_IF;
// Acknowledge fault
IF %I0.1 THEN
bFaultAck := TRUE;
END_IF;
// Write to output image
%QW272 := qRawAO;
%Q8.0 := bFaultAck;
END_FUNCTION_BLOCK
This is functionally equivalent to the classic LAD/FBD contact network that uses PIW256 and PQW272 in move boxes. The symbolic alternative ("AI_ProcessWord", "AO_ControlWord") is preferred for readability and is automatically updated by the cross-reference.
The :P Suffix for Peripheral-Direct Access
Standard %IW and %QW addresses access the process image, which is refreshed once per OB1 cycle (or at the configured update time for partial process images). When the application requires the value at the exact moment of access (for example, a high-speed input that updates between OB1 scans, or an output that must be updated immediately), use the :P (peripheral) suffix.
| Notation | Access Path | Latency | Use Case |
|---|---|---|---|
%IW256 |
Process input image (PII) | Up to one OB1 cycle | Standard cyclic I/O |
%IW256:P |
Direct peripheral read of PIW256 | Backplane bus access, ~1 ms typical | Time-critical inputs, diagnostics |
%QW272 |
Process output image (PIQ) | Up to one OB1 cycle | Standard cyclic outputs |
%QW272:P |
Direct peripheral write of PQW272 | Backplane bus access, immediate | Fast outputs, safety I/O |
:P access initiates a backplane read/write. Use it sparingly inside time-critical loops. A burst of :P accesses on a remote ET 200SP station can saturate PROFINET IO and degrade the bus cycle. The S7-1500 instruction list shows the exact cycle cost; for an S7-1516 the peripheral read latency to a central rack is ~1 µs, while a PROFINET IO round-trip is ~1 ms.Direct peripheral access in SCL:
// Read the raw input word directly from the module
iRawStatus := %IW256:P;
// Write a control word directly to the output module
%QW272:P := iControlValue;
// Direct access to a single bit in the input peripheral area
bDiagFlag := %I256.0:P;
The :P suffix is supported on S7-1500 and S7-1200 firmware V4.0 and later, and on S7-300/400 when the address is configured in the hardware. The S7-1200 firmware V4.0 release notes document the introduction of the peripheral-direct read for the high-speed counters on the CPU board.
PEEK and POKE for Indirect Addressing
When the I/O address must be computed at runtime (for example, indexing a vector of 16 analog inputs whose hardware slot is only known during commissioning), use the PEEK and POKE instructions. These are SCL system functions that read or write a single byte, word, or double word from a parameterized area at a parameterized byte offset.
| Function | Return Type | Purpose |
|---|---|---|
PEEK(area, byteOffset) |
BYTE | Read 1 byte at bit offset byteOffset from area |
PEEK_WORD(area, byteOffset) |
WORD | Read 1 word (2 bytes) |
PEEK_DWORD(area, byteOffset) |
DWORD | Read 1 double word (4 bytes) |
PEEK_BOOL(area, byteOffset) |
BOOL | Read 1 bit |
POKE(area, byteOffset, value) |
(procedure) | Write 1 byte |
POKE_BOOL(area, byteOffset, value) |
(procedure) | Write 1 bit |
The area constant is a hexadecimal literal that selects the memory region:
| Area Constant (UINT) | Memory Region | Legacy Equivalent |
|---|---|---|
16#81 |
Process input image (PI / PE) |
PEW / PED
|
16#82 |
Process output image (PQ / PA) |
PAW / PAD
|
16#83 |
Bit memory (M) |
MW / MD
|
16#84 |
Global data block (DB) |
DBW / DBD
|
The byteOffset parameter is given in bits, not bytes. To address PIW256, the offset is 256 × 8 = 2048 bits. To address PQW272, the offset is 272 × 8 = 2176 bits.
PEEK example reading PIW256 as a word:
FUNCTION fc_ReadIndirectAI : WORD
VAR_INPUT
iByteOffset : DINT; // in bits
END_VAR
VAR
wValue : WORD;
END_VAR
BEGIN
wValue := PEEK_WORD(area := 16#81, byteOffset := iByteOffset);
fc_ReadIndirectAI := wValue;
END_FUNCTION
POKE example writing PQW272 as a word:
PROCEDURE proc_WriteIndirectAO
VAR_INPUT
iByteOffset : DINT; // in bits
wValue : WORD;
END_VAR
BEGIN
POKE(area := 16#82, byteOffset := iByteOffset, value := wValue);
END_PROCEDURE
For further detail, see the Siemens Industry Online Support entry ID 109011420, "In STEP 7 (TIA Portal), how can you implement indirect addressing in an SCL program?" which contains a full discussion of PEEK, POKE, VARIANT, and DB-Any pointer techniques.
CPU Family Differences
Although the SCL syntax is largely identical across SIMATIC families, the supported data types, instruction extensions, and addressing rules differ. Treat the following as a commissioning checklist.
| Feature | S7-300/400 | S7-1200 (FW V4.x) | S7-1500 (FW V2.x) | ET 200SP CPU |
|---|---|---|---|---|
%IW / %QW image access |
Yes | Yes | Yes | Yes |
:P peripheral direct |
Yes (configured addr) | Yes (FW V4.0+) | Yes | Yes |
PEEK / POKE
|
Yes (legacy syntax) | Yes | Yes | Yes |
| Optimized block access | No | Default since V4.0 | Default | Default |
| Symbolic I/O tag | Yes | Yes (recommended) | Yes (recommended) | Yes |
| VARIANT in FB | Limited | Yes | Yes | Yes |
| Multi-instance DBs | Yes | Yes | Yes (preferred) | Yes |
| SCL language package | Optional add-on | Included | Included | Included |
%IW256 access against an optimized tag if the access conflicts with the symbol table. To force absolute access for a tag, open PLC tags > Default tag table > Show/hide and add the I/O address with the Accessible from SCL attribute, or use the Hardware identifier instead of the address.For S7-300/400, the legacy STL approach of loading a word via L PIW 256 and transferring via T PQW 272 is still valid in TIA Portal, but SCL gives you a typed, debuggable equivalent that integrates with the cross-reference.
TIA Portal Version Considerations and Known Bug Classes
Field experience shows that SCL compilation passes differ noticeably between TIA Portal major versions. The following are recurring failure modes reported in production plants, summarized by major version family.
| TIA Version | Known SCL Issue | Workaround |
|---|---|---|
| V11 | Unstable SCL editor; SCL blocks occasionally corrupt on save | Avoid if SCL is the primary language |
| V13 | Indirect addressing edge cases; some PEEK functions return inconsistent types |
Use explicit type conversion |
| V14 / V14 SP1 | New compiler family; complex SCL constructs (nested CASE with VARIANT) may mis-compile |
Split blocks, avoid deep nesting, apply the latest hotfix |
| V15 / V15.1 | Performance regression on S7-1500 with large SCL FBs | Update to V15.1 + Update 3 or later |
| V16 / V17 | Watch table on PEEK/POKE temporary results may show stale values | Force an online refresh; pin a snapshot tag |
| V18 / V19 | Rare incorrect code generation for SCL FOR loops with optimized array access |
Refer to the TIA Portal release notes for the latest service pack |
Always run the TIA Portal Software Update tool from the Siemens Industry Online Support portal and apply the latest Service Pack + Update combination for the installed major version. The release notes list every closed SCL compiler bug with the ID in the Entries database.
Code Example: Complete Function Block
The following FB reads eight 16-bit analog inputs from a parameterized base address, scales each with a per-channel gain and offset, and writes eight scaled values to a parameterized output base. It uses PEEK_WORD and POKE for indirect addressing, and demonstrates :P access for the diagnostics channel.
FUNCTION_BLOCK fb_AnalogVector
VAR
aiBaseIn : DINT; // base byte offset of AI vector (bits)
aoBaseOut : DINT; // base byte offset of AO vector (bits)
aGain : ARRAY[1..8] OF REAL := [8(1.0)];
aOffset : ARRAY[1..8] OF REAL := [8(0.0)];
aScaled : ARRAY[1..8] OF REAL;
wDiagWord : WORD;
bOverflow : ARRAY[1..8] OF BOOL;
END_VAR
VAR_TEMP
i : INT;
iOff : DINT;
wRaw : WORD;
iRaw : INT;
END_VAR
BEGIN
FOR i := 1 TO 8 DO
// Compute the bit offset for channel i (16 bits per word)
iOff := aiBaseIn + (DINT_TO_DINT(i - 1) * 16);
// Read raw value (peripheral-direct for diagnostics-grade latency)
wRaw := PEEK_WORD(area := 16#81, byteOffset := iOff);
iRaw := WORD_TO_INT(wRaw);
// Scale
aScaled[i] := INT_TO_REAL(iRaw) * aGain[i] + aOffset[i];
// Range check
IF aScaled[i] > 27648.0 THEN
bOverflow[i] := TRUE;
aScaled[i] := 27648.0;
END_IF;
// Write scaled value back to output vector
iOff := aoBaseOut + (DINT_TO_DINT(i - 1) * 16);
POKE(area := 16#82, byteOffset := iOff, value := REAL_TO_INT(aScaled[i]));
END_FOR;
// Diagnostics: read status word from PIW258 directly
wDiagWord := %IW258:P;
END_FUNCTION_BLOCK
This pattern replaces a hand-written loop in STL with a type-safe SCL equivalent. The S7-1500 compiler optimizes the array indexing to the same code as the STL version, but the source remains portable and readable.
Documentation and Reference Hierarchy
The TIA Portal in-software help is the canonical source for SCL. Open it from Help > Show Help or press F1 on any SCL keyword. The relevant chapters are:
- Programming concepts > Programming language > SCL > SCL expressions and operations — covers operators, precedence, and type conversion rules. See the public mirror at TIA Portal documentation cloud.
- STEP 7 Professional manual, chapter 7.1.2.4 (SCL) — the printed reference, hosted as ID 109011420.
- Accessing I/O devices — the in-software help section that explains the difference between process image access, direct peripheral access, and PROFINET IO slot addressing.
- SITRAIN course TIA-SCL1 — instructor-led online training on SCL programming in TIA Portal, indexed at Siemens SITRAIN.
- Programming and Operating Manual for the target CPU — the device manual lists the firmware-version-specific instruction set and any restrictions on indirect addressing.
For a first SCL block, the "Writing your first SCL code in TIA Portal" walkthrough provides a step-by-step procedure for project setup, FB/FC creation, interface definition, and the first compile/download cycle.
Commissioning and Verification Procedure
After the SCL block is written, validate it in five steps before releasing to production.
- Compile the program in TIA Portal (Project > Compile > All or Ctrl+B). Resolve every warning, especially the ones that flag optimized-block access conflicts.
- Download the block to the target PLC. The download dialog displays the firmware compatibility check; if the firmware does not match, the download is rejected.
-
Monitor online the block. Right-click the SCL block in the project tree, choose Open in SCL editor, then click Monitor on/off to attach the SCL debugger. Set breakpoints on the
%IW/%QWlines and step through the cycle. -
Force / overwrite an output to validate the write path. Use a watch table on the tag mapped to
%QW272and set the value. The output module should respond within one OB1 cycle for image access, or within the backplane latency for:Paccess. - Document the access pattern in the function specification. Record the hardware slot, the I/O address, the symbol name, the scaling, and the SCL block number. This information is required for the as-built documentation and for any subsequent maintenance work.
:P direct peripheral writes bypass the process image and are not subject to the standard output-disable mechanism that the safety program uses. In a safety-related application, the safety output must be driven through the safety program, not through an SCL :P write.Troubleshooting Matrix
| Symptom | Likely Cause | Fix |
|---|---|---|
| Compiler error: "Absolute address not allowed in optimized block" | Symbolic-only optimized block access is enabled and a %IW read crosses the optimization boundary |
Add the address to the PLC tag table with the Accessible from SCL attribute, or change the block to non-optimized |
| Read value is always zero | Hardware module not inserted; PROFINET IO station not configured; address offset wrong | Verify the device configuration in Devices & Networks; check the slot and I/O range against the tag table |
| Watch table shows stale value for PEEK result | TIA Portal V16/V17 watch-table caching of PEEK temporaries | Force a re-read of the watch table; pin a snapshot tag; update to V17 Update 4 or later |
| Download rejected: "Firmware not supported" | Block was compiled for a newer CPU firmware than the target PLC has | Match the CPU firmware, or recompile against the actual firmware |
| Runtime error 16#FFFF (illegal PEEK area) | Area constant outside the supported set (only 16#81-16#84 are valid for user code) | Check the area parameter; use the symbolic tag instead |
| SCL editor locks up on save | Known TIA Portal V11 / V13 issue with large SCL blocks | Split the block, or upgrade to a current TIA Portal major version |
FAQ
How do I read PIW 256 in SCL on TIA Portal?
Use %IW256 for process-image access, or %IW256:P for direct peripheral read. The S7-1500 and S7-1200 (FW V4.0+) support both notations. Symbolic tags mapped to the same address are preferred for readability.
How do I write PQW 272 in SCL?
Assign the value with %QW272 := value; (process image) or %QW272:P := value; (peripheral-direct). The SCL compiler enforces the data-type match between the value and the I/O size.
What is the difference between PEEK and %IW:P?
%IW256:P requires a fixed, known address. PEEK_WORD(area := 16#81, byteOffset := ...) takes a runtime-computed bit offset and lets you index into a vector of I/O words. Use PEEK for arrays of analog channels with parameterized base address.
Can I use SCL to program an S7-300 or S7-400 in TIA Portal?
Yes. TIA Portal supports SCL on S7-300/400 with the same syntax. The legacy STL approach of L PIW/T PQW is still valid; SCL is the typed, debuggable replacement that integrates with the cross-reference.
Which TIA Portal version should I use for a new SCL project?
Use the latest supported major version for the target CPU firmware. Confirm in Siemens Industry Online Support by checking the TIA Portal compatibility list and applying the latest Service Pack + Update. Avoid V11-V13 for new SCL development.