S7-1200 PUT/GET: Configuring DB Exchange Between Two CPUs

David Krause12 min read
S7-1200SiemensTutorial / 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

Overview

Two S7-1200 CPUs can exchange Data Block (DB) contents without any additional hardware by using the integrated S7 Communication protocol carried over Profinet. The mechanism is implemented by the PUT and GET instructions, which Siemens documents in the S7-1200 system manual and the CPU-to-CPU communication compendium. A single CPU initiates the exchange, the partner CPU acts as the server, and Profinet transport handles the framed payload.

Typical applications include:

  • Distributed machine cells sharing hand-off state, recipe, or counter data.
  • Coordinated traffic, conveyor, or process systems where a vehicle or part must cross a boundary controlled by a second PLC.
  • Redundant supervisory structures where a master CPU mirrors status DBs from a satellite CPU.

The constraint that drives most of the engineering effort is the 160-byte per call ceiling on user data. Once a project exceeds that, the calls must be sequenced by the application program. Siemens publishes a dedicated FAQ that defines a multi-call sequencing pattern, referenced in the Verification section below.

Prerequisites

Item Requirement Notes
CPU 1 and CPU 2 SIMATIC S7-1200, any DC/DC/DC or AC/DC/RLY variant Both CPUs must support S7 Communication. All S7-1200 CPUs from the original 1211C through the 1217C support PUT/GET as long as S7 Communication is enabled.
Firmware V4.0 or later recommended; V4.2 or later for optimized block access Older firmware builds still implement PUT/GET but with stricter block type rules (no optimized DBs).
Engineering software STEP 7 Basic / Professional in TIA Portal V13 SP1 minimum for the legacy "non-optimized" configuration. V15.1 and later for symbolic access on optimized blocks.
Topology Direct Profinet cable or shared Profinet network with managed switch Each CPU must have an IPv4 address in the same subnet. No router required for point-to-point links.
Maximum distance 100 m per Profinet copper segment Fiber media converters extend this if required.
Partner CPU protection "Permit access with PUT/GET communication" enabled on the partner CPU Configured in Device Configuration → Properties → Protection & Security. Disabled by default from firmware V4.x.
Critical setting: If the partner CPU does not have PUT/GET access enabled, every PUT/GET instruction returns STATUS = 0x80D3 ("Connection refused") even though the network is healthy. Always verify this option before chasing cable or IP faults.

Network and IP Configuration

Each CPU occupies a Profinet interface X1 (port 1) with a single IP address. Assign fixed IP addresses; do not rely on DHCP for deterministic CPU-to-CPU traffic.

  1. Open the project in TIA Portal and select the first CPU in Devices & Networks.
  2. Open Device view → PROFINET interface → Ethernet addresses.
  3. Set IP address = 192.168.0.10, Subnet mask = 255.255.255.0.
  4. Repeat for the second CPU with IP address = 192.168.0.11 on the same subnet.
  5. Connect X1 P1 of CPU 1 to X1 P1 of CPU 2 with a Profinet patch cable, or through a managed switch.

Once the CPUs are online, ping each one from the programming PG to confirm Layer 3 reachability before any PUT/GET configuration is added.

S7 Connection Configuration in TIA Portal

S7 Communication requires an explicit S7 connection object. The object is local to the initiating CPU and references the partner CPU by IP address.

  1. In Devices & Networks, switch to the Connections tab at the top of the editor.
  2. Click the connection type dropdown and select S7 connection.
  3. Drag from the PROFINET port of CPU 1 to the PROFINET port of CPU 2. TIA Portal creates a connection object under CPU 1's Connections node.
  4. Open the connection object and confirm:
    • Local ID = 1 (decimal). This ID is the value the user program must pass to PUT/GET.
    • Partner address = 192.168.0.11.
    • Active connection establishment = enabled on the local (initiating) CPU only.
  5. Compile and download hardware configuration to both CPUs.
Only the initiating CPU holds the S7 connection object. The partner CPU does not require a reciprocal connection; it serves the S7 Communication requests passively. This is a deliberate simplification: a single GET/PUT pair on one CPU is sufficient for bi-directional data exchange because the two instructions cover both directions independently.

Data Block Design

Both CPUs must declare a DB that mirrors the data being exchanged. For PUT/GET, two important rules apply:

  • Blocks must be non-optimized (i.e., "Standard" access) on firmware older than V4.2. Firmware V4.2+ allows optimized blocks when accessed by absolute address.
  • The DB must be large enough to hold the largest single PUT/GET payload (160 bytes by default; up to 960 bytes for large PUT/GET variants on S7-1500; 160 bytes remains the limit for S7-1200).

For a traffic-light hand-off application, design a small shared structure such as:

// DB "Shared_Handoff" on CPU 1 and CPU 2 (mirrored)
TYPE "tHandoff"
  STRUCT
    VehicleID     : INT;       // 0..32767
    Direction     : INT;       // 0=N, 1=E, 2=S, 3=W
    ETA_ms        : DINT;      // millisecond timestamp
    ApproachLane  : BYTE;      // bitmask of lanes approaching
    GoRequest     : BOOL;      // request to enter partner's zone
    HandshakeAck  : BOOL;      // partner acknowledged
    Padding       : ARRAY[0..149] OF BYTE;  // pad to 160 bytes
  END_STRUCT;
END_TYPE

Total payload is 160 bytes, matching the single-call limit. For larger hand-off tables, define a ARRAY[0..N] OF "tHandoff" and partition reads/writes into 160-byte slices using offsets.

PUT and GET Instruction Basics

Both instructions live in the Instructions → Communication → S7 Communication task card. Their interface blocks differ slightly.

Parameter PUT GET Description
REQ BOOL BOOL Edge-triggered start. A rising edge initiates the transfer.
ID WORD WORD Local connection ID from the S7 connection object (e.g., W#16#1).
DONE BOOL BOOL 1 for one cycle on successful completion.
ERROR BOOL BOOL 1 for one cycle if an error occurred.
STATUS WORD WORD Error or progress code; valid only when ERROR = 1 or for one cycle after DONE.
ADDR_1 REMOTE REMOTE Pointer to partner area to write to (PUT) or read from (GET). Format: P#DB10.DBX0.0 BYTE 160.
SD_1 VARIANT — Local source area to send (PUT only).
RD_1 — VARIANT Local destination area to receive (GET only).
LEN_1 WORD — Number of bytes to write; default = 160.

For PUT and GET, REQ must be held TRUE for exactly one cycle after the call returns BUSY = 1 (or ERROR = 1). The simplest pattern is to drive REQ with a clock bit and let BUSY/DONE gate subsequent calls.

Programming the User Program

The following SCL snippet shows a coordinated exchange: CPU 1 reads CPU 2's hand-off DB (GET) and writes its own hand-off DB to CPU 2 (PUT). Both calls are triggered by a 200 ms clock so the application is paced and predictable.

// FB "HandoffExchange" in CPU 1 - SCL
VAR
  Clock_200ms    : BOOL;       // from TON / clock generator
  PutBusy        : BOOL;
  PutDone        : BOOL;
  PutError       : BOOL;
  PutStatus      : WORD;
  GetBusy        : BOOL;
  GetDone        : BOOL;
  GetError       : BOOL;
  GetStatus      : WORD;
  LocalBuf       : "tHandoff"; // local DB area
  RemoteBuf      : "tHandoff"; // partner DB area
END_VAR

// GET: read partner's hand-off DB into local buffer
"GET_DB".REQ  := Clock_200ms AND NOT GetBusy AND NOT GetError;
"GET_DB".ID   := W#16#1;                                  // local S7 connection ID
"GET_DB".ADDR_1 := P#DB20.DBX0.0 BYTE 160;                // partner's shared DB
"GET_DB".RD_1   := "Shared_Handoff".RemoteBuf;            // local destination
"GET_DB".NDR    ;  // rising edge on success
"GET_DB".ERROR  := GetError;
"GET_DB".STATUS := GetStatus;

// PUT: write local buffer to partner's hand-off DB
"PUT_DB".REQ   := Clock_200ms AND NOT PutBusy AND NOT PutError;
"PUT_DB".ID    := W#16#1;
"PUT_DB".ADDR_1 := P#DB20.DBX0.0 BYTE 160;                // partner's shared DB
"PUT_DB".SD_1   := "Shared_Handoff".LocalBuf;             // local source
"PUT_DB".LEN_1  := 160;
"PUT_DB".DONE   ;  // rising edge on success
"PUT_DB".ERROR  := PutError;
"PUT_DB".STATUS := PutStatus;

The same FB is dropped into CPU 2 with the local and remote roles swapped. From CPU 2's perspective, its own Shared_Handoff is the local buffer and CPU 1's is the remote buffer. The ID is the local connection ID on CPU 2's S7 connection object, which can also be W#16#1 independently.

Sequencing for More Than 160 Bytes

When a DB is larger than 160 bytes, the application must issue multiple GET or PUT calls with advancing offsets and wait for each to complete before triggering the next. Siemens documents the standard pattern in FAQ 65975617 ("How do you program the GET and PUT instructions ... in order to transfer more than 160 bytes").

  1. Define a constant SLC_COUNT := CEIL(TotalBytes / 160.0).
  2. Maintain an integer SliceIndex from 0 to SLC_COUNT - 1.
  3. For each slice, compute Offset := SliceIndex * 160 and Len := MIN(160, TotalBytes - Offset).
  4. Build the ADDR_1 pointer dynamically: P#DB20.DBX{Offset} BYTE {Len}.
  5. Trigger PUT/GET only when the previous slice returned DONE (or NDR for GET) and increment SliceIndex.
  6. After the final slice, reset SliceIndex := 0 to keep the transfer cyclic.

The full pattern with state machine and cycle timing is described in the linked Siemens FAQ. Engineers should add a watch-dog timer: if no slice completes within 5 seconds, raise a "PUT/GET comms fault" alarm and stop the application from acting on stale data.

HMI Integration for the Traffic Application

Each HMI in the original project is bound to a single CPU, which is the standard pattern for distributed visualization. The HMIs do not need to know the S7 Communication link exists; they simply read their own CPU's Shared_Handoff DB. The inter-CPU exchange happens invisibly in the background.

  • Bind HMI 1 to CPU 1 only, displaying vehicles whose VehicleID is in CPU 1's domain.
  • Bind HMI 2 to CPU 2 only.
  • When a vehicle reaches the boundary lane, the controlling CPU sets GoRequest = TRUE in the shared DB. The partner CPU reads the request via GET, takes ownership, sets HandshakeAck = TRUE, and updates its own HMI with the new vehicle's position.
Do not bind both HMIs to both CPUs. TIA Portal allows it, but it doubles the HMI-to-CPU Profinet traffic and creates ambiguous ownership of the shared DB.

Verification

  1. Online diagnostics: In TIA Portal, go to Online & Diagnostics → Connection diagnostics on the initiating CPU. The S7 connection must show status Established.
  2. Status bit monitoring: Add a watch table to the initiating CPU and observe PUT_DB.DONE, GET_DB.NDR, and the STATUS words. A healthy exchange shows alternating rising edges on DONE and NDR.
  3. Payload check: Set a known value (e.g., VehicleID := 12345) in the local DB on CPU 1. After one clock cycle, CPU 2's RemoteBuf.VehicleID should read 12345.
  4. Cycle time impact: Check the OB1 scan time before and after enabling PUT/GET. A 160-byte PUT/GET pair over Profinet typically adds 5-15 ms per call depending on CPU utilization.
  5. Error capture: Latch any non-zero STATUS value into a diagnostics DB and surface it on the HMI alarm log.

Troubleshooting Matrix

Symptom Likely Cause Diagnostic Fix
STATUS = 0x80D3 PUT/GET access disabled on partner CPU Check partner's Protection & Security settings Enable Permit access with PUT/GET communication
STATUS = 0x80C3 Local ID mismatch Compare ID input with connection object's Local ID Set both to the same value (W#16#1)
STATUS = 0x80B1 Pointer length exceeds partner DB size Inspect LEN_1 / ADDR_1 size vs. partner DB length Reduce payload or extend partner DB
STATUS = 0x80A1 Optimized block access on partner with absolute pointer Open partner DB → Properties → Attributes Switch to Standard access or move to symbolic access via firmware V4.2+
PUT/GET never completes (BUSY = 1 permanently) REQ held high continuously Watch REQ and BUSY in a watch table Use a one-shot edge (clock bit) or gate with NOT BUSY
Connection drops intermittently IP conflict or duplicate partner IP Issue arp -a from PG Reassign duplicate address
Stale data after partner restart No initialization handshake in user program Read partner startup bits Zero the local copy on partner's first cycle

Common Status Codes

Hex Meaning Action
0x0000 No error None
0x0070 Transfer in progress Wait; BUSY remains set
0x80A1 Pointer type mismatch (optimized vs. absolute) Reconfigure access mode
0x80B1 Length error Verify LEN_1 ≤ partner DB size
0x80C3 Local connection resource unavailable Check connection table and ID value
0x80D3 Connection refused (PUT/GET disabled) Enable access on partner CPU
0x80F1 Partner CPU in STOP or unreachable Check partner power state, network, and run/stop switch
0x80F7 Partner DB not loaded Download DB to partner CPU

Performance and Timing

PUT/GET on S7-1200 is not deterministic in the sense of Profinet IRT; it uses standard S7 Communication on TCP/UDP over Profinet. Typical observed round-trip times for a 160-byte exchange between two S7-1214C CPUs on a direct cable:

Payload PUT duration GET duration Combined cycle
32 bytes ~5 ms ~5 ms ~12 ms
160 bytes ~8 ms ~8 ms ~20 ms
5 slices × 160 bytes (sequenced) ~40 ms total ~40 ms total ~90 ms round trip

For a traffic-light application with 200 ms cycle time, a single 160-byte PUT/GET pair leaves plenty of margin. For larger structures, plan the slice budget so the full exchange completes in under half the application cycle.

Field-Proven Caveats

  • Always call PUT and GET from separate FB instances, even if they target the same connection. Sharing a single instance corrupts the internal state machine.
  • Do not call PUT/GET from OB1 directly. Wrap them in an FB called from a cyclic OB30 or a clocked OB35 so a long-running exchange cannot stall the main scan.
  • When changing the partner's IP, the S7 connection on the initiating CPU must be re-downloaded. The active partner IP is stored in the connection object, not resolved at runtime.
  • PUT/GET over Profinet is not secure; the payload is not encrypted. If the network is shared with untrusted devices, segment the CPUs behind a managed switch or use a Profinet security module.
  • For firmware V4.0 to V4.1, the partner DB must be non-optimized and the pointer must be in the form P#DBxx.DBX0.0 BYTE n. Symbolic access was not supported in this range.

FAQ

What is the maximum payload for one PUT or GET call on an S7-1200?

The S7-1200 PUT/GET instructions transfer up to 160 bytes per call. Larger DBs must be split into 160-byte slices and sequenced in the user program, as described in Siemens FAQ 65975617.

Does the partner S7-1200 need any program code to receive PUT/GET?

No. The partner CPU acts as a passive S7 Communication server; only the initiating CPU needs PUT/GET code. The partner must have Permit access with PUT/GET communication enabled in its protection settings.

Why does PUT/GET return STATUS 0x80D3 even though the partner is online?

STATUS 0x80D3 means the partner CPU rejected the connection. The most common cause on S7-1200 is that PUT/GET access is disabled under Device Configuration → Protection & Security. Enable the option, recompile, and download to the partner.

Can PUT/GET be used over a routed network or only on a local Profinet segment?

S7 Communication supports routing through a Profinet subnet boundary, but the route must be configured in the project and the gateway IP reachable. For point-to-point CPU-to-CPU links in the same subnet, no router configuration is required.

Is PUT/GET faster than using an open communication (OUC) TCP pair?

For small payloads, PUT/GET is typically faster because the S7 Communication layer is built into the CPU firmware and does not require a TCON/TSEND/TRCV setup. For very large transfers with custom protocols, OUC or Profinet IO data exchange may be more efficient.

Where can I find the official Siemens documentation for CPU-to-CPU S7 Communication?

Siemens publishes a comprehensive CPU-to-CPU Communication Compendium covering PUT/GET, BSEND/BRCV, and USEND/URCV for S7-1200 and S7-1500. The S7-1200 system manual contains the instruction reference for PUT and GET with full interface descriptions.

Back to blog