Converting S7-300 STL Timer Code to LAD: SP SE Coil Mapping

David Krause17 min read
S7-300SiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

1. Overview: Converting S7-300 STL Timer Code to LAD

When migrating Siemens SIMATIC S7-300 STL (Statement List) code to LAD (Ladder Diagram), the timer block (lines containing SE, SP, SD, SS, SF, and FR) maps cleanly onto the IEC 61131-3 graphical timer coil. The surrounding input logic, however, and especially the time-readout instructions (L T n, LC T n) often confuse first-time programmers. This reference walks through a 13-line STL timer example, gives a complete LAD equivalent rung by rung, and explains the three behaviour traps engineers most commonly hit:

  • The unconditional nature of the L (Load) instruction relative to the RLO.
  • The difference between L T n (binary readout) and LC T n (BCD readout) when copying elapsed time to a flag word.
  • The self-latching behaviour of a one-shot T MB0 when no reset path is present in the program.

The reference STL excerpt used throughout this document is the canonical "start with enable, extend with retrigger, reset on demand" example that ships in the STEP 7 online help for SIMATIC S7-300 CPUs:

01.  A     I      2.0
02.  FR    T      1
03.  A     I      2.1
04.  L     S5T#10S
05.  SE    T      1
06.  A     I      2.2
07.  R     T      1
08.  A     T      1
09.  =     Q      4.0
10.  L     T      1
11.  T     MW    10
12.  LC    T      1
13.  T     MW    12

The same pattern is documented in the SIMATIC S7-300 CPU 31x/31xC Reference Manual under "Time cells (S5 timers)" and the STEP 7 Programming with STL / LAD / FBD manual under "IEC timer / S5 timer coexistence".

2. Prerequisites and Required Knowledge

Before working through this reference, the engineer should be familiar with:

  • STEP 7 V5.x or TIA Portal with an S7-300 CPU 31x or 31xC target (firmware V2.0 or later; CPU 312 IFM and older firmware omit some timer functions).
  • The RLO (Result of Logic Operation) concept: STL instructions beginning with A, O, AN, X modify RLO; = assigns it; S, R latch/unlatch dependent on RLO.
  • The accumulator concept: STL is accumulator-based with two 32-bit accumulators (ACCU1, ACCU2). L writes to ACCU1 while shifting the previous ACCU1 into ACCU2.
  • The S5TIME data type (16-bit) and its 10-bit BCD time base + value format.
Note: The S5T# literal syntax is accepted by both STEP 7 V5.x and TIA Portal V13+. The maximum value is S5T#2H46M30S (9990 seconds, encoded as BCD 0010_1001_1001_1010 with a 1 s time base).

3. The S5TIME Data Type

S5TIME is a 16-bit value occupying two bytes (one word). The bit layout, referenced from the S7-300 CPU 31x/31xC manual, is:

Bit 15-14 Bit 13-12 Bit 11-10 Bit 9-0
Unused (0) Time base (BCD) Time base (BCD) Time value in BCD (0-999)

The time base field encodes the resolution:

Code (binary) Resolution Range
00 0.01 s (10 ms) 10 ms - 9 s 990 ms
01 0.1 s (100 ms) 100 ms - 1 m 39 s 900 ms
10 1 s 1 s - 16 m 39 s
11 10 s 10 s - 2 h 46 m 30 s

The IEC 61131-3 native TIME type (DWORD, ms resolution, 32-bit signed) is also accepted on S7-300/400 with firmware V3.0 or later, but the legacy S5TIME remains the dominant format because it is what the S5 timer coils consume directly.

4. S5 Timer Coil Instructions: SP, SE, SD, SS, SF, FR

The STL abbreviations map to the S5 timer cells originally inherited from the SIMATIC S5 family. Each has a different trigger behaviour and therefore a different LAD graphical symbol (coil vs box). The table below is cross-checked against the STEP 7 Online Help "Working with Timers" topic and the S7-300/400 Timer Functions Application Note.

STL Full name (English / German) IEC 61131-3 block name Behaviour summary LAD representation
SP T n Pulse timer / Impuls S_PULSE Runs for programmed time while start input stays high. Cancels on falling edge of start. Coil form available; box form preferred.
SE T n Extended pulse / verlängerter Impuls S_PEXT (S_ODTS in classic S7) Starts on rising edge, runs full programmed duration even if start input drops. Coil form available; box form preferred.
SD T n Off-delay / Ausschaltverzögerung S_OFFDT Output stays high as long as start is high, then runs the programmed time after start drops. Box form only.
SS T n On-delay / Einschaltverzögerung S_ODT Output goes high only after programmed time elapses with continuous start. Box form (IEC) and coil form (S5) both available.
SF T n Retentive on-delay / speichernde Einschaltverzögerung S_ODTG (no direct IEC equivalent on S7-300) On-delay that latches; requires R to clear. Box form only.
FR T n Enable / Freigabe Not applicable (S5 legacy) Permits a cold restart on a 0->1 transition of the enable input, even while running. Often placed ahead of a timer coil to force a fresh restart on the next start. Coil form only.
Note on coil form limitations: The coil form of SP / SE / SS / SD cannot read out the current time value, cannot drive the BCD time base output, and cannot supply a separate reset. The box form in LAD/FBD gives access to the time value outputs (BI - binary, BCD - BCD), the S input, and the R reset input. For any non-trivial logic, use the box form.

5. Line-by-Line Decomposition of the Source STL Example

Line STL Operands Function
01 A I 2.0 I2.0 AND input I2.0 with current RLO. Sets RLO for subsequent timer enable.
02 FR T 1 T1 Enable (Freigabe). Allows a cold restart of T1 on the next rising edge of I2.0 even if T1 is already running.
03 A I 2.1 I2.1 AND input I2.1 with RLO. Start signal for T1.
04 L S5T#10S S5T#10S Load 10 s S5TIME constant into ACCU1. Constant is unconditional.
05 SE T 1 T1 Start T1 as an extended-pulse timer with the time value in ACCU1.
06 A I 2.2 I2.2 AND input I2.2 with RLO. Reset signal for T1.
07 R T 1 T1 Reset T1 to zero. RLO must be 1 for reset to occur.
08 A T 1 T1 AND timer word T1 (status = running). RLO reflects timer state.
09 = Q 4.0 Q4.0 Assign RLO to output Q4.0. Output follows timer status.
10 L T 1 T1 Load current time value from T1 in binary (integer) format into ACCU1.
11 T MW 10 MW10 Transfer ACCU1 L-word to flag word MW10. Holds binary elapsed time.
12 LC T 1 T1 Load current time value from T1 in BCD format (preserves time base bits) into ACCU1.
13 T MW 12 MW12 Transfer ACCU1 L-word to flag word MW12. Holds BCD-coded time including base.

6. LAD Conversion: Networks 1 to 4 (Lines 1-9)

The first nine lines of the STL break naturally into four LAD networks. The key conversion rule is: each STL line beginning with A, O, =, S, or R becomes a contact, output coil, or box in the same network; the L S5T#10S line is consumed by the timer box and therefore does not appear as a separate network.

Network 1 - Enable (FR)

|   I2.0   |---(FR T1)---|

The FR coil is a parameterless enable coil. It can only be programmed in STL or as a LAD coil; there is no FBD equivalent box. Place it ahead of the start coil.

Network 2 - Start and Reset of the Timer

|   I2.1   |---[S_PEXT  T1  S5T#10S  TV]--|
|   I2.2   |---(R)---(T1)------------------|

Use the IEC box S_PEXT (extended pulse) for the SE behaviour. The set input is connected to I2.1, the reset input is connected to I2.2, and the TV (Timer Value) input is hard-wired to the constant S5T#10S. Do not add a separate L S5T#10S line - the IEC box carries its own TV input.

Network 3 - Output

|  T1.Q   |---( Q4.0 )---|

The IEC box exposes its Q (output) terminal. Wire it directly to the Q4.0 coil. This replaces STL lines 8 and 9.

7. LAD Conversion: Networks 5 to 6 (Lines 10-13)

Lines 10 and 12 both read the current timer value but in two different encodings. The conversion requires two separate MOVE blocks, one for the binary value and one for the BCD value.

Network 4 - Binary Time Readout

EN  |   T1.BI   |---[MOVE]--|  MW10  |

The BI output of the IEC timer box carries the remaining time as an integer (binary) value with units consistent with the time base. The MOVE block transfers it into MW10. This replaces STL lines 10 and 11.

Encoding note: The BI output does not include the time base bits. If the user needs to interpret the value in human-readable units (ms vs s vs 10 s), they must also remember the resolution that was programmed. A common trap is wiring a 1 s base timer to BI and then dividing by 1000 expecting milliseconds.

Network 5 - BCD Time Readout

EN  |   T1.BCD   |---[MOVE]--|  MW12  |

The BCD output reproduces the raw S5TIME word, including the 4-bit time base in bits 13-12 and the BCD-coded value in bits 9-0. This is the format used by OP/TP HMI displays that natively read S5TIME. This replaces STL lines 12 and 13.

8. Binary vs BCD Readout: L T n vs LC T n

The two STL instructions look similar but the resulting accumulator contents differ:

Aspect L T 1 (binary) LC T 1 (BCD)
ACCU1 L-word contents Remaining time as 16-bit integer (units = current time base resolution) S5TIME word: bits 13-12 = time base, bits 11-0 = BCD value 0-999
Use case Arithmetic (multiply, divide, scale) before transferring to a process word Direct display on OP/TP panels that understand S5TIME
Resulting MW content for a 10 s timer at 7 s elapsed MW = W#16#0003 (decimal 3 of 10 time-base units) MW = W#16#1070 (time base 10 s = binary 10, value BCD 0070)
LAD equivalent Wire BI output of IEC box to MOVE block Wire BCD output of IEC box to MOVE block
MW overlap warning: MW10 occupies bytes MB10 and MB11; MW12 occupies bytes MB12 and MB13. They do not overlap, but if the original STL writes to MW10 and then to MW12 in adjacent networks, LAD programmers must keep the two MOVE blocks independent - do not let them target adjacent bytes through two separate MOVE operations that could collide on cycle boundaries.

9. The Unconditional L Instruction

The most counter-intuitive behaviour for engineers used to LAD is that L (Load) in STL does not consult the RLO. The CPU executes L S5T#10S regardless of whether the previous A I 2.1 produced RLO = 0 or RLO = 1. The constant is unconditionally placed into ACCU1 and the previous ACCU1 is shifted into ACCU2.

The only STL load instructions that are conditional on RLO are the jump functions:

  • JC <label> - jump if RLO = 1
  • JCN <label> - jump if RLO = 0
  • JB / JNB <label> - jump on BR / jump on BR = 0
  • JCB / JBI / JNBI / JO / JOS / JZ / JN / JP / JM / JPZ / JMZ / JU - status-bit jumps

Therefore, the naive STL snippet:

A   I 0.0
L   2#11111111
T   MB 0

does not behave like "load MB0 with 0xFF only when I0.0 is high". It unconditionally executes L 2#11111111 (places 0xFF into ACCU1) and then T MB 0 (writes ACCU1 L-byte to MB0). The A I 0.0 is dead code as far as the transfer is concerned - it modifies RLO but no subsequent instruction inspects RLO. The user observes MB0 permanently stuck at 0xFF because the load and transfer execute every scan, regardless of I0.0.

9.1 Corrected Pattern A - Conditional Jump Around the Load

AN  I 0.0          // RLO = 1 when I0.0 is OFF
JC  end            // skip the load if I0.0 is OFF
L   2#11111111
T   MB 0
end: NOP 0

9.2 Corrected Pattern B - JNB with Inline Skip

STEP 7 also supports the inverse pattern using JNB (jump if RLO = 0):

A   I 0.0
JNB xng            // skip next block if RLO = 0 (I0.0 is OFF)
L   W#16#FF
T   MB 0
xng: NOP 0

This is the canonical STEP 7 idiom for "if-then do this one transfer". JNB branches to label xng when RLO is 0, leaving RLO untouched at the destination (no RLO corruption for downstream logic).

9.3 Corrected Pattern C - LAD MOVE Block with Enable Input

In LAD the equivalent is the MOVE box with an EN (enable) input wired to I0.0:

|   I0.0   |--EN  MOVE  IN:=B#16#FF  OUT:=MB0--|

When EN = 0, the MOVE does not execute and MB0 retains its previous value. This is structurally what the user expected.

10. The MB0 Self-Latch Mystery

Even after the conditional jump is added, MB0 may still appear "stuck on". The reason is unrelated to RLO handling and is a direct consequence of how the bit memory area works in the S7-300:

  • Once a bit in MB, MD, or MW is set to 1, it stays at 1 until something explicitly writes 0 to it.
  • The PLC retentive flag area is configured in the hardware configuration (HW Config) under "CPU Properties > Retentive Memory". Bits, bytes, and words within the configured range are preserved across power-cycle.
  • Even for the non-retentive portion of the flag area, the previous cycle's value carries into the next cycle. The CPU never auto-clears flag memory.

So if at any earlier point in the program's history the user wrote 0xFF to MB0 (for example by manually forcing it in the variable table), the bit pattern will persist indefinitely until one of the following is done:

  1. Reset explicitly with R MB 0 or L 0 / T MB 0 at program start (in OB100 / OB101 warm restart).
  2. Overwrite conditionally with the MOVE pattern of section 9.3, ensuring the enable input is wired and the OUT always reassigns the value when the enable is true.
  3. Use the SET / CLR bit-pattern instructions to force a known state.
Commissioning tip: When migrating STL code with unconditional transfers into flag memory, add an OB100 startup block that performs L 0 / T MB 0 ... T MB n on every byte of the flag area used by the program. This guarantees a deterministic initial state regardless of how the program was exited previously. Also force-clear MB0 from the watch table once during commissioning so any retained 0xFF value is wiped.

11. STL to LAD Cross-Reference Table

STL instruction LAD equivalent Notes
A I x.y | I x.y | normally-open contact RLO modifier
AN I x.y |/I x.y| normally-closed contact RLO modifier
O I x.y Parallel branch contact RLO modifier
= Q x.y ---( Q x.y )--- coil RLO consumer
S Q x.y ---( S )--- set latch RLO consumer
R Q x.y ---( R )--- reset latch RLO consumer
L value Hard-wired input on a box Unconditional
T operand MOVE box OUT terminal Unconditional
L T n / LC T n BI / BCD output of IEC timer box to MOVE See section 8
SP / SE / SS T n S_PULSE / S_PEXT / S_ODT box Box form recommended
SD / SF T n S_OFFDT / S_ODTG box Box form only on S7-300
FR T n ---(FR T n)--- coil Only as LAD coil
JC label / JNB label Not directly representable; use contact + MOVE with EN Conditional logic required

12. Verification and Commissioning Checklist

After conversion to LAD, run through the following checks before deploying to the field:

  1. Open the LAD editor in STEP 7 / TIA Portal and confirm there are no "STL remaining" regions. LAD cannot fully represent JC / JNB, so any unconverted jump produces a compile error.
  2. Compile (Consistency Check) and download to the target CPU. Open the watch table and force I2.0 / I2.1 / I2.2 in sequence.
  3. Verify timer behaviour: With I2.1 momentarily pulsed, T1 should start and Q4.0 should remain high for 10 s regardless of further transitions on I2.1 (extended-pulse behaviour). With I2.2 forced high, T1 should immediately reset and Q4.0 should drop to 0.
  4. Verify BI / BCD readouts: Use a VAT or HMI tag to monitor MW10 (binary) and MW12 (BCD). Seven seconds after a fresh start, MW10 should hold W#16#0007 (decimal 7, value in time-base units) and MW12 should hold the BCD word whose bits 13-12 = 10 (binary, 1 s time base) and bits 11-0 = 0070 BCD.
  5. Reset scan: Cold-restart the CPU (power cycle) and verify MB0 starts at 0x00 unless the program explicitly assigns it. If MB0 is in the retentive range and was previously 0xFF, force-clear from the watch table once.
  6. Cycle-time check: Two MOVE blocks plus an IEC timer box add approximately 25-40 microseconds of OB1 execution time on a CPU 315-2 DP. Confirm that OB1 cycle time remains within the configured OB1 watchdog (default 150 ms on CPU 315-2).
  7. Cross-reference check: In LAD/FBD editor, "Cross-references > Show" should list every consumer of MW10 and MW12 to catch accidental overlaps with adjacent flag bytes.
Safety warning: The S_OFFDT (off-delay) timer can mask the loss of a safety-relevant input if used on a safety function. Per IEC 62061 and ISO 13849-1, safety stop functions must use monitored inputs and must not rely on software timers alone to enforce a safe state. Use certified safety relays or the integrated safety functions of a CPU 31xF-2 DP / CPU 31xF-2 PN for SIL 2/3 or PL d/e applications.

13. CPU-Specific Notes and Firmware Caveats

  • CPU 312 IFM / 312C: Only 64 S5 timers available (T0-T63); running two such timers per cycle in S7-300 will exhaust the resource. Use IEC SFB 3 through SFB 7 (TP, TON, TOF, TONR, etc.) instead.
  • CPU 314 / 315-2 DP / 317-2: 128 S5 timers (T0-T127). IEC timers (SFB3-SFB7) and S5 timers coexist; the IEC timers use DB instance memory instead of the timer word area.
  • CPU 319-3 PN/DP: 256 S5 timers; full multi-instance IEC timer support in firmware V2.7 or later.
  • Firmware V3.0 or later: Required for the TIME (DWORD, 32-bit, ms) data type at timer inputs. Earlier firmware rejects T#10s literals.
  • TIA Portal V13+: The legacy "S5 timer" block face is replaced with the IEC 61131-3 box icon but the underlying instruction mnemonics (SP, SE, etc.) remain in the imported STL. Re-converting to LAD produces the same box as in STEP 7 V5.x.

14. FAQ

Why does my MB0 stay at 0xFF even when I0.0 is off?

Because the STL L instruction is unconditional and executes every scan. A I 0.0 modifies the RLO but no subsequent instruction consults it. Replace the unconditional L / T pair with a LAD MOVE block with EN wired to I0.0, or use JNB in STL to skip the load and transfer when I0.0 is OFF.

How do I read the current time value from an S5 timer in LAD?

Use the IEC timer box form (S_ODT, S_PEXT, S_OFFDT, S_PULSE, S_ODTG) instead of the coil form. The box exposes two outputs: BI (binary elapsed time as integer) and BCD (raw S5TIME word with time base). Wire BI or BCD to a MOVE block whose OUT points to the flag word where you want the value stored. MW10 is commonly used for binary, MW12 for BCD.

What is the difference between SE and SS timer coils?

SS (S_ODT, on-delay) keeps the output OFF until the programmed time has elapsed with continuous start; if the start drops early, the timer resets. SE (S_PEXT, extended pulse) latches the run on the rising edge of the start and runs the full programmed duration even if start drops. Use SE when you want "minimum guaranteed run time" and SS when you want "delay before turning on".

Can I use the L (Load) and T (Transfer) instructions inside an FB / FC?

Yes. Within an FB, the transfer target may also be a static local variable (FB-internal memory) or an instance DB multi-instance. The unconditional-load problem persists: use JNB / JC patterns or, in LAD, MOVE boxes with EN enable to make the transfer conditional.

Why does the FR coil sit ahead of the SE coil in the canonical example?

FR (Freigabe / enable) permits a cold restart of the timer on the next rising edge of the start signal even if the timer is already running. Without FR, a second rising edge on the start input during an active run has no effect; with FR placed before SE, each rising edge on the enable input forces a fresh restart. For SE this is rarely necessary, but the canonical example demonstrates the pattern for engineers migrating code from SIMATIC S5.

How do I move a constant into a flag byte only when a specific bit is set?

In LAD: | bit |---EN---[MOVE IN:=B#16#FF OUT:=MB0]---|. In STL: AN bit / JC end / L B#16#FF / T MB 0 / end: NOP 0 or A bit / JNB end / L B#16#FF / T MB 0 / end: NOP 0. The JNB idiom is the most common in STEP 7 example code.

Back to blog