Overview
The S5 function block FC 84 performs a 16-bit signed integer division with explicit overflow and quotient/remainder zero flags. When porting an S5 program to an S7-300 or S7-400 controller using classic STEP 7 (SIMATIC Manager) or TIA Portal, FC 84 is not carried forward as a named block. The native STEP 7 integer-division instruction /I produces identical arithmetic but exposes the result through the Status Word (STW / STATUS) instead of dedicated boolean outputs. This article maps every FC 84 parameter to its STEP 7 equivalent and shows how to recover the missing boolean flags using jump instructions evaluated on the status word.
The procedure applies to CPU firmware families that support the STL /I operation, i.e., S7-300 (CPU 312/314/315/317/319) and S7-400 (CPU 412/414/416/417) running STEP 7 V5.x or TIA Portal with active STL language switching. Reference the official Siemens migration manual STEP 7 - From S5 to S7 (entry ID 45531547) for the broader conversion ruleset.
Prerequisites
- STEP 7 V5.5 SPx or TIA Portal V13+ with the STL editor enabled (Options > Package management > STL).
- S7-300/S7-400 CPU whose firmware supports the
/Iinstruction (standard for all S7-CPU since CPU 312 IFM). - Source S5 program with the original
CALL FC 84block instance and a documented I/O parameter list (Z_1, Z_2, OV, FEH, Z3_0, Z4_0, Z_3, Z_4). - Free bit memory (M area) and word memory (MW) range that does not collide with the existing S7 symbol table. Reserve eight consecutive flags for the recovered status outputs (e.g., M 50.0–M 50.7).
- Optional: the Siemens S5-to-S7 Converter tool (entry 45531547) to perform the bulk block conversion; this guide covers only the manual replacement of
FC 84.
FC 84 Parameter Mapping
The S5 FC 84 interface uses formal parameters beginning with Z (German: Zaehler = dividend/quotient). The following table lists each parameter, its data width, meaning, and the STEP 7 equivalent after conversion.
| S5 FC 84 Parameter | Type | Meaning | S7 Replacement |
|---|---|---|---|
| Z_1 (MW 122) | INT (16-bit) | Dividend | Source operand of L; loaded into ACCU1-L |
| Z_2 (MW 104) | INT (16-bit) | Divisor (from DB 22) | Source operand of the second L; loaded into ACCU1-L, ACCU2-L holds Z_1 |
| OV (M 50.1) | BOOL | Overflow during division | Status word bit OV (status bit 5) – interrogate via JO
|
| FEH (M 50.2) | BOOL | Fault – division by zero | Status word bits CC0=1 and CC1=1 – interrogate via JUO
|
| Z3_0 (M 50.3) | BOOL | Quotient equals zero | CC0=1 and CC1=0 – interrogate via JZ
|
| Z4_0 (M 50.5) | BOOL | Remainder equals zero | Compare remainder word against zero after T
|
| Z_3 (MW 124) | INT | Quotient | Low word of ACCU1 (bits 0–15) after /I
|
| Z_4 (MW 126) | INT | Remainder (modulo) | High word of ACCU1 (bits 16–31) after /I
|
STEP 7 /I Instruction Behavior
The STEP 7 integer-division instruction /I consumes two 16-bit operands previously loaded into the two accumulators. The 32-bit subtraction chain that produces the quotient is documented in the Siemens S5-to-S7 conversion manual section 4.7 ("Arithmetic Functions"). The resulting distribution in the 32-bit accumulators is:
| Register / Word | Bit Range | Content after /I |
|---|---|---|
| ACCU1-L (bits 0–15) | Word 0 | 16-bit signed quotient (Z_3) |
| ACCU1-H (bits 16–31) | Word 1 | 16-bit signed remainder (Z_4) |
| ACCU2-L (bits 0–15) | Word 0 | Original divisor Z_2 (preserved) |
| ACCU2-H (bits 16–31) | Word 1 | Original dividend Z_1 (preserved) |
Use T MD <tag> to deposit both words into one double-word marker; the even MW receives the remainder and the odd MW receives the quotient on S7-300/400. The layout is little-endian within ACCU1, which matches the byte order of T MD.
Status Word Reference
The S7 status word (STW) is a 16-bit register updated by every arithmetic, comparison, and word logic instruction. After /I, the relevant bits hold the same diagnostic information that S5 FC 84 returned as discrete flags.
| Bit | Name | Set after /I when… | Equivalent FC84 Flag |
|---|---|---|---|
| CC1 | Condition Code 1 | Quotient < 0 OR invalid (div/0) | (contributes to FEH, OV) |
| CC0 | Condition Code 0 | Quotient = 0 OR invalid | (contributes to FEH, Z3_0) |
| OV | Overflow | Result out of INT range, or div/0 | OV (M 50.1) |
| OS | Stored Overflow | Same as OV, latched | OV (M 50.1) held until JOS |
| BR | Binary Result | Always 1 after a math op | n/a |
After /I, the four CC/OV combinations decode to the FC84 outputs as follows:
| CC1 | CC0 | OV | Result | FC84 Equivalent | STL Jump |
|---|---|---|---|---|---|
| 0 | 0 | 0 | Quotient > 0 | None of the FC84 flags | JP / JPZ if combined |
| 0 | 1 | 0 | Quotient = 0 | Z3_0 = 1 | JZ |
| 1 | 0 | 0 | Quotient < 0 | None | JM / JMZ |
| 1 | 1 | 1 | Invalid (div/0 or range overflow) | FEH = 1, OV = 1 | JUO (CC1&CC0), JO (OV) |
JOS jump, a block call, or a block end (BE/BEU) clears it. Read the flags immediately after /I if you need them later in the cycle.Step-by-Step Conversion
-
Load the divisor first, then the dividend. STEP 7 pops ACCU1 into ACCU2 on each
L, so the divisor must be loaded first to satisfy theACCU2 ÷ ACCU1semantics of/I.L MW 104 // divisor Z_2 (from DB22.DBW...) L MW 122 // dividend Z_1 /I // 16-bit signed integer division T MD 124 // MD124: MW126 = remainder (Z_4), MW124 = quotient (Z_3) -
Reset the four FC84 boolean outputs before evaluating. Use
CLRto clear RLO, then assign zero to each flag.CLR = M 50.1 // OV = M 50.2 // FEH (div/0) = M 50.3 // Z3_0 (quotient zero) = M 50.5 // Z4_0 (remainder zero) -
Detect division by zero via
JUO. The combined condition (CC1=1 AND CC0=1) flags an invalid operation, which on integer division means divisor = 0.JUO DIV0 // CC1=1 & CC0=1 → jump to DIV0 handler JU OK // else continue with OK branch DIV0: SET = M 50.2 // FEH = 1 = M 50.1 // OV = 1 BEU // block end unconditional; skip quotient-zero test OK: -
Detect quotient-zero via
JZ.JZ Q0 // CC0=1 & CC1=0 → quotient = 0 JU QNZ Q0: SET = M 50.3 // Z3_0 = 1 QNZ: -
Detect remainder-zero by direct comparison. Because the remainder is held in MW 126 (high word of MD 124), compare it with zero and set the flag.
L MW 126 L 0 ==I = M 50.5 // Z4_0 = 1 if remainder equals zero -
Latch overflow using OS for cross-scan visibility.
JO OVF // OV=1 (also true on div/0 – already handled) JU NOV OVF: SET = M 50.1 // OV latch NOV: JOS OSR // clear stored overflow after reading OSR: NOP 0 - Continue with the original downstream logic. Both Z_3 (MW 124) and Z_4 (MW 126) are valid integers; consume them in place of the S5 call result.
Complete STL Snippet
// --- Replace S5: CALL FC 84 (Z1=MW122, Z2=MW104, ...) ---
// Reset FC84 boolean outputs
CLR
= M 50.1 // OV
= M 50.2 // FEH (div/0)
= M 50.3 // Z3_0
= M 50.5 // Z4_0
// Load and divide
L MW 104 // divisor Z_2
L MW 122 // dividend Z_1
/I // 16-bit signed integer division
T MD 124 // MW126 remainder, MW124 quotient
// Division-by-zero check (CC1=1, CC0=1)
JUO DIV0
JU OK
DIV0: SET
= M 50.2 // FEH = 1
= M 50.1 // OV = 1
BEU
// Quotient-zero check (CC0=1, CC1=0)
OK: JZ QZ
JU QNZ
QZ: SET
= M 50.3 // Z3_0 = 1
// Remainder-zero check (direct compare)
QNZ: L MW 126
L 0
==I
= M 50.5 // Z4_0 = 1
// Read and clear stored overflow
JOS OSR
OSR: NOP 0
// --- End replacement; downstream logic continues with MW124/MW126 ---
Reading the Status Word Programmatically
If you prefer to inspect the entire status word symbolically rather than rely on individual jump instructions, load the STW into accumulator 1 with L STW and mask the desired bits. The mapping from FC84 output to STW bit is:
| FC84 Output | Marker | STW Bit | Bit Mask (hex) | Test Instruction |
|---|---|---|---|---|
| OV | M 50.1 | OV (bit 5) | 0x0020 |
A STW; AN ... ; = M50.1 or JO label
|
| FEH | M 50.2 | CC1 (b7) AND CC0 (b6) | 0x00C0 | JUO label |
| Z3_0 | M 50.3 | CC0 (bit 6) | 0x0040 | JZ label |
| Z4_0 | M 50.5 | n/a (remainder word) | n/a | L MW126; L 0; ==I |
For full word access, use:
L STW // load 16-bit status word
T MW 200 // local copy for inspection
L MW 200
L W#16#0020 // OV mask
UW
L W#16#0020
==I
= M 50.1 // OV recovered
MOD instruction in STEP 7; the modulo (remainder) is the high word of ACCU1 after /I, accessible via T MD or MOD in SCL (x MOD y). For TIA Portal SCL, prefer the MOD operator.Block Errors (FB 238–FB 251) After Bulk Conversion
When STEP 7's converter (or the S5-to-S7 tool) processes an S5 program, S5-specific standard function blocks such as FB 238 through FB 251 (analog value handling, PID, and integrator blocks in the S5-135U/155U libraries) are flagged as "not convertible". The online error "Error from FB 238 to FB 251" indicates that the converter could not auto-generate the S7 equivalents. Manual remediation:
- Delete the unresolved
FB 238–FB 251calls from the S7 STL source. - Replace them with the corresponding S7 standard library blocks:
FB 41(CONT_C, continuous PID),FB 42(CONT_S, step PID),FB 43(PULSEGEN),FC 106(UNSCALE),FC 105(SCALE). - Recompile and download the S7 program. Refer to Siemens entry ID 45531547 for the cross-reference table.
Verification
Validate the conversion on the target CPU using the STEP 7 Monitor/Modify function or PLCSIM:
- Force MW 122 = 12345, MW 104 = 0. Run one OB1 cycle. Expect M 50.2 = 1 (FEH), M 50.1 = 1 (OV), MW 124 = 0, MW 126 = 0.
- Force MW 122 = 100, MW 104 = 7. Expect MW 124 = 14 (quotient), MW 126 = 2 (remainder), M 50.3 = 0, M 50.5 = 0.
- Force MW 122 = 0, MW 104 = 55. Expect MW 124 = 0, MW 126 = 0, M 50.3 = 1, M 50.5 = 1.
- Force MW 122 = -100, MW 104 = 7. Expect MW 124 = -14, MW 126 = -2, M 50.3 = 0, M 50.5 = 0, CC1 = 1.
-
Cross-check with PLCSIM breakpoint on the
/Iline to inspect ACCU1 (quotient/remainder) and the status word bits.
Troubleshooting Matrix
| Symptom | Likely Cause | Remedy |
|---|---|---|
| Quotient is always zero | Load order reversed – divisor loaded second | Swap: load divisor first, dividend second |
| FEH never set, even with Z_2 = 0 |
JUO placed after another math op that cleared CC bits |
Place JUO immediately after /I
|
| Z3_0 and Z4_0 always equal | Comparing full MD 124 against zero instead of MW 124 / MW 126 | Split into L MW 124 and L MW 126, then compare each |
| OV false on legitimate overflow |
/I only sets OV on invalid; positive overflow falls outside range and is reported via OS |
Evaluate OS in addition to OV |
| FB 238–FB 251 errors persist after compile | Converter left stubs in the S7 source | Delete stub FBs manually and replace with S7 library equivalents |
| Negative quotient interpreted as positive downstream | Target loads Z_3 as WORD instead of INT | Use ITD to sign-extend or load with L MW as INT |
Notes on TIA Portal
In TIA Portal, the SCL text editor treats integer division as / and modulo as MOD. The compiler does not expose CC0/CC1 directly; instead, you must branch on the result:
#quotient := #dividend / #divisor; // raises exception on div/0
#remainder := #dividend MOD #divisor;
IF #quotient = 0 THEN #z3_0 := TRUE; END_IF;
IF #remainder = 0 THEN #z4_0 := TRUE; END_IF;
Wrap the division in an IF #divisor <> 0 THEN guard to replicate the FC84 FEH behavior without relying on the OB121 error handler.
FAQ
What is the direct S7 replacement for S5 FC 84?
Use the STEP 7 STL instruction /I for 16-bit signed integer division. The quotient lands in the low word of ACCU1 and the remainder in the high word; both are available via T MD <tag>. Status bits CC0, CC1, OV, and OS hold the diagnostic flags that FC 84 returned as discrete outputs.
How do I detect a division by zero in STEP 7 after /I?
Use the jump instruction JUO immediately after /I. JUO evaluates true when both CC1 and CC0 are 1, which is the S7 indicator of an invalid arithmetic operation including division by zero. The OV and OS status flags are also set, but JUO is the cleanest single check.
Where do I find the remainder (modulo) after an integer division?
After /I, transfer ACCU1 to a double-word marker with T MD n. The even MW (n) holds the quotient; the odd MW (n+2) holds the 16-bit remainder. In SCL, the operator is x MOD y, which returns the same value directly.
Why does the S5-to-S7 converter report errors for FB 238 to FB 251?
These are S5-135U/155U standard library blocks for analog signal processing and PID control. They are not carried into the STEP 7 standard library. Replace them with the S7 equivalents: FB 41 (CONT_C) for continuous PID, FB 42 (CONT_S) for step PID, FB 43 (PULSEGEN) for the pulse generator, and FC 105/FC 106 for scaling. See the Siemens S5-to-S7 manual, entry ID 45531547.
How do I read the status word bits A1, A0, OV, and OS in STL?
Either use the dedicated jump instructions (JZ for CC0, JM for CC1 negative, JUO for both set, JO for OV, JOS for OS), or load the status word with L STW into a marker word and bit-test individual bits using UW (AND word) and ==I. The mapping is: bit 8 = BR, bit 7 = CC1 (A1), bit 6 = CC0 (A0), bit 5 = OV, bit 4 = OS, bit 3 = OR, bit 2 = STA, bit 1 = RLO, bit 0 = /FC.