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. |
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.
- Open the project in TIA Portal and select the first CPU in Devices & Networks.
- Open Device view → PROFINET interface → Ethernet addresses.
- Set
IP address = 192.168.0.10,Subnet mask = 255.255.255.0. - Repeat for the second CPU with
IP address = 192.168.0.11on the same subnet. - Connect
X1 P1of CPU 1 toX1 P1of 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.
- In Devices & Networks, switch to the Connections tab at the top of the editor.
- Click the connection type dropdown and select S7 connection.
- 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.
- 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.
-
Local ID =
- Compile and download hardware configuration to both CPUs.
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").
- Define a constant
SLC_COUNT := CEIL(TotalBytes / 160.0). - Maintain an integer
SliceIndexfrom0toSLC_COUNT - 1. - For each slice, compute
Offset := SliceIndex * 160andLen := MIN(160, TotalBytes - Offset). - Build the
ADDR_1pointer dynamically:P#DB20.DBX{Offset} BYTE {Len}. - Trigger PUT/GET only when the previous slice returned
DONE(orNDRfor GET) and incrementSliceIndex. - After the final slice, reset
SliceIndex := 0to 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
VehicleIDis in CPU 1's domain. - Bind HMI 2 to CPU 2 only.
- When a vehicle reaches the boundary lane, the controlling CPU sets
GoRequest = TRUEin the shared DB. The partner CPU reads the request via GET, takes ownership, setsHandshakeAck = TRUE, and updates its own HMI with the new vehicle's position.
Verification
- Online diagnostics: In TIA Portal, go to Online & Diagnostics → Connection diagnostics on the initiating CPU. The S7 connection must show status Established.
-
Status bit monitoring: Add a watch table to the initiating CPU and observe
PUT_DB.DONE,GET_DB.NDR, and theSTATUSwords. A healthy exchange shows alternating rising edges onDONEandNDR. -
Payload check: Set a known value (e.g.,
VehicleID := 12345) in the local DB on CPU 1. After one clock cycle, CPU 2'sRemoteBuf.VehicleIDshould read 12345. - 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.
-
Error capture: Latch any non-zero
STATUSvalue 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.