Fixing TIA Portal DBW2 Absolute Addressing After S7 Classic

David Krause10 min read
SiemensTIA PortalTroubleshooting
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

Problem Description

During STEP 7 V5.x to TIA Portal migration, Function (FC) blocks that pass a data word (for example DBW2) as an IN, OUT, or IN_OUT parameter often stop addressing the intended data block. The auto-conversion rewrites the formal parameter to a word that lives in a different DB than the one the program was originally meant to read or write. The classic symptom:

  • FC41 (or any other migrated FC) is declared with an OUT parameter originally typed as WORD and connected to DB90.DBW2 in the call environment.
  • STEP 7 V5.x compiles and simulates correctly: FC41 writes through the pointer-shaped DBW2 operand into DB90.
  • After running the TIA Portal migrator, the FC interface is preserved, but the call site automatically rewrites the connected operand. The migrator rebinds the parameter to DB91.DBW2 (the DB that was last opened globally) instead of the originally intended DB90.DBW2.
  • At runtime, FC41 opens its internal DB90 with OPN DB90, but the parameter value it manipulates still points at DB91.DBW2 because TIA Portal rejected the typed WORD interface connected directly to a DB word.

Engineers see values that look correct in the FC source but never reach the target DB. PLC tags monitored in TIA Portal online watch confirm that DB90.DBW2 never changes while the FC is being scanned.

Critical: The issue is not in the FC body but in the migrator's treatment of WORD parameters tied to DBW operands. The S7 classic compiler accepted the absolute DBW2 symbol as a fully resolvable address; the TIA Portal compiler treats it as an untyped absolute that must be qualified by a DB number.

Root Cause Analysis

Three constraints in TIA Portal explain the behavior. Knowing each one narrows the fix.

1. Absolute Address Format Requires a DB Number

In TIA Portal, every absolute address in a global DB is qualified by the DB number followed by a dot and the tag's offset. Per the STEP 7 Basic V13.1 programming and operating manual (section "Addressing variables in global data blocks"), the syntax is:

%DB<db_number>.<area><size><offset>

For example, DB90.DBW2 is internally represented as %DB90.DBX5.0 (byte 4 + bit 0 is the low byte, byte 5 is the high byte — the offset 2 in WORD units maps to byte 4, which is the LSB of the word). A bare DBW2 operand has no DB context and is rejected by the TIA Portal compiler when used as a default value or call-site operand on a typed WORD parameter.

2. The "%" Prefix and Typed Parameters

According to the S7-1200 G2 manual collection on absolute addressing, the % character is automatically prepended in LAD/FBD to mark an address as absolute. TIA Portal still expects a fully qualified operand; the bare DBW2 syntax from STEP 7 classic is not legal at the call interface.

3. The Migrator's Conservative Rewrite

The STEP 7 V5.x → TIA Portal migrator scans each FC/FB call site and, for any operand it cannot bind symbolically, generates a fully qualified absolute address from the currently open DB in the calling block. If the calling block opens DB91 just before the FC call, the migrator assumes DBW2 meant DB91.DBW2. The original design intent (a parameter that points to an arbitrary DB selected at runtime) is lost unless the source code is restructured before migration.

Affected Firmware and Software Versions

Component Affected Versions Notes
STEP 7 V5.5 / V5.6 source All service packs Source of the migrated program
TIA Portal V13 Up to V13 SP2 Initial migrator with limited parameter binding
TIA Portal V14 / V15 / V15.1 All service packs Migrator behavior unchanged; manual fixes still required
TIA Portal V16 / V17 / V18 All service packs Improved symbolic migration, but the typed-WORDDBW interface pattern still requires restructuring
S7-300/400 CPU firmware All Original target; no firmware change required
S7-1200/1500 CPU firmware All New target; the migrated code runs identically on these CPUs after recompile

Solution 1: Eliminate the DBOU/DBIN Pattern with OPN DB

The most direct fix when an FC uses an output parameter DBOU (or input DBIN) to designate a data word inside a globally opened DB.

  1. Open the migrated FC in TIA Portal.
  2. Delete the DBOU (or DBIN) parameter from the FC interface.
  3. Inside the FC body, replace any reference to DBOU with the symbolic name of the tag the calling block intends to read or write, e.g., "MyPlant".outWord or DB90.DBW2.
  4. At the FC call site in the calling OB/FB, add an explicit OPN DB90 (or use the equivalent OPN "MyDB" in SCL) immediately before the FC call. This matches the S7 classic semantics that the migrator lost.

Sample SCL pattern to express this in TIA Portal SCL:

// OB1 (cyclic)
IF "startCondition" THEN
    OPN "PlantDataDB";          // DB90, opened before call
    "MyFC"(enable := TRUE,     // FC41 in this example
           index  := 2);        // pass offset, not the word
END_IF;

Inside the FC body, dereference the index against the currently open DB using a P# pointer and BLD/area-internal instructions, or simply read the symbol that the caller exposed via the call interface.

Solution 2: Encode the Full DB Address in the Call Site

If the FC must remain generic (called from many places, each pointing at a different DB), pass the symbolic DB tag instead of a bare word offset.

  1. Declare a parameter on the FC of type DB_ANY or, more usefully, an IN_OUT parameter of type VARIANT that points at the actual data word.
  2. At each call site, supply the symbolic tag, e.g., "PlantData".speedSetpoint, which the compiler resolves to DB90.DBW2.
// FC interface (TIA Portal SCL)
{ S7_Optimized_Access := 'FALSE' }
FUNCTION "ProcessWord" : Void
VAR_INPUT
    enable : BOOL;
END_VAR
VAR_IN_OUT
    target : VARIANT;   // points at DB90.DBW2 in this call
END_VAR
BEGIN
    IF enable THEN
        WORD_TO_INT(tag := target);   // user logic, fully typed
    END_IF;
END_FUNCTION

Call site in an FB:

"ProcessWord"(enable := TRUE,
               target := "PlantData".speedSetpoint);

The migrator does not produce this interface automatically; it must be added to the FC before recompiling. Once done, the FC carries the address context with it and the wrong-DB problem cannot recur.

Solution 3: Use an Index Instead of the Word Itself

For FCs that operate on a configurable word offset within a known DB, replace the parameter DBOU : WORD with DBOU_INDEX : INT and reconstruct the pointer inside the FC.

  1. Change the FC interface: DBOU : WORDindex : INT.
  2. Add a constant DB_NUMBER : INT = 90 at the top of the FC, or pass it as an additional DB_NO parameter.
  3. Inside the FC, build the area pointer: OPN DB[#db_no] and then use L P#[index] or L DIX [#index] to fetch the value from the open DI/DB.
// FC body (SCL, S7-1500 syntax)
VAR_TEMP
    pWord : POINTER;
    wValue : WORD;
END_VAR
BEGIN
    pWord := P#DB90.DBX [index * 2];   // word offset × 2 = byte offset
    wValue := WORD_AT(pWord);
    // ...
END_FUNCTION

This pattern is portable across S7-300/400/1200/1500 and survives re-migration because no DB number is hard-coded at the call interface.

Solution 4: Preserve the Original Pointer in STL Source

If the FC body is STL and you have the source from STEP 7 V5.x, you can keep the pointer arithmetic but add the missing qualification so TIA Portal accepts it.

// STL body of FC41 (after migration)
OPN   #DBOU_DB        // new local DB number, passed in
L     DIB [#DBOU]     // or DBB / DIW / DID depending on size
T     %DB90.DBW2      // explicit, fully qualified
BE

The %DB90.DBW2 syntax is what TIA Portal's absolute-address resolver expects, and the OPN instruction uses the runtime DB number so the FC remains generic.

Step-by-Step Migration Workflow

  1. Export the STEP 7 V5.x project to a TIA Portal-readable archive (.zip or .s7p).
  2. Open TIA Portal and run the migrator. Capture the conversion log.
  3. Compile the migrated project. Note every error and warning.
  4. For each error of the form "The address DBW<n> cannot be assigned to the parameter of type WORD", apply Solution 1, 2, or 3 above based on the FC's call frequency.
  5. Recompile. Verify the error list is empty.
  6. Download to the target CPU (or PLCSIM) and run an online watch on every DBW the FC is supposed to touch.
  7. Force a value through the FC and confirm it appears at the correct offset in the correct DB.

Verification

Check Method Pass Criteria
Compiler clean Project → Compile (Software) 0 errors, 0 warnings related to FC41/DBW
DB consistency Project tree → Program blocks → DB90 DBW2 declaration matches the FC's intended access size (WORD, INT, or REAL)
Online watch Online → Monitor/Modify Writing to the FC input updates DB90.DBW2 within one cycle
Cross-reference Right-click DBW2 → Cross-references Only one write site: the FC body; only one read site: the consumer block
PLCSIM test S7-PLCSIM V16+ Sequence table shows the value at DB90.DBW2 changing in step with the FC's call

Common Pitfalls

  • Forgetting the OPN after a multi-instance call. The migrator may strip the OPN DB90 if the calling FB uses multi-instances. Re-insert it before the FC call.
  • Optimized block access. S7-1500 optimized blocks hide absolute offsets. The %DB90.DBW2 syntax still works in SCL, but the symbolic tag is preferred to remain migration-safe.
  • Watchdog timeouts. Adding an OPN instruction inside a fast OB (e.g., OB35 with a 1 ms period) is fine, but if the FC runs in OB1 and the OB also needs to open its own DB, the runtime DB becomes the OPN-ed one only for the duration of the FC. Confirm with a "DI" / "DB" read-back inside the FC if nesting matters.
  • Symbolic vs. absolute mismatch. Renaming a DB after migration breaks the hard-coded DB90 reference. Prefer symbolic names ("PlantData") for long-term maintenance.

Best Practices for Future Conversions

  1. Refactor S7 classic code to use VARIANT or DB_ANY parameters before the next migration, even if the current TIA Portal version handles bare DBW operands.
  2. Always pair a WORD interface parameter with a fully qualified absolute address in the call site comment so the next migration tool or engineer can see the intent.
  3. Maintain a written migration log that records every FC/FB where a DBW/DBB/DBD parameter was preserved and which DB it originally pointed at. This avoids the "trace every call" effort that complicates large S5 → TIA conversions.
  4. Run the migration on a copy of the project first; the auto-rewriter to DB91.DBW2 is not always reversible from the GUI without a backup.
  5. For high-frequency FCs in motion or PID paths, prefer the index-based approach (Solution 3) to keep the FC CPU-agnostic and migration-agnostic.

Diagnostic Quick Reference

Symptom Likely Cause First Action
FC value not reaching target DB Migrator rebound DBW to wrong DB number Open the FC call site, verify the bound absolute address
Compiler error "Cannot convert WORD to POINTER" FC expects a pointer, caller supplied a value Refactor parameter to VARIANT or POINTER
Online watch shows correct DB, value still wrong Another FC/FB is overwriting the word in the same cycle Use cross-references to find additional writers
PLCSIM passes, real CPU fails Different firmware; OPN semantics differ on S7-1500 Use symbolic DBs and check the "Use symbolic addressing" project option

FAQ

Why does STEP 7 classic accept DBW2 as a parameter operand but TIA Portal rejects it?

STEP 7 V5.x resolves DBW2 against the currently open DB at compile time, and the migrator then rebinds the resolved absolute to whichever DB was open at the call site. TIA Portal's compiler requires a fully qualified operand of the form DB<n>.DBW<offset> at every call site, so a bare DBW2 fails with a type-conversion error.

Can I keep using absolute addresses like DBW2 in TIA Portal?

Yes, but always qualify them with the DB number, e.g., DB90.DBW2. For S7-1500 optimized blocks, prefer the symbolic tag (for example "PlantData".speedSetpoint) because the compiler can validate the type and the address together.

How do I find every FC call where the migrator rebound the wrong DB?

Right-click the formal parameter in the FC interface, choose Go to → Usage in TIA Portal, and inspect each call site's bound operand. Sort by the DB number prefix; any deviation from the original S7 classic value flags a call that needs manual correction.

Is OPN DB still required on S7-1500 with optimized blocks?

For symbolic access in optimized blocks, no. For any remaining absolute access pattern (including migrated code), yes — the OPN DB[#db_no] instruction still sets the runtime DB and is required when the FC uses DBW/DBB/DBD indirectly.

What is the safest long-term pattern for FCs that read or write a word in a caller-selected DB?

Use a VARIANT or POINTER IN_OUT parameter and pass the symbolic tag from the call site. The variant carries both the DB number and the offset, removing the dependency on the runtime open DB and surviving future TIA Portal migrations intact.

Back to blog