Overview: Why FC 92 (SHRB) Cannot Be Loaded Directly into S7-1200/1500
The classic SIMATIC S7-300/S7-400 FC 92 SHRB (Shift Right Bit) belongs to the legacy "Standard Library – Bit Logic Functions" that ships with STEP 7 V5.x. When you open a STEP 7 V5 project that contains FC 92 in TIA Portal and try to migrate it into an S7-1200 or S7-1500 CPU, the migration tool reports that the block is not supported on the target. The instruction set of the S7-1200/1500 firmware family is binary-compatible only with the TIA Portal instruction catalog, not with the V5.x standard library. Consequently, the FC must be replaced by a functionally equivalent TIA Portal instruction or by a user-written FC/FB that performs the same single-bit shift operation.
This reference shows exactly how to reproduce the FC 92 behaviour on S7-1200 (firmware V4.0 and higher) and S7-1500 (firmware V1.0 and higher) using native TIA Portal instructions, and how to encapsulate the logic in a reusable FC so that the call interface matches the legacy block.
Prerequisites
- TIA Portal V16, V17 or V18 with installed SIMATIC S7-1200/S7-1500 support package. TIA Portal V19 is supported for S7-1200 (firmware V4.5+) and S7-1500 (firmware V2.9+).
- S7-1200 CPU with firmware V4.2 or later (CPU 1211C, 1212C, 1214C, 1215C, 1217C). Firmware V4.0 is the minimum for the SHR/SHL/ROL/ROR instructions used in this article.
- S7-1500 CPU with firmware V1.8 or later (CPU 1511, 1513, 1515, 1516, 1517, 1518). Bit-shift instructions require firmware V1.0 as a minimum, but later firmware adds the BYTE/WORD/DWORD/LWORD variants.
- Programming language: LAD, FBD, or SCL. STL is available only on S7-1500.
- Access to the TIA Portal Online Help – Function (FC) and the S7-1200/S7-1500 system manuals referenced at the bottom of this article.
FC 92 (SHRB) Behaviour on S7-300/S7-400
FC 92 SHRB is a single-bit shift register. The formal parameters are:
| Parameter | Declaration | Data Type | Description |
|---|---|---|---|
| S_DATA | INPUT | BOOL | Data bit to be shifted in |
| S_BIT | INPUT | POINTER | Pointer to the least-significant bit of the shift register (ANY pointer in older manuals, POINTER in V5.5+) |
| N | INPUT | INT | Number of bits to shift (1..32) |
| CLK | INPUT | BOOL | Shift clock; rising edge triggers the shift |
| RET_VAL | OUTPUT | INT | Function return value (error code, 0 = OK) |
On every rising edge of CLK the contents of the bit array starting at S_BIT are shifted toward the high-order bit by one position; S_DATA is written into the low-order bit. Bits shifted past the high boundary are discarded. The block writes back to absolute or symbolic addresses pointed to by S_BIT.
Why the Block Does Not Migrate
The S7-1200/1500 instruction set drops several legacy V5.x features:
- Memory-area pointers (P#M0.0, P#DB1.DBX0.0) used by the POINTER data type are not accepted as formal parameters on S7-1200/1500 FCs. The CPU only resolves symbolic or fully-qualified absolute addresses during compilation.
- The "old" ANY pointer (16-byte legacy header) used by older V5.x variants of FC 92 is not part of the TIA Portal type system. TIA Portal ANY pointers have a different internal layout and are restricted in how they can be passed to instructions.
- The standard library that ships with STEP 7 V5.5 SPx is a separate CD image and is not installed with TIA Portal. The library must be removed before migration; only the user-written code is migrated.
As a result, the only supported approach is to reimplement the behaviour using the native bit-shift instructions documented in the TIA Portal information system.
Native Bit-Shift Instructions on S7-1200/1500
TIA Portal exposes the following bit-shifting instructions under Instructions > Bit logic operations and Instructions > Move operations:
| Instruction | Operation | Operands | Notes |
|---|---|---|---|
| SHR | Shift right | BYTE, WORD, DWORD, LWORD | Fills vacated high bits with 0; result length is operand length |
| SHL | Shift left | BYTE, WORD, DWORD, LWORD | Fills vacated low bits with 0 |
| ROR | Rotate right | BYTE, WORD, DWORD, LWORD | Bit shifted out of LSB is written into MSB |
| ROL | Rotate left | BYTE, WORD, DWORD, LWORD | Bit shifted out of MSB is written into LSB |
| SHRB | NOT available | — | No native SHRB instruction. Replaced by SHR + bit manipulation or by a custom FC. |
All four instructions are available on S7-1200 firmware V4.0+ and on every S7-1500 firmware. LWORD variant requires S7-1500 firmware V2.0+ and S7-1200 firmware V4.2+.
Reimplementing SHRB as a User-Written FC in TIA Portal
The cleanest replacement is a single-input/single-output FC that hides the data-type juggling from the caller. The following SCL snippet creates a parameter set that mirrors the legacy FC 92 interface as closely as TIA Portal will allow.
FC block interface
| Name | Declaration | Type | Comment |
|---|---|---|---|
| S_DATA | Input | Bool | Bit to shift in |
| CLK | Input | Bool | Shift clock |
| BIT_COUNT | Input | Int | Number of valid bits, 1..32 |
| SHIFT_WORD | InOut | DWord | Bit array, bit 0 = LSB = newest |
| RET_VAL | Output | Int | 0 = OK, 1 = BIT_COUNT out of range |
| CLK_EDGE | Static | Bool | Edge memory bit |
SCL implementation
FUNCTION "FC_SHRB" : Int
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
S_DATA : Bool; // Bit shifted in at position 0
CLK : Bool; // Shift clock
BIT_COUNT : Int; // 1..32 valid bits in SHIFT_WORD
END_VAR
VAR_IN_OUT
SHIFT_WORD : DWord; // Bit array, LSB = newest
END_VAR
VAR_OUTPUT
RET_VAL : Int;
END_VAR
VAR
CLK_EDGE : Bool; // Edge memory
END_VAR
BEGIN
RET_VAL := 0;
IF (BIT_COUNT < 1) OR (BIT_COUNT > 32) THEN
RET_VAL := 1; // Range error
RETURN;
END_IF;
IF CLK AND NOT CLK_EDGE THEN // Rising edge
// 1. Shift everything left by one to make room for the new bit
SHIFT_WORD := SHL(SHIFT_WORD, 1) OR DINT_TO_DWORD(BIT_COUNT - 1);
// 2. Clear bits above BIT_COUNT (one-shots)
SHIFT_WORD := SHIFT_WORD AND
SHL(DWORD#1, BIT_COUNT) - DWORD#1;
// 3. Insert the new bit at position 0
IF S_DATA THEN
SHIFT_WORD := SHIFT_WORD OR DWORD#1;
END_IF;
END_IF;
CLK_EDGE := CLK;
END_FUNCTION
InOut on a DWord tag. If the original code referenced bits scattered through memory (for example M0.0, M1.3, M5.7), they must first be packed into a contiguous DWord tag in the data block of the calling program. Symbolic or fully-qualified absolute references must be used; symbolic-only references inside an FB instance DB are not allowed as InOut parameters.LAD/FBD Alternative Without Writing Code
If you prefer to stay inside the instruction palette, the SHRB behaviour can be reproduced in two network segments:
-
Network 1 — edge detection: Place a
P=(scan operand for positive edge) coil driving a tagshrb_clk_one. Use a second tagshrb_clk_mementoas the edge memory if you cannot use the implicit edge bit of the FC. -
Network 2 — shift and OR: Place an
SHLinstruction with IN =SHIFT_WORD, N = 1, OUT =SHIFT_WORD. Then place a parallel branch withORthat conditionally ORs the constant 1 into bit 0 ofSHIFT_WORDwhenS_DATAis TRUE. -
Network 3 — mask: AND
SHIFT_WORDwith the constant maskSHL(1, BIT_COUNT) - 1to keep only the requested number of bits.
The three networks can be wrapped in a single FC by selecting Insert > FC and pasting them. The FC will then be called from the OB1 (or cyclic OB) just like the legacy FC 92.
Migrating a STEP 7 V5 Project that Uses FC 92
- Open the STEP 7 V5 project in TIA Portal via Project > Migrate project. TIA Portal will warn that unsupported library blocks must be removed.
- Delete every instance of the legacy
FC 92 SHRBfrom the program blocks. Make a list of each call site and the absolute pointer passed inS_BIT. - Add a new FC to the S7-1200/1500 program. Paste the SCL code above (or the LAD networks) and compile. Address compiler warnings about implicit type conversions before downloading.
- For each call site, replace the old pointer argument with a DWord tag that has been mapped to the original memory area. For example, the bits M0.0 to M3.7 map to
"ShiftWordM0"of type DWORD in a global DB. The four bytes must be unique – they cannot overlap with other symbolic tags used by the rest of the program. - Wire the call:
S_DATA= digital input;CLK= cycle bit or pulse generator;BIT_COUNT= constant or configurable tag;SHIFT_WORD= DWord tag.
Verification and Commissioning
Use the following checks before going online to the real CPU:
| Test | Procedure | Pass criterion |
|---|---|---|
| Static compile | Right-click the project tree > Compile > Software (rebuild all) | Zero errors, zero warnings about data type mismatches or uninitialised tags |
| PLCSIM simulation | Open S7-PLCSIM (S7-1200) or S7-PLCSIM Advanced (S7-1500). Force S_DATA through 32 distinct patterns and observe SHIFT_WORD in the watch table | After 32 clocks the register equals the 32-bit serial pattern that was fed in; bits beyond BIT_COUNT remain 0 |
| Edge detection | Toggle CLK with S_DATA held TRUE. Confirm SHIFT_WORD increments by one bit per rising edge and that falling edges are ignored | Exactly one shift per rising edge; no double shift on a held HIGH signal |
| Boundary | Set BIT_COUNT = 33 and call the FC | RET_VAL = 1 and SHIFT_WORD unchanged |
| Retentivity | Power-cycle the CPU and confirm SHIFT_WORD holds its last value | If retentive behaviour is required, declare SHIFT_WORD in a retentive DB (S7-1500: Properties > Attributes > Retain = Set) or pass it through a retentive instance DB of an FB wrapper |
Troubleshooting Matrix
| Symptom | Likely cause | Corrective action |
|---|---|---|
| Compile error: "InOut parameter SHIFT_WORD cannot be a literal" | A constant was passed instead of a tag | Insert a DWord tag in a global DB and pass it by symbolic name |
| RET_VAL = 1 on every call | BIT_COUNT tag is initialised to 0 because the calling block did not write it | Assign an initial value in the DB or set the tag at the beginning of the calling OB |
| Double shift per clock pulse | CLK_EDGE not declared in VAR or declared as TEMP instead of STATIC | Move CLK_EDGE into the STATIC section; verify with "monitor/modify" that the edge memory holds its value between cycles |
| Bits above BIT_COUNT are not cleared | Mask step skipped | Insert the AND with SHL(DWORD#1, BIT_COUNT) - DWORD#1 after the shift |
| Migration tool refuses to load the project | Legacy FC 92 still present in the program blocks | Delete the FC, re-run the migration, then add the user FC as described above |
Reference: Officially Available Bit-Shift Instructions in TIA Portal
The complete list of bit-shifting instructions available on the S7-1200/1500 is found in the TIA Portal information system under Instructions > Bit logic operations. Below is a compact mapping back to the STEP 7 V5 standard library.
| V5.x standard library FC | Function | S7-1200/1500 equivalent |
|---|---|---|
| FC 90 / FC 91 | SHR / SHL on WORD | Native SHR / SHL, operand type WORD |
| FC 92 | SHRB (single-bit shift register) | Custom FC (this article) or SHR + bit manipulation |
| FC 93 / FC 94 | ROR / ROL | Native ROR / ROL |
| FC 95 / FC 96 | SHRB variants | Same replacement as FC 92 |
For the canonical instruction catalogue, consult the S7-1200 and S7-1500 system manuals linked below.
Where can I find an official list of all TIA Portal instructions for S7-1200 and S7-1500?
The TIA Portal information system itself (press F1 on any instruction) is the authoritative source. Programmatically, you can also open Instructions > Basic instructions in the project tree; the pane lists every instruction supported by the CPU that is currently selected in the project. The S7-1200 system manual and S7-1500 system manual mirror the same catalogue in PDF form.
Is there a native SHRB instruction on S7-1200 or S7-1500?
No. S7-1200 and S7-1500 firmware does not implement a SHRB opcode. You must build the single-bit shift register either by combining SHR/SHL with bit-wise OR/AND operations, or by wrapping the logic in a custom FC or FB as shown in this article.
Can I keep using the legacy FC 92 from the S7-300 standard library?
Only on S7-300/S7-400 CPUs running STEP 7 V5.x. The FC cannot be downloaded to an S7-1200 or S7-1500 because the POINTER-based parameter interface and the legacy library headers are not supported by the newer instruction set. The FC must be reimplemented.
How many bits can the user-written FC_SHRB shift in one call?
Because the SHIFT_WORD parameter is a DWord, the maximum is 32 bits per call. For longer shift registers, chain multiple DWord tags or upgrade to LWORD (S7-1500 firmware V2.0+ or S7-1200 firmware V4.2+) to reach 64 bits per parameter.
Why is my edge flag CLK_EDGE not holding its value between cycles?
On S7-1200/1500, TEMP variables are reinitialised at the start of every block call. The edge memory must therefore be declared in the STATIC section of the FC, or in the static section of the wrapping FB instance DB. Declaring it as TEMP causes the edge detection to fire on every cycle instead of only on rising edges.