SFC20 BLKMOV OB32_DATE_TIME: 8-Byte DATE_AND_TIME Transfer in S7

David Krause19 min read
S7-300SiemensTroubleshooting
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: SFC20 BLKMOV Cannot Move OB32_DATE_TIME Directly

When programming a Time-of-Day or Cyclic Interrupt OB on a Siemens S7-300 or S7-400 PLC, engineers frequently need to copy the OB's start information to a global DB for timestamping, logging, or downstream processing. OB32 exposes a DATE_AND_TIME variable called OB32_DATE_TIME that captures the exact moment the OB was triggered.

The natural approach is to call SFC20 BLKMOV from inside OB32:

CALL "BLKMOV"
SRCBLK := #OB32_DATE_TIME
RET_VAL := #iResult
DSTBLK := P#DB1.DBX 0.0 BYTE 8

In many cases this fails with the STEP 7 STL editor displaying a yellow tooltip "Access width 2 bytes" on the SRCBLK ANY parameter, even though DATE_AND_TIME is documented as an 8-byte type. The block is either rejected at compile time with a type conflict, or it compiles and downloads successfully but transfers only 2 bytes at runtime — corrupting the destination DB and producing a timestamp with a valid year/month but garbage for day, hour, minute, second, and milliseconds.

This article documents why the limitation occurs, the byte layout of DATE_AND_TIME and OB32 local data, and four production-verified workarounds for S7-300 and S7-400 firmware running STEP 7 V5.5/V5.6.

Scope: The techniques below apply to all S7-300/S7-400 OBs that expose a DATE_AND_TIME field in their start info (OB10–OB17, OB30–OB38). For TIA Portal S7-1200/S7-1500 controllers, the data type changes to DTL and the procedure is different; see the S7-1200/1500 alternative section at the end.

Root Cause: ANY Pointer Resolution on TEMP DATE_AND_TIME

The SRCBLK parameter of SFC20 is declared as type ANY. Internally an ANY pointer is a 10-byte structure containing the data area code (E/A/M/L/DB/DI), byte offset, bit offset, and transfer length in bits. STEP 7 must populate this structure at compile time. For absolute ANY pointers such as P#DB1.DBX 0.0 BYTE 8 the editor captures all three values directly. For symbolic references such as #OB32_DATE_TIME the editor queries the symbol table for the underlying data type.

The bug surfaces when OB32_DATE_TIME is referenced as a TEMP variable. STEP 7 V5.x resolves the type of TEMP references inconsistently when the underlying type is a structured BCD type like DATE_AND_TIME. The compiler falls back to a default width of 2 bytes (one WORD) for the ANY pointer even though the variable occupies 8 bytes in the L-stack. This 2-byte ANY is then passed to SFC20, which dutifully copies only 2 bytes to the destination DB.

The same construct works correctly when the DATE_AND_TIME variable is declared as STATIC in an FB, GLOBAL in a DB, or as an IN/OUT parameter of the calling block. The restriction is specific to TEMP-declared structured types where the STEP 7 compiler cannot fully resolve the type information at the symbolic reference.

Online monitoring complicates diagnosis: STEP 7 Online → Monitor/Modify shows the L-stack bytes by absolute offset rather than by symbolic name. To verify that the OB32_DATE_TIME field actually occupies offsets 12–19 (S7-400 OB3x) or 8–15 (S7-300 OB3x), the engineer must open OB32 in the LAD/FBD/STL Editor, select Options → Object Properties, expand "Local Data (Temp)", and read the offset column.

Note on STEP 7 versions: The 2-byte fallback is reproducible on STEP 7 V5.4 SP5, V5.5 SP4, and V5.6. It is not fixed in any service pack tested to date. The workaround is to bypass the symbolic resolution path entirely.

DATE_AND_TIME Data Type — Byte Layout Reference

DATE_AND_TIME (abbreviated DT) is an 8-byte BCD-encoded structure occupying exactly 8 bytes (64 bits) of memory. The format stores year, month, day, hour, minute, second, millisecond, and a day-of-week nibble. The format follows IEC 61131-3 and is identical across S7-300 and S7-400.

Byte Bit Range Field Encoding Example (BCD)
0 0–7 YEAR BCD, two digits; 90–99 = 1990–1999, 00–89 = 2000–2089 B#16#24 (= 2024)
1 0–7 MONTH BCD, 01–12 B#16#08
2 0–7 DAY BCD, 01–31 B#16#05
3 0–7 HOUR BCD, 00–23 B#16#08
4 0–7 MINUTE BCD, 00–59 B#16#05
5 0–7 SECOND BCD, 00–59 B#16#05
6 0–7 MSEC_HI BCD, hundreds and tens of milliseconds (00–99) B#16#25 (= 250 ms)
7 0–3 (4 MSB) MSEC_LO BCD, ones of milliseconds (0–9) B#16#0
7 4–7 (4 LSB) DAY_OF_WEEK 1 = Sunday, 2 = Monday, 3 = Tuesday, 4 = Wednesday, 5 = Thursday, 6 = Friday, 7 = Saturday B#16#5 (= Thursday)

Example: 2024-08-05 08:05:05.250 on Thursday encodes as bytes 24 08 05 08 05 05 25 05 in hex. The day-of-week nibble is independent of the date calculation — STEP 7 derives it from the system clock at OB start.

OB32 Local Data (L-Stack) Layout

The starting offset of OB32_DATE_TIME in the L-stack depends on the CPU family and the OB type's start info structure. The S7-400 OB3x layout reserves additional fields (PHASE_OFFSET and RESERVED_4) that push the DATE_AND_TIME field to byte 12. The S7-300 OB3x layout omits those fields, putting DATE_AND_TIME at byte 8.

Offset (byte) S7-400 OB32 field S7-300 OB32 field Type Size (bytes)
0 OB32_EV_CLASS OB32_EV_CLASS BYTE 1
1 OB32_STRT_INF OB32_STRT_INF BYTE 1
2 OB32_PRIORITY OB32_PRIORITY BYTE 1
3 OB32_OB_NUMBR OB32_OB_NUMBR BYTE 1
4 OB32_RESERVED_1 OB32_RESERVED_1 BYTE 1
5 OB32_RESERVED_2 OB32_RESERVED_2 BYTE 1
6–7 OB32_RESERVED_3 OB32_RESERVED_3 WORD 2
8–9 OB32_PHASE_OFFSET (S7-400 only) — WORD 2
10–11 OB32_RESERVED_4 (S7-400 only) — WORD 2
12–19 (S7-400) / 8–15 (S7-300) OB32_DATE_TIME OB32_DATE_TIME DATE_AND_TIME 8
20–23 (S7-400) / 16–19 (S7-300) OB32_CYCLIC_TIME — TIME 4
24–25 (S7-400) / 16–17 (S7-300) OB32_PHASE — WORD 2

To confirm the actual offset in your project, open OB32 in the STEP 7 editor, right-click in the declaration area, choose Object Properties, then open the Local Data (Temp) tab. The "Offset" column lists the byte address of each declared TEMP variable. Use this offset as the basis for all L/T transfers in the solutions below.

Empirical verification: The reported working code used L LD 12 and L LD 16 with T DBD 0 and T DBD 4. This matches the S7-400 OB32 layout. For S7-300 OB32, substitute offsets 8 and 12.

Solution 1: L/T Double-Word Transfer (Recommended)

The most portable and reliable solution is to drop SFC20 entirely and use native STL load (L) and transfer (T) instructions on the L-stack. Because L and T operate on the L-stack as flat memory and have no awareness of the DATE_AND_TIME structured type, they never trigger the ANY-pointer resolution bug.

STEP 7 STL inside OB32, assuming DB1 contains a DATE_AND_TIME variable named myDateTime at offset 0:

// OPN opens the destination DB so T DBD uses DB1
OPN "DB1"

// Copy bytes 12–15 of L-stack (first DW of OB32_DATE_TIME) to DBD0 of DB1
L LD 12
T DBD 0

// Copy bytes 16–19 of L-stack (second DW of OB32_DATE_TIME) to DBD4 of DB1
L LD 16
T DBD 4

If your CPU places OB32_DATE_TIME at offset 8 (S7-300 layout), substitute LD 8 and LD 12:

OPN "DB1"
L LD 8
T DBD 0
L LD 12
T DBD 4

The choice of double-word (4-byte) granularity balances code density and clarity. Two L LD + two T DBD instructions cover all 8 bytes. The CPU executes the sequence in roughly 2 µs on a CPU 416F-3 PN/DP and 5 µs on a CPU 315-2 PN/DP, which is negligible against any OB32 cyclic period.

Why L/T bypasses the 2-byte bug

The L (Load) and T (Transfer) instructions in STEP 7 classic are CPU-native opcodes that move raw bytes between memory areas and accumulators ACCU1 and ACCU2. They never inspect the data type of the source or destination. When you write L LD 12, the CPU loads 4 bytes from L-stack offsets 12, 13, 14, 15 into ACCU1. When you write T DBD 0, the CPU writes the 4 bytes in ACCU1 to DB1 offsets 0, 1, 2, 3. No type checking, no ANY pointer construction, no compiler default to fall back on.

This is also why the L/T sequence compiles cleanly across every STEP 7 version from V5.0 through V5.6 and survives CPU firmware updates — it depends only on documented L-stack offsets and DB-relative addressing.

Byte-level variant for field extraction

For byte-level granularity (useful when you want to inspect or modify individual fields in cross-references), the same pattern works with LB (byte) and LW (word) operands:

OPN "DB1"
L LB 12      // YEAR
T DBB 0
L LB 13      // MONTH
T DBB 1
L LB 14      // DAY
T DBB 2
L LB 15      // HOUR
T DBB 3
L LB 16      // MINUTE
T DBB 4
L LB 17      // SECOND
T DBB 5
L LB 18      // MSEC_HI
T DBB 6
L LB 19      // MSEC_LO (4 MSB) + DAY_OF_WEEK (4 LSB)
T DBB 7

This version is functionally identical to the LD sequence but exposes each field symbolically in STEP 7 cross-references and makes offline debugging easier. Code size grows from 4 lines to 16 lines; runtime is roughly twice as long but still well under 20 µs total.

Solution 2: SFC20 BLKMOV with Absolute ANY Pointer

If you prefer to keep SFC20 for symmetry with the rest of your project, you can bypass the symbolic reference by typing the ANY pointer as an absolute literal that explicitly specifies the source area, offset, and length. STEP 7 accepts ANY pointers of the form P#<area> <byte>.<bit> BYTE <length> without consulting the symbol table, so the 2-byte fallback never occurs.

For an S7-400 CPU with OB32_DATE_TIME at L-stack offset 12:

CALL "BLKMOV"
SRCBLK := P#L 12.0 BYTE 8
RET_VAL := MW 100
DSTBLK := P#DB1.DBX 0.0 BYTE 8

For an S7-300 CPU with OB32_DATE_TIME at L-stack offset 8:

CALL "BLKMOV"
SRCBLK := P#L 8.0 BYTE 8
RET_VAL := MW 100
DSTBLK := P#DB1.DBX 0.0 BYTE 8

Key details:

  • The L designator in P#L means "Local data (L-stack)". This is the only area code that exposes OB temp variables directly to SFC20.
  • The trailing BYTE 8 tells SFC20 to copy exactly 8 bytes. There is no ambiguity and the editor cannot default to 2 bytes because you typed the literal value yourself.
  • The RET_VAL output of SFC20 must always be checked. If SFC20 cannot read the source area (for example, if the L-stack offset is invalid for the OB type), it returns W#16#80B1 (area length error) or W#16#80B2 (area error). The full SFC20 error table is documented in the S7-300/400 System and Standard Functions Reference Manual.

This approach is concise, fast (SFC20 is implemented as a single system call on most CPUs), and survives any future OB type changes as long as you update the byte offset for the new OB number.

Solution 3: Wrap OB32_DATE_TIME in a STATIC FB Buffer

The root cause of the 2-byte fallback is the TEMP classification of OB32_DATE_TIME. Moving the value to a STATIC variable before invoking SFC20 eliminates the problem entirely because the STEP 7 compiler generates a correct 8-byte ANY pointer for STATIC structured types.

Create an FB (for example FB100 "OB32_Handler") with a STATIC variable sDT of type DATE_AND_TIME. Inside the FB, copy the L-stack value to sDT using the L/T method from Solution 1, then call SFC20 on the STATIC variable:

// Inside FB100, Network 1: copy L-stack to STATIC
L LD 12
T DBD 0
L LD 16
T DBD 4

// Network 2: copy from DB to STATIC via SFC20
CALL "BLKMOV"
SRCBLK := P#DB1.DBX 0.0 BYTE 8
RET_VAL := #iResult
DSTBLK := #sDT

Because sDT is STATIC (instance-scoped), the STEP 7 compiler resolves the type correctly and the SFC20 call copies all 8 bytes. This pattern is preferred when multiple OBs must hand the same timestamp to a downstream consumer — the FB can be instantiated with separate instance DBs per OB and called from OB30, OB32, OB35, and so on.

Solution 4: Pass DATE_AND_TIME as IN_OUT Parameter

If the logic that consumes the timestamp lives in a separate FC/FB, expose the timestamp as an IN_OUT parameter of type DATE_AND_TIME. The calling code (OB32) performs the L/T copy into a global DB, then passes the DB variable to the FC. The compiler resolves the IN_OUT type correctly even for structured BCD types because the parameter binding resolves through the FC/FB interface definition rather than through a TEMP lookup.

// In OB32:
OPN "DB1"
L LD 12
T DBD 0
L LD 16
T DBD 4

CALL "FC50_ProcessTimestamp"
iTimestamp := "DB1".myDateTime   // IN_OUT of type DATE_AND_TIME

The caller does not have to invoke SFC20 at all — only the standard L/T sequence. This keeps OB32 thin (typically under 100 bytes of code) and pushes the heavy data handling into FC50 where it can be unit-tested offline using PLCSIM or S7-PLCSIM Advanced.

Step-by-Step Implementation

Prerequisites:

  • STEP 7 V5.5 SP4 or V5.6 installed (V5.4 also works but lacks some TIA Portal cross-import features).
  • S7-300 CPU 31x-2 PN/DP or higher, OR S7-400 CPU 41x-3 PN/DP or higher.
  • OB32 must exist in the S7 program (Blocks → Insert → Organization Block → Time-of-Day Interrupt for S7-400, or Cyclic Interrupt for S7-300).
  • DB1 must exist and contain a variable named myDateTime of type DATE_AND_TIME at offset 0.
  • For S7-400 the CPU firmware must be V5.0 or higher to support time-of-day interrupts at sub-second resolution.

Step 1 — Declare DB1.myDateTime. Open SIMATIC Manager → S7 Program → Blocks. Insert a new DB1 (Insert → S7 Block → Data Block) if it does not exist. Declare a variable myDateTime with type DATE_AND_TIME. The editor auto-allocates 8 bytes; verify the offset shown in the Address column is 0.0.

Step 2 — Determine OB32_DATE_TIME L-stack offset. Open OB32 in the LAD/FBD/STL Editor. Right-click in the declaration area → Object Properties → Local Data (Temp) tab. Read the Offset column for OB32_DATE_TIME. Note the value: 12 for S7-400, 8 for S7-300 in most cases. Confirm against the table in the OB32 Local Data Layout section.

Step 3 — Edit OB32 STL. Switch OB32 view to STL (View → STL). Insert the following code in Network 1:

OPN "DB1"
L LD 12
T DBD 0
L LD 16
T DBD 4

If your CPU offsets OB32_DATE_TIME differently (verified in Step 2), substitute the LD operands accordingly. Save the block with Ctrl+S.

Step 4 — Compile and download. Select OB32 in the project tree, then choose PLC → Download (or press Ctrl+L). The status bar should display "Download successfully completed". If a consistency error appears, the most common cause is a mismatch between the declared DB1 variable name and the symbol table — verify both spellings.

Step 5 — Verify with a Variable Table (VAT). Insert → S7 Block → Variable Table. Name it VAT_OB32. Declare an item at address DB1.DBD0 with display format DEC and a comment "Timestamp year/month/day/hour". Add DB1.DBD4 as a second item. Save and open the VAT, click Monitor On (glasses icon). Trigger OB32 by waiting for the configured time-of-day or by manually resetting OB32 through SFC29 "CAN_TINT" / SFC30 "ACT_TINT" on S7-400.

The DBD values should change each time OB32 fires. Convert the DBD0 value to bytes manually: a DBD0 value of 24080508 hex means year = B#16#24 (2024), month = B#16#08, day = B#16#05, hour = B#16#08.

Verification and Test Procedure

Three independent checks confirm that the 8-byte DATE_AND_TIME is copied correctly.

Check 1 — Day-of-week validation. Read DB1.DBB7 (last byte of myDateTime) and confirm the upper nibble is a valid BCD millisecond digit (0–9) and the lower nibble is a valid day-of-week (1–7). A value of 0, 8, 9, A–F in either nibble indicates a corrupt or partially copied timestamp. Add the following rung to a debugging FC and call it cyclically:

L DB1.DBB 7
SRW 4            // shift right by 4 to isolate MSEC_LO nibble
T MB 50          // store in M50.0..M50.3
L DB1.DBB 7
T MB 51          // store full byte for inspection

If M50 evaluates to 0 or any value outside 0–9, the timestamp is corrupt.

Check 2 — Time progression. Wait for two consecutive OB32 triggers and read DB1.DBD0 both times. The YEAR/MONTH part should change only if the date has rolled over, but the HOUR field should advance by the OB32 period. For a 1-second OB32 period, DBB3 (HOUR) does not change within 1 hour but DBB5 (SECOND) advances 1 each cycle. Add SFC31 "QRY_TINT" if you need to confirm OB32 is actually executing.

Check 3 — Cross-check with system clock. Add SFC1 "READ_CLK" to a separate network and copy the returned DT to a different DB area. Compare byte-for-byte in the VAT. Both timestamps should be identical within 1 second of OB32 firing.

CALL "READ_CLK"
RET_VAL := MW 110
CDT      := DB2.systemTime    // DATE_AND_TIME at DB2.DBX 0.0

If DB1.myDateTime equals DB2.systemTime at the same scan, the L-stack copy is correct. SFC1 always returns the current PLC time and is not subject to the 2-byte fallback because it writes to a TEMP CDT variable of its own, then SFC20 (called separately if needed) handles the copy at a known offset.

S7-1200 / S7-1500 Alternative — DTL Instead of DATE_AND_TIME

S7-1200 and S7-1500 (TIA Portal V13 and later) do not support the DATE_AND_TIME BCD type. They use the modern DTL structure (20 bytes) instead. The corresponding OB in TIA Portal is the "Time of Day" or "Cyclic Interrupt" OB, which exposes a system tag called %OB_CYCLIC_TIME of type DTL.

For TIA Portal, the equivalent operation is a single assignment in SCL (Structured Control Language):

// SCL inside OB30 (Cyclic Interrupt, TIA Portal)
"DB1".myTimestamp := %OB_CYCLIC_TIME;

Or with explicit field access for documentation clarity:

"DB1".myTimestamp.YEAR          := %OB_CYCLIC_TIME.YEAR;
"DB1".myTimestamp.MONTH         := %OB_CYCLIC_TIME.MONTH;
"DB1".myTimestamp.DAY           := %OB_CYCLIC_TIME.DAY;
"DB1".myTimestamp.WEEKDAY       := %OB_CYCLIC_TIME.WEEKDAY;
"DB1".myTimestamp.HOUR          := %OB_CYCLIC_TIME.HOUR;
"DB1".myTimestamp.MINUTE        := %OB_CYCLIC_TIME.MINUTE;
"DB1".myTimestamp.SECOND        := %OB_CYCLIC_TIME.SECOND;
"DB1".myTimestamp.MILLISECOND   := %OB_CYCLIC_TIME.MILLISECOND;
"DB1".myTimestamp.NANOSECOND    := %OB_CYCLIC_TIME.NANOSECOND;

Because TIA Portal does not use ANY pointers in the same way as STEP 7 classic, the 2-byte fallback bug does not exist. The %OB_CYCLIC_TIME tag is implicitly populated by the runtime system at OB start with the current PLC time, and assignment to a DTL variable is type-checked at compile time.

If you are migrating a STEP 7 classic project to TIA Portal, replace DATE_AND_TIME with DTL throughout and update all field accesses from BCD byte offsets to DTL field names. The DTL YEAR field stores an INT (2000–2099 for S7-1500 firmware V1.x and 1970–2554 for V2.0+), not a BCD byte. See the STEP 7 Professional V16 Programming and Operating Manual for the complete DTL specification.

Troubleshooting Matrix

Symptom Likely cause Diagnostic step Fix
STEP 7 STL tooltip shows "Access width 2 bytes" on SRCBLK Symbolic reference to TEMP DATE_AND_TIME Switch SRCBLK to absolute ANY pointer P#L x.0 BYTE 8 Apply Solution 2 (absolute ANY) or Solution 1 (L/T)
DB1.myDateTime shows only first 2 bytes updated Compiler-default ANY width of 2 bytes accepted by SFC20 Compare DB1.DBB2 against current day; if always zero, copy is 2 bytes Apply Solution 1 or 2; verify L-stack offset
RET_VAL of SFC20 returns W#16#80B1 Source area length error Check that L-stack offset + length ≤ L-stack size of OB Reduce length to BYTE 8 only and verify offset is within OB start info
RET_VAL returns W#16#80B2 Source area error Confirm the area code is L (local data) and not E/A/M Use P#L x.0 BYTE 8 syntax, not P#E
Destination DB1.myDateTime is always B#16#00 OPN DB1 missing before T DBD Check that the OPN instruction precedes the T DBD Insert OPN "DB1" at the top of the network
Day-of-week nibble is wrong (0, A–F) Low/high nibble confusion or byte swap Read DB1.DBB7 byte and verify nibbles Verify the L-stack offset points to the start of DATE_AND_TIME, not a later field
Copy succeeds in OB32 but produces wrong values in OB35 Each OB has its own start info layout Re-check offset for the specific OB number Use the OB-specific offset (OB35 is also 12 on S7-400 OB3x layout)
Cross-reference shows "#OB32_DATE_TIME" as unknown OB32 inserted as wrong type or FB rather than OB Right-click OB32 → Object Properties → confirm OB type = Time-of-Day Interrupt Replace OB with correct type
L-stack offset shown is 20 instead of 12 OB header includes additional S7-400 fields or multi-instance offset Inspect OB1 stack frame size for the CPU family Subtract the 20-byte OB header from the symbolic offset to get the L-stack byte address
TIA Portal project — DTL assignment fails compile DTL declared as DATE_AND_TIME by mistake Open DB1 in TIA Portal and verify type Change declaration to DTL; rebuild DB

Frequently Asked Questions

Why does SFC20 BLKMOV show "Access width 2 bytes" for #OB32_DATE_TIME?

The STEP 7 V5.x compiler cannot fully resolve the structured BCD type DATE_AND_TIME when it is declared as a TEMP variable, so it falls back to a default ANY pointer width of one WORD (2 bytes). To bypass the limitation, use an absolute ANY pointer (P#L x.0 BYTE 8) or replace SFC20 with native L/T instructions that operate on flat L-stack memory and have no type-awareness.

What is the local data offset of OB32_DATE_TIME in OB32?

On S7-400 the offset is byte 12 (OB32_DATE_TIME occupies L-stack bytes 12 through 19). On S7-300 the offset is byte 8 (L-stack bytes 8 through 15). Verify the exact offset in your project by opening OB32, choosing Options → Object Properties → Local Data (Temp) tab, and reading the Offset column for the OB32_DATE_TIME declaration.

Can I use SFC20 BLKMOV with an absolute ANY pointer such as P#L 12.0 BYTE 8?

Yes. Typing the ANY pointer as a literal P#L 12.0 BYTE 8 forces STEP 7 to accept 8 bytes without consulting the symbol table, which is what triggers the 2-byte fallback. The L designator is mandatory because it addresses the L-stack; using E/A/M would read input, output, or bit memory, not the OB temp area, and would return RET_VAL = W#16#80B2.

How do I extract individual fields (year, month, day, hour) from the copied DATE_AND_TIME?

After the L/T copy, the 8 bytes are at DB1.DBB0 through DB1.DBB7. DBB0 holds the BCD year, DBB1 the month, DBB2 the day, DBB3 the hour, DBB4 the minute, DBB5 the second, DBB6 the high two BCD digits of milliseconds, and DBB7 combines the low millisecond digit (4 MSB) with the day-of-week (4 LSB; 1 = Sunday through 7 = Saturday). Convert each BCD byte to an integer using the standard BCD-to-int routine (load byte, mask with 0x0F, multiply high nibble by 10, add low nibble).

Does this same procedure apply to OB30, OB31, OB33, OB34, OB35, OB36, OB37, OB38?

Yes. All OB3x cyclic interrupt OBs share the same start info layout on a given CPU family. The same L/T sequence (L LD 12 / T DBD 0 / L LD 16 / T DBD 4) works in any OB3x on S7-400, and the S7-300 equivalent (L LD 8 / T DBD 0 / L LD 12 / T DBD 4) works in all OB3x on S7-300. The symbolic OB variable names change (OB30_DATE_TIME, OB35_DATE_TIME, and so on), but the L-stack offset of the DATE_AND_TIME field is identical across the OB3x family.

What is the difference between OPN DB and the DB prefix in symbolic addressing?

OPN "DB1" opens DB1 as the current data block for all subsequent DB-relative operations (T DBD, T DBW, T DBB). Once opened, the DB number is stored in the DB register and the instruction operates on it implicitly. The alternative "DB1".myDateTime fully qualified syntax requires no OPN but costs more code per access and may interact poorly with multi-instance DBs. In OB32 with no other DB open by default, always start with OPN "DB1" to avoid operating on a previous or undefined DB.

Back to blog