Overview
The Siemens P_RCV function block (FB2) on the CP 340 point-to-point communication processor normally receives data into a single, fixed data block whose number is hard-coded in the DB_NO input. Many field applications, however, require that the receive target be selected at runtime — for example, when an HMI operator presses one of three buttons and the PLC must redirect the next incoming serial telegram to DB10, DB11, or DB12 depending on the button pressed. This article documents a complete, field-proven implementation pattern that ties HMI button selection to the DB_NO parameter of P_RCV while preserving the integrity of the active receive transaction.
The pattern is officially supported in the STEP 7 V5.x documentation and the TIA Portal PTP Data Link manual for the CP 340 — both of which state that the DB_NO input accepts an INT value identifying the destination data block. The block transfer itself is performed by FB2 (P_RCV) and the parallel send block is FB3 (P_SND). The P_RCV: receiving data (S7-300, S7-400) — STEP 7 manual is the authoritative reference for parameter semantics.
Prerequisites
- SIMATIC S7-300 or S7-400 CPU (e.g., CPU 315-2 DP, CPU 317-2 PN/DP, CPU 414-2 DP) with a CP 340 module configured for ASCII, 3964(R), or RK 512 protocol.
- STEP 7 V5.5+ or TIA Portal V13+ with the CP 340 Point-to-Point Data Link option installed (article assumes STEP 7 V5.x terminology, but TIA Portal follows the same FB2 interface).
- Hardware configuration: CP 340 inserted in the SIMATIC S7 project, with its input/output addresses known (e.g., 288..295 in the example below).
- Three destination data blocks (DB10, DB11, DB12) created in the S7 program, each with a structure of
ARRAY [0..n] OF BYTElarge enough to hold the longest expected telegram (typical: 200 bytes; 1024 bytes for RK 512 frames). - An HMI tag set (ProTool/Pro, WinCC flexible, or TIA WinCC) with three Boolean buttons bound to PLC merkers M0.0, M0.1, M0.2.
- A free DB_Val INT tag in a global DB (e.g., DB100.DBW0) to hold the currently selected destination DB number.
P_RCV interface described here is the legacy ASCII/3964(R) variant delivered with the CP 340. CP 341 (and the modular CP 440/CP 441) ship a different FB set (FB7/FB8 for ASCII, FB12/FB13 for 3964(R), FB20/FB21 for RK 512) but the dynamic DB selection concept is identical. Verify the FB number of your receive block in the CP's parameter assignment dialog under Properties > Point-to-Point > Function Blocks.
P_RCV (FB2) Parameter Reference
Before writing the dynamic selection logic, confirm the exact input/output map of FB2 in your STEP 7 installation. The parameter set is documented in the CP 340 manual and the linked Siemens support page.
| Parameter | Direction | Type | Description |
|---|---|---|---|
EN_R |
IN | BOOL | Enable receive. A positive edge starts (or continues) a receive operation; a FALSE aborts the current transaction. |
R |
IN | BOOL | Abort current receive (asynchronous reset). |
LADDR |
IN | INT | Logical base address of the CP 340 (from HW config, e.g., 288). |
DB_NO |
IN | INT | Number of the destination data block — the parameter made dynamic by this technique. |
DBB_NO |
IN | INT | Byte offset within the destination DB where the first received byte is written. Typically 0. |
LEN |
OUT | INT | Actual number of bytes received (valid only when NDR=TRUE). |
NDR |
OUT | BOOL | New data received without error (single-cycle pulse on completion). |
ERROR |
OUT | BOOL | Receive error flag — latched until next EN_R edge. |
STATUS |
OUT | WORD | Detailed error / status code (see the status word table further down). |
CP_START_OK |
IN/OUT | BOOL | CP startup handshake flag — must be TRUE before EN_R is set. |
Full parameter semantics are in P_RCV: receiving data (S7-300, S7-400) and the abort/error procedure is in Siemens KB article 58881016 — How do you abort data transfer on the receive block FB2 P_RCV of CP340?
Destination Data Block Structure
Each destination DB must be declared as an array of bytes long enough to absorb the maximum telegram length configured for the protocol. The example below uses 200-byte arrays for an ASCII protocol with a 192-character user data field plus 8 bytes of trailer/header overhead.
DATA_BLOCK DB10
TITLE = 'Receive Buffer Button 1'
VERSION : 0.1
STRUCT
RX_BUF : ARRAY [0..199] OF BYTE; // 200-byte receive buffer
END_STRUCT
END_DATA_BLOCK
DATA_BLOCK DB11
TITLE = 'Receive Buffer Button 2'
VERSION : 0.1
STRUCT
RX_BUF : ARRAY [0..199] OF BYTE;
END_STRUCT
END_DATA_BLOCK
DATA_BLOCK DB12
TITLE = 'Receive Buffer Button 3'
VERSION : 0.1
STRUCT
RX_BUF : ARRAY [0..199] OF BYTE;
END_STRUCT
END_DATA_BLOCK
DATA_BLOCK DB100
TITLE = 'CP340 HMI Selector'
VERSION : 0.1
STRUCT
DB_VAL : INT; // currently selected destination DB (10, 11, or 12)
OLD_VAL : INT; // last value written, for change detection
RX_BUSY : BOOL; // P_RCV active flag (NDR-pulsed latched)
CP_OK : BOOL; // CP startup handshake
END_STRUCT
END_DATA_BLOCK
ARRAY [0..n] OF BYTE: The CP 340 writes raw, uninterpreted bytes into the destination DB. If you declare the area as STRING, WORD, or REAL, byte-level writes are still accepted but the operator panel will not display the buffer meaningfully, and STEP 7 will flag the DB as inconsistent on upload. Always use BYTE arrays for raw serial reception.
Step-by-Step Implementation in LAD/FBD
Network 1 — HMI Button Selector (LAD)
Network 1 maps each of the three HMI buttons to an integer value stored in DB100.DBW0 (DB_VAL). The network uses three mutually exclusive MOVE blocks so that only the last-pressed button sets the destination DB. A leading-edge contact (P) on each button ensures that the operator must release and re-press to switch destinations — this protects the receive transaction from a mid-flight change.
Network 1: HMI Button -> DB_VAL
M0.0 M0.1 M0.2 "DB100".DB_VAL
| | | (INT)
+-------+-------+
| | | +-----------+
| | | | MOVE |
| | +----+ EN ENO +----+ IN OUT +
| | | | 10 |
| +------------+ IN OUT +-----------+
| | 11 ? | DB100.DB_VAL
+--------------------+ EN ENO +----+
| 12 ? |
+-----------+
Concrete ladder snippet (STEP 7 V5.5 syntax):
| M0.0
-----| |----+--------------------------------( MOVE )----
| 10 DB100.DB_VAL
| ENO (INT)
| M0.1
-----| |----+--------------------------------( MOVE )----
| 11 DB100.DB_VAL
| ENO (INT)
| M0.2
-----| |----+--------------------------------( MOVE )----
| 12 DB100.DB_VAL
| ENO (INT)
Network 2 — Change-Detect Latch
Capture the previously written DB_VAL so the next network can detect a button change and refresh DB_NO only when no receive is in progress.
| DB100.DB_VAL | | M100.1 | DB100.OLD_VAL
| <> | | ( NDR OR | (INT)
| DB100.OLD_VAL | | ERROR ) |
| +---|/|------------+-----( MOVE )----
| DB_VAL OLD_VAL
| ENO
Network 3 — P_RCV Enable Gate
The EN_R signal of FB2 must reflect the operator's intent to receive. In the dynamic-DB pattern, EN_R is set unconditionally while the CP is up, but DB_NO is updated only between transactions. The block itself latches the destination at every EN_R edge.
| DB100.CP_OK | M100.2
| +-----| |----------
| (P_RCV)
| +---- EN_R NDR ----- M100.1
| | R ERROR ----- M100.2
| | LADDR = 288 LEN ----- MW200
| | DB_NO = DB100.DB_VAL STATUS ----- MW210
| | DBB_NO = 0
| +----
Network 4 — Strobe M0.0..M0.2 to Trigger Receive on Demand
When the operator presses a button, that same network must also be interpreted as "the next telegram I send you belongs to this DB". A simple scheme is to keep EN_R continuously TRUE and let the scanner send the telegram whenever it is ready; the chosen DB captures the data. If the application requires a manual trigger, gate EN_R with a per-button M-bit that pulses high on button press:
| M0.0 M0.1 M0.2 M101.0
| | | | |
+---+-----+-----+-------------+
( O ) ( S )
M101.0 // one-shot strobe
| M100.1 M100.2 M101.0
| | | |
+---+-------+----------------+----( R )
M101.0
STL Equivalent (Advanced)
Engineers who prefer Statement List (STL) can express the entire selection logic in a single function block. The following FC demonstrates the recommended idiom.
FUNCTION FC 50 : VOID
TITLE = 'CP340 HMI Dynamic DB Selector'
VERSION : 0.1
VAR_TEMP
INFO : DWORD;
END_VAR
BEGIN
NETWORK
// Network 1 - Button -> DB_VAL with edge detection
A M 0.0; // Button 1
FP M 50.0;
JCN NB1;
L 10;
T DB100.DBW 0; // DB_VAL := 10
NB1: A M 0.1; // Button 2
FP M 50.1;
JCN NB2;
L 11;
T DB100.DBW 0; // DB_VAL := 11
NB2: A M 0.2; // Button 3
FP M 50.2;
JCN NB3;
L 12;
T DB100.DBW 0; // DB_VAL := 12
NB3: NOP 0;
NETWORK
// Network 2 - P_RCV call (multi-instance, FB2)
A DB100.DBX 4.0; // CP_OK
= L 0.0;
CALL FB 2, DB200
EN_R := L0.0,
R := FALSE,
LADDR := 288,
DB_NO := DB100.DBW0,
DBB_NO := 0,
LEN := MW200,
NDR := M100.1,
ERROR := M100.2,
STATUS := MW210,
CP_START_OK := DB100.DBX4.0;
END_FUNCTION
Verification and Commissioning Procedure
- Compile and download the project to the S7-3xx CPU. Open the online view of the CP 340 in HW Config > CP 340 > Diagnostics and confirm CP_START_OK goes TRUE within a few seconds of RUN.
- Open a watch table (VAT) containing
DB100.DBW0,M0.0,M0.1,M0.2,MW200,MW210,M100.1,M100.2, and the first 32 bytes ofDB10,DB11, andDB12. - Force
M0.0= 1. ConfirmDB100.DBW0= 10 within one PLC cycle. - From a PC running a serial terminal (e.g., Docklight, sscom32E, or a custom Python script via the CP 340's RS-232/422/485 port), transmit a known ASCII string, e.g.
TEST_BUTTON1_HELLO\r\n(24 bytes). - Within a few hundred milliseconds, monitor
M100.1(NDR) for a single positive edge, then check thatMW200= 24 (LEN) and that the bytes "TEST_BUTTON1_HELLO..." appear atDB10.DBB0..DBB23. - Force
M0.1= 1, transmit a different string, and verify the data lands inDB11withDB10untouched. - Repeat for
M0.2/DB12. - Test cross-pressing: while a receive is in progress, force a different button. Verify that the current telegram completes into the originally selected DB and that the next telegram is captured by the new DB. If the original destination changes mid-flight, the CP 340 returns status 0x0A0B ("DB_NO changed during active receive") — see STATUS table below.
STATUS Word Interpretation
When ERROR is TRUE, the STATUS WORD contains an SFB-style error code. The most relevant codes for the dynamic-DB pattern are listed below. The full list is in the CP 340 manual / Siemens KB 58881016.
| STATUS (hex) | Meaning | Recommended Action |
|---|---|---|
| 0x0000 | No error. | — |
| 0x0A01 | CP 340 not yet started (CP_START_OK = FALSE). | Wait for startup, do not set EN_R until CP_OK = TRUE. |
| 0x0A02 | DB_NO does not exist or has wrong length. | Verify the DB number written to DB_VAL exists and has ARRAY [0..n] OF BYTE structure. |
| 0x0A05 | LEN out of range or telegram truncated. | Increase destination array size or shorten the sender's frame. |
| 0x0A0B | DB_NO changed during active receive. | Gate DB_VAL writes with NOT(NDR OR ERROR); wait for NDR pulse before re-arming. |
| 0x0E01 | 3964(R) protocol: NAK received from partner. | Check partner device wiring, baud rate, parity. |
| 0x0E02 | 3964(R) protocol: timeout waiting for partner. | Verify the partner is transmitting; check character timeout parameter. |
| 0x0F01 | Frame error (parity, stop bit, baud mismatch). | Match protocol settings in HW Config to the partner device. |
| 0x7000 | Internal CP firmware warning — non-fatal. | Log and continue; if persistent, upgrade CP 340 firmware (≥ V1.0.6 recommended). |
Common Pitfalls and Field-Proven Fixes
| Symptom | Likely Cause | Fix |
|---|---|---|
STATUS = 0x0A02 on first call |
Destination DB number set in DB_VAL has not been created in the S7 project. | Open Blocks in STEP 7 and create DB10, DB11, DB12 with the ARRAY structure above. Recompile. |
NDR fires but LEN is wrong or buffer empty |
DBB_NO is non-zero, so the CP writes to a region that overlays a different tag. | Set DBB_NO = 0 in the P_RCV call. |
| Data always goes to the same DB regardless of button | The button merker is wired to the wrong bit (e.g., M0.0/M0.1 swapped in HMI tags). | Cross-check the HMI tag database; verify the area pointer address in the HMI connection. |
| Sporadic 0x0A0B errors during fast operator use | DB_VAL was modified between the rising edge of EN_R and the arrival of the first byte from the CP. | Insert the change-detect latch from Network 2 and ensure DB_VAL is updated only when NDR=0 AND ERROR=0. |
| Operator sees garbage in WinCC display | Display tag is bound to a non-BYTE region of the destination DB. | Bind WinCC text tag to the BYTE array's symbolic name and convert with the appropriate WinCC string function block (e.g., FC 109 on S7-300). |
| No receive at all after FB call | CP_START_OK not latched; FB instance is single-instance and the multi-instance DB is not loaded. | Use a multi-instance DB (DB200) or a single-instance DB; ensure the instance DB is downloaded with the project. |
Migrating the Pattern to TIA Portal and to CP 341/CP 441
The same dynamic-DB pattern translates directly to TIA Portal projects, but the FB number changes. The CP 341 ASCII block is FB7 and the 3964(R) block is FB12, while the modular CP 441 uses FB20 (ASCII) or FB20-21 (3964). In all cases, the inputs DB_NO and DBB_NO accept the same INT semantics, so a TAG of type INT bound to the HMI selector can be wired directly to the input pin of the receive FB inside a TIA Portal CFC or ladder network.
If the application moves to a CM PtP (S7-1500) or to a CP 1542, the FBs are renamed RCV_PTP / SND_PTP and the parameter is now ID rather than DB_NO; the dynamic selection concept still applies, but the receiving area is specified by a POKE pointer or by a Variant tag rather than by a DB number. TIA Portal V15.1+ supports the Variant approach natively.
Best Practices Checklist
- Use a separate destination DB per logical receive channel. Do not pack all channels into a single DB with varying
DBB_NOoffsets — the operator panel will not be able to bind symbolic tags to mid-array ranges without a UDT wrapper. - Size the destination array to at least protocol-defined max frame + 4 bytes of headroom. For 3964(R), this means 1024 bytes for the standard 1024-byte user data limit.
- Add a watchdog (e.g., a TON with PT = 2 s) on the NDR pulse: if no NDR arrives within the expected telegram cadence, raise a CP 340 fault on the HMI.
- Keep
EN_Rcontinuously TRUE unless you specifically want to block reception. Toggling EN_R restarts the receiver and discards any partial buffer. - Never modify
DB_NOwhileEN_R= TRUE and the CP has bytes in its FIFO. The only safe moment is when the receiver is idle (no telegram in progress). - Document the mapping (Button 1 → DB10, etc.) in the HMI's user manual so that maintenance staff do not have to reverse-engineer the logic.
- Use a UDT for the receive buffer if you need a uniform symbol set across DB10/DB11/DB12: declare a UDT 100 with the same ARRAY [0..199] OF BYTE structure and use UDT 100 as the type of the data block.
FAQ
What function block is P_RCV on a Siemens CP 340, and which CPU families support it?
P_RCV is the legacy receive FB numbered FB2, supplied with the CP 340 Point-to-Point Data Link option package. It is supported on SIMATIC S7-300 and S7-400 CPUs in STEP 7 V5.x. The same functional interface is preserved in TIA Portal for use with the CP 340/CP 341 modules. See the P_RCV manual page for the full parameter list.
Can the DB_NO parameter of P_RCV be changed at runtime?
Yes. DB_NO is a standard INT input; you can drive it from any tag of type INT, including a global DB word written by HMI buttons. The only restriction is that you must not modify DB_NO while a receive is in progress. The block will return STATUS 0x0A0B ("DB_NO changed during active receive") if violated. The safe pattern is to update the selector only when NDR=0 AND ERROR=0.
What data type must the destination data block be?
The destination DB must contain a region declared as ARRAY [0..n] OF BYTE. The CP 340 writes raw bytes; declaring the area as STRING, WORD, INT, or REAL will produce inconsistent data in the destination. Use BYTE arrays for all P_RCV receive buffers, then convert to the application-specific type in user code.
How do I abort a P_RCV receive that is stuck waiting for partner data?
Pulse the R input of FB2 to TRUE for one cycle. The block clears the active receive, the CP 340 flushes its FIFO, and the next rising edge of EN_R starts a new transaction. The full procedure is documented in Siemens KB 58881016. After an abort, always check the STATUS word and log it before re-arming.
Does this dynamic-DB pattern work with the CP 341 and CP 441 modules?
Yes, but the FB numbers differ. The CP 341 uses FB7 (ASCII) or FB12 (3964); the CP 441 uses FB20 (ASCII) and FB21 (RK 512/3964). All of them accept a DB_NO / DBB_NO INT input, so the same HMI-driven INT tag can be wired to any of them. For the S7-1500 ET 200SP CM PtP, the equivalent is the RCV_PTP instruction with a Variant pointer; migrate the selector concept to a Variant tag in that environment.
What STATUS value appears if the destination DB does not exist?
The CP 340 returns STATUS 0x0A02 with ERROR = TRUE. Verify the DB is present in the offline project, has been downloaded to the CPU, and contains a BYTE array of sufficient length. STATUS 0x0A02 is the single most common commissioning error when implementing dynamic-DB selection, because operators sometimes create DBs only for the buttons that were wired during initial testing.