S7-300 to S7-200 MPI Data Transfer Using X_PUT and X_GET
This technical reference details the engineering workflow for exchanging process data between a Siemens SIMATIC S7-300 (master/client) and a SIMATIC S7-200 (slave/server) over an existing MPI bus. The procedure uses the S7-300 system function blocks SFC67 X_GET, SFC68 X_PUT, and SFC69 X_ABORT — the only blocks in the standard S7-300 instruction library that natively speak the S7-200 server protocol on MPI.
1. Architecture and Protocol Background
The S7-300 and S7-200 are linked by an MPI subnet (default 187.5 kbit/s, up to 12 stations without repeaters, up to 32 with two repeaters on a bus segment). The S7-200 cannot initiate communication; it only responds to read/write requests from the S7-300. Each CPU has a unique MPI address; the S7-200 default is 2, the S7-300 default is 2 — these must be made unique before commissioning.
| Station | Role | MPI Address | Configuration Tool | Communication Block |
|---|---|---|---|---|
| S7-300 CPU 31x/31xC/31xT | MPI client (master) | e.g. 2 | STEP 7 V5.x / Simatic Manager | SFC67 X_GET, SFC68 X_PUT, SFC69 X_ABORT |
| S7-200 CPU 21x/22x | MPI server (slave) | e.g. 3 | STEP 7 Micro/WIN V4.0 SPx | None (firmware-handled) |
The X_GET / X_PUT services are S7-communication variants wrapped by the SFC layer. They operate on a single connection at a time per block instance and require the S7-200 to be parameterized with at least one TSAP (Transport Service Access Point) reserved for S7 communication. By default Micro/WIN allocates TSAP 02.01 on the S7-200; this value is hard-coded into the SFC67/68 instance and cannot be changed from STEP 7 on the S7-300 side.
2. Prerequisites
Before any block is written, verify the following:
- STEP 7 (Simatic Manager) version compatible with the installed S7-300 CPU firmware. STEP 7 V5.5 SP2 or later is recommended; earlier versions (V5.3, V5.4) also support SFC67/68/69 but may require an HSP for newer CPUs.
- STEP 7 Micro/WIN V4.0 SP6 or later (Micro/WIN Smart is for S7-200 SMART and is not covered here). Micro/WIN is required only to configure the S7-200 as an MPI server, not to write user logic.
- An PC adapter (USB/PPI or USB/MPI) or CP 5611 / CP 5613 on the engineering station, with the right to access both MPI nodes.
- Profibus/MPI cable with proper terminating resistors (terminator switches ON at the two end stations only).
- Unique MPI addresses (commonly S7-300 = 2, S7-200 = 4).
- The S7-200 project file (MWP) so the server configuration can be re-applied after any firmware update.
3. Configuring the S7-200 as an MPI Server
Open the S7-200 project in Micro/WIN and navigate to View → Component → Configure the CPU (or use the "System Block" dialog). The key parameters are:
- MPI Address: 4 (or any unused address 1–31, ≠ S7-300 address).
- MPI Baud Rate: 187.5 kbit/s (must match the S7-300's MPI subnet baud rate).
- Highest MPI Address: 31 (default), unless the segment is intentionally small.
Then enable the S7 communication channel. In Micro/WIN V4.0 the relevant toggle is System Block → Communication; the field is "Number of communication connections for S7 protocol" and must be ≥ 1. The CPU reserves internal resources for this. Download the system block to the S7-200; the S7-200 does not need user code modifications for the X_PUT/X_GET to work.
4. S7-300 Hardware and NetPro Configuration
Open HW Config and double-click the MPI interface of the S7-300 CPU. Set:
- Address: 2 (example)
- Subnet: MPI(1), 187.5 kbit/s
- Highest MPI address: 31
The S7-200 will not appear in the STEP 7 hardware catalog as a normal DP/PN slave. It is represented by a "S7-200-Station" placeholder inserted via Insert → Other Station → SIMATIC S7-200 in NetPro (STEP 7 V5.x). Assign it MPI address 4 and download the net configuration. If NetPro cannot see the S7-200 over MPI, run PLC → Accessible Nodes in Simatic Manager to confirm that the S7-200 responds; the placeholder station may still be inserted even when the S7-200 is offline, and the configuration is then downloaded to the S7-300 only.
5. Writing the X_PUT Block (S7-300 → S7-200 Write)
SFC68 X_PUT writes from a source area in the S7-300 to a destination area in the S7-200. The block has a fixed interface:
| Parameter | Type | Description |
|---|---|---|
| REQ | INPUT (BOOL) | Edge-triggered: '1' on rising edge initiates the write |
| CONT | INPUT (BOOL) | 1 = connection remains established after job completes (recommended) |
| DEST_ID | INPUT (BYTE/WORD) | MPI address of S7-200 (e.g. W#16#4 for address 4) |
| VAR_ADDR | INPUT (ANY) | Destination area in S7-200 (e.g. P#V100.0 BYTE 20 → VW100 to VB119) |
| SD | INPUT (ANY) | Source area in S7-300 (e.g. P#DB20.DBX0.0 BYTE 20) |
| RET_VAL | OUTPUT (INT) | Return value / error code (see Table 4) |
| BUSY | OUTPUT (BOOL) | 1 = job still running; do not retrigger |
| RD | OUTPUT (BOOL) | Reserved, must be tied low |
Sample call in an SCL / STL block. The standard pattern is to use OB1 (cyclic main) with a cyclic trigger on the REQ input, or a time-based interrupt (see §7).
// SCL example - call X_PUT from OB1 or OB35
// Transfers 20 bytes from DB20 to S7-200 VB100..VB119
// Rising-edge on bTrig starts the job, bHold = TRUE keeps connection open
IF bInit THEN
iBusy := 0;
bInit := FALSE;
END_IF;
// Call once after PLC startup to establish the connection context
X_PUT(REQ := bTrig, // BOOL trigger (pulse)
CONT := TRUE, // keep connection established
DEST_ID := W#16#4, // MPI address of S7-200 = 4
VAR_ADDR := P#V100.0 BYTE 20, // S7-200 destination
SD := P#DB20.DBX0.0 BYTE 20, // S7-300 source
RET_VAL := iRetVal, // error code
BUSY := bBusy);
6. Writing the X_GET Block (S7-200 → S7-300 Read)
SFC67 X_GET is the read counterpart. The interface is identical to X_PUT except that SD is replaced by RD (receive destination on the S7-300 side). The same MPI address and the same TSAP are used; X_GET and X_PUT can be issued from independent OBs and the firmware handles the connection table internally.
| Parameter | Type | Description |
|---|---|---|
| REQ | INPUT (BOOL) | Edge-triggered read request |
| CONT | INPUT (BOOL) | 1 = keep connection |
| DEST_ID | INPUT (BYTE/WORD) | MPI address of S7-200 |
| VAR_ADDR | INPUT (ANY) | Source area in S7-200 (e.g. P#V200.0 BYTE 10) |
| RD | OUTPUT (ANY) | Destination area in S7-300 (e.g. P#DB21.DBX0.0 BYTE 10) |
| RET_VAL | OUTPUT (INT) | Error code |
| BUSY | OUTPUT (BOOL) | Job in progress |
7. Where to Place the SFC Calls in the S7-300 Program
The SFC67/68/69 calls do not have to live in OB1. Three placement strategies are field-proven:
| Placement | Scan behavior | Best use case | Watch out for |
|---|---|---|---|
| OB1 (cyclic main) | Every scan (call rate depends on trigger) | Process values updated as fast as possible | Overloads the MPI bus; do not retrigger while BUSY = 1 |
| OB35 (cyclic interrupt 100 ms default) | Every 100 ms (configurable 1 ms–1 min) | Process values, periodic telemetry | OB35 time must exceed worst-case X_PUT turnaround or a W#16#80A1 timeout occurs |
| OB10..OB17 (time-of-day interrupt) | Once per minute / hour / day | Slow setpoints, recipes, logs | Must be enabled with SFC28 SET_TINT and started with SFC30 ACT_TINT |
| OB82 / OB100 | On diagnostic / restart event | One-shot configuration on startup | No periodic update |
For a Reverse Osmosis control application (as in the source scenario) where the S7-300 already contains the running control logic, do not insert the X_PUT/X_GET into the main control block. Wrap the calls in a dedicated FB (e.g. FB100 "MPI_S7_200_Transfer") and call it once from OB35 with a 200 ms period. This decouples the data exchange from the control scan, simplifies the OB1 of the running program, and makes the timing deterministic.
Sample F-block stub:
FUNCTION_BLOCK FB100
VAR
bTrig : BOOL;
bBusyPut : BOOL;
bBusyGet : BOOL;
iRetPut : INT;
iRetGet : INT;
END_VAR
BEGIN
// 200 ms cyclic - instance DB carries the persistent state
X_PUT(REQ := bTrig, CONT := TRUE, DEST_ID := W#16#4,
VAR_ADDR := P#V100.0 BYTE 20,
SD := P#DB100.DBX0.0 BYTE 20,
RET_VAL := iRetPut, BUSY := bBusyPut);
X_GET(REQ := bTrig, CONT := TRUE, DEST_ID := W#16#4,
VAR_ADDR := P#V200.0 BYTE 10,
RD := P#DB101.DBX0.0 BYTE 10,
RET_VAL := iRetGet, BUSY := bBusyGet);
bTrig := NOT bTrig; // edge generation for next cycle
END_FUNCTION_BLOCK
8. STOP / RUN Mode Handling on First Commissioning
When SFC67/68/69 are first downloaded into an S7-300 that is in RUN, the blocks are present in the work memory but the connection resources are not initialized. The published Siemens guidance is to set the S7-300 CPU to STOP once, then back to RUN, so that OB100 / restart logic re-initializes the internal S7-communication table. After that first initialization cycle, subsequent edits and downloads of the SFC calls do not require a STOP transition.
Practical procedure in Simatic Manager:
- Online → Accessible Nodes confirms the S7-300 at MPI address 2 is online.
- Right-click the S7-300 station → PLC → Operating Mode (or
CTRL+I). - Click "Stop"; wait for the diagnostic buffer entry "STOP caused by operator".
- Download the blocks (SFBs, DBs, FB100, OB35 if newly created).
- Switch the CPU back to Run via the same dialog or the mode selector on the CPU.
- Monitor the instance DBs in online view — BUSY must oscillate 0 → 1 → 0 and RET_VAL must read
W#16#0000on a successful job.
SFC69 X_ABORT once in OB100 on startup to clear any stale connection state, then proceed with X_PUT/X_GET in OB35. Newer CPU 31x-2 DP / 31x-2 PN/DP units do not require this workaround.9. Return Codes and Error Mapping
RET_VAL is the single most important value to capture. Always store it in a DB and trend it on the HMI, because the S7-300 will silently skip the job on the next scan if RET_VAL is non-zero.
| RET_VAL (hex) | Class | Meaning | Corrective action |
|---|---|---|---|
| 0000 | OK | Job accepted, no error | — |
| 0001..007F | Warning | User-data length truncated; check length | Re-check the ANY pointer length |
| 0x0A01 / 0x0A02 | Parameter error | DEST_ID or VAR_ADDR invalid | Verify TSAP and S7-200 V-area range |
| 0x0E01 / 0x0E02 | Communication error | No resource / partner not reachable | Check MPI cable, addresses, terminator |
| 0x80A1 | Timeout | Partner did not respond within configured time | Increase cycle time of calling OB; check S7-200 RUN |
| 0x80C3 / 0x80C4 | Resource | No free connection resource on S7-300 | Reduce number of open S7 connections, or call X_ABORT |
| 0x80D0 / 0x80D1 | Partner error | Negative ack from S7-200 / wrong address | Verify MPI address matches Micro/WIN project |
The SFC69 X_ABORT RET_VAL set is identical but with 0x8001 indicating "no connection was established" — that is normal at first call and is not an error.
10. Verification Procedure
After commissioning, the data exchange must be confirmed in three independent ways:
- PLC-to-PLC test (online monitor): Open the source DB on the S7-300 and the V-area in the S7-200 with both CPUs online. Force a distinct value in the S7-300 source byte and confirm the S7-200 V-byte updates within the next OB35 period. Do the reverse for X_GET.
- Diagnostic buffer: On the S7-300, view PLC → Diagnostic Buffer. Successful S7-200 connections log "S7-200 server connection established" and "connection in operation" within a few seconds of RUN.
- Bus monitor (optional): With a CP 5611 and a softing PROFIBUS monitor or Siemens BT200, capture the MPI telegrams. X_PUT appears as an S7 Put PDU addressed to the S7-200 MPI node. The S7-200 acknowledges with a single positive ACK PDU. This is the only way to prove the wire-level protocol is healthy when the higher-level SFCs return ambiguous codes.
11. Data Rate and Sizing Notes
The MPI bus at 187.5 kbit/s carries approximately 1500–2000 bytes/s of useful payload per active pair. Each X_PUT/X_GET exchange of 76 bytes takes 30–50 ms end-to-end including the S7-300 OB scan overhead. For a Reverse Osmosis plant the typical update cycle is 1 s, well within the bus budget.
If multiple S7-200 stations must be polled, place each SFC pair in its own OB35 instance or use OB35 with a state machine that services one S7-200 per OB35 tick. Do not run more than 3 active X_PUT calls per second against a single S7-200; the CPU 22x's internal S7 stack is small and will refuse new connections with RET_VAL 0x80C3 if flooded.
12. Troubleshooting Matrix
| Symptom | Likely root cause | First check |
|---|---|---|
| RET_VAL = 0x80D0 immediately | S7-200 has wrong MPI address | Micro/WIN → PLC Information, must match DEST_ID |
| RET_VAL = 0x80A1, no S7-200 in online view | Terminator missing or cable swapped | Check both ends have 220 Ω terminator, ports A and B on PROFIBUS connector wired straight |
| BUSY stays at 1, no return | Trigger toggled faster than job completion | Use an edge detector and gate REQ with NOT BUSY |
| Data correct for 1 second, then wrong | Length mismatch — destination area too small | Length of ANY pointer must match on both sides; max 76 bytes |
| BF (bus fault) LED on S7-300 MPI port | Duplicate MPI address on bus | Survey all nodes' addresses |
| Connection OK in diagnostic buffer but values are 0 | DB has not been initialized; source data is 0 | Verify source DB / V-area with VAT table |
13. FAQ
Do I have to use STEP 7 V5.x to program the S7-300, or can STEP 7 Micro/WIN also work for the S7-300 side?
STEP 7 Micro/WIN is for the S7-200 family only; it cannot open S7-300 projects. The S7-300 side must be programmed with STEP 7 V5.x (Simatic Manager) or, on newer S7-300-compatible hardware, TIA Portal with the S7-300 add-on. For the SFC67/68/69 calls, the program is identical in either tool.
Can I keep the S7-300 in RUN while I first download the S7-200 SFC blocks, or must I really switch it to STOP?
On the very first download of the FB/DB that contains the SFC67/68/69 calls, switch the S7-300 to STOP once and then back to RUN. This triggers OB100/OB101 startup logic that initializes the S7-connection resources. Subsequent edits and downloads do not require a STOP transition.
What is the maximum data length for one X_PUT / X_GET call?
Up to 76 bytes of user data per call for the S7-300/S7-200 combination. For larger transfers, split the data into multiple SFC invocations and advance the VAR_ADDR / SD / RD pointers accordingly.
My S7-200 is a CPU 224XP. Is the same procedure valid?
Yes. CPU 224XP and 226 support the S7-MPI server protocol identically to the older CPU 21x/22x. The TSAP 02.01 is hard-coded in firmware and is the value STEP 7 assumes when DEST_ID is set to the S7-200 MPI address.
How can I update the data only every minute, to reduce MPI bus load?
Use a Time-of-Day interrupt OB10..OB17. Call SFC28 SET_TINT to set the start time and period, then SFC30 ACT_TINT to arm the OB. Place the X_PUT / X_GET calls inside that OB; do not call them from OB1. This keeps the MPI bus free between updates and is the recommended pattern for slow setpoints or recipe transfers.