Overview
DP_SEND (FB13) and DP_RECV (FB14) are the PROFIBUS DP process-data exchange blocks supplied in the SIMATIC NET library for the CP 342-5 (order numbers 6GK7 342-5DA02-0XE0 and 6GK7 342-5DA03-0XE0). When the CP 342-5 is operated as a DP master on an S7-300 station with a CPU 315-2 DP (e.g. 6ES7 315-2EH14-0AB0) or CPU 315-2 PN/DP, the CPU does not access DP slaves directly. Instead the CPU transfers a contiguous data image to the CP and the CP performs the DP master role on the PROFIBUS segment. Each transfer call is parameterised with a 10-byte ANY pointer that identifies the source (DP_SEND) or destination (DP_RECV) data area in the CPU.
Writing this code in STL is straightforward because STL treats the ANY as a 10-byte literal (for example P#DB1.DBX5.0 BYTE 276). In SCL and CFC the same task is more nuanced: the compiler does not always allow the direct symbolic form when the buffer has non-standard layout, and programmers often have to manually populate the 10 bytes of an ANY-tagged UDT. This reference documents both the manual construction path and the recommended alternative: a dedicated byte-array DB used as a buffer between the user DB and the DP_SEND/DP_RECV calls.
The information below is consistent with the SIMATIC NET CP S7-300/S7-400 programming manual and the Siemens FAQ 109744374, which cover DP_SEND/DP_RECV for CP 342-5 in STEP 7 V5.5 and in TIA Portal V16 or later. Refer to the official links at the end of each section for the canonical Siemens wording.
Prerequisites
| Item | Value | Notes |
|---|---|---|
| STEP 7 | V5.5 + SP2 or higher (TIA Portal V16+ for S7-300 migration) | SIMATIC NET block library must be installed |
| CPU | S7-300 CPU 315-2 DP / 317-2 DP or comparable | Integrated PROFIBUS DP interface is unused when CP 342-5 is master |
| CP | CP 342-5 (6GK7 342-5DA0x-0XE0) configured as DP master | GSD file import or DP slave catalog entry in HW Config |
| Function blocks | FB13 DP_SEND, FB14 DP_RECV, FC1 DP_INIT, FC2 DP_CLEAR | Installed from SIMATIC NET library, instance DB auto-generated |
| Buffer DB | DB1 (input area), DB2 (output area), array of BYTE | Length must match configured PROFIBUS I/O size |
DP_SEND / DP_RECV Call Order and Handshake Rules
For the CP 342-5 the DP master executes a strict handshake between the CPU and the CP. According to the SIMATIC NET programming manual, exactly one DP_SEND or DP_RECV call must precede every subsequent call sequence. The rule, documented in the official Siemens manual page for DP_RECV (S7-300, S7-400), is summarised below:
- Call FC1 DP_INIT once at start-up to configure the CP operating mode (master / slave / diagnostic).
- Call FB14 DP_RECV to fetch the most recent DP input image into the destination buffer.
- Call FB13 DP_SEND to push the next DP output image to the CP.
- Repeat RECV / SEND in every OB1 cycle; do not skip a call.
- Call FC2 DP_CLEAR before re-initialising the CP or in the event of an unrecoverable error.
The first call after power-up or DP_INIT must be either DP_RECV or DP_SEND; the CP will return STATUS =16#0000 and zero-length data on the first exchange while it builds the DP connection. Subsequent calls return STATUS =16#0000 on success, otherwise an event-class error word is returned in the STATUS output.
Understanding the 10-Byte ANY Pointer
An S7-300 ANY pointer is always 80 bits (10 bytes). For DP_SEND/DP_RECV the relevant subset is shown in the table below. Bytes 0 to 3 are the header; bytes 4 to 9 identify the data area.
| Byte | Field | Value for DB data | Meaning |
|---|---|---|---|
| 0 | Syntax-ID | 16#10 |
S7-300/400 ANY, no DB prefix |
| 1 | Transport type |
16#01 = BOOL, 16#02 = BYTE, 16#04 = WORD, 16#05 = DWORD, 16#07 = STRING |
Element size / data type |
| 2-3 | Length | Count of transport-type units (e.g. 276 for 276 bytes) | WORD, big-endian |
| 4 | Memory area |
16#84 = DB, 16#83 = Bit memory, 16#82 = Inputs (E), 16#81 = Outputs (A) |
Area selector byte |
| 5-6 | DB number (only for 16#84) |
e.g. W#16#0001 = DB1 |
WORD, big-endian |
| 7-9 | Byte / bit address | Bit 0-2 = bit number (0-7), bit 3-19 = byte address | 24-bit, big-endian, byte-bit packed |
The byte/bit packing rule is the most common source of bugs: DBX<B>.<b> is encoded as (B * 8) + b. For DB1.DBX5.0 the encoded value is (5 * 8) + 0 = 40 = 16#28, which goes into bytes 7-9 as 16#000028. The remainder of the area specifier (byte 4 = 16#84) is sometimes packed into the same DWORD; in the Siemens FAQ snippet cited in the field report, byte 4 occupies the high byte of the Source_Byte_Pointer DWORD while bytes 7-9 occupy bytes 1-3.
Approach 1: Manually Building the ANY in SCL
Declare an ANY-typed UDT or a STRUCT matching the 10-byte layout, fill it in SCL, and pass it to FB13 / FB14. This is the approach the source thread is exploring.
UDT declaration
TYPE UDT_ANY_PTR
STRUCT
S7Code : BYTE; // Syntax-ID, normally 16#10
DataType : BYTE; // 16#02 = BYTE
Lenght : INT; // count of elements
MemoryArea : BYTE; // 16#84 = DB
DB_Number : INT; // DB number
ByteAddressMSB : BYTE; // high byte of address
ByteAddressLSB : WORD; // low word of address (bit 0-2 = bit)
END_STRUCT
END_TYPE
SCL population for a 276-byte receive buffer in DB1 starting at DBX5.0
VAR_TEMP
pAny1 : UDT_ANY_PTR;
END_VAR
pAny1.S7Code := 16#10;
pAny1.DataType := 16#02; // BYTE
pAny1.Lenght := 276; // bytes
pAny1.MemoryArea := 16#84; // Shared DB
pAny1.DB_Number := 1; // DB1 = input area
pAny1.ByteAddressMSB := 0;
pAny1.ByteAddressLSB := 40; // DBX5.0 = 5*8+0 = 40
// Pass to FB14 DP_RECV:
DP_RECV_DB14.RECV := pAny1;
DP_RECV_DB14.NDR := ...;
DP_RECV_DB14.ERROR := ...;
DP_RECV_DB14.STATUS:= ...;
CALL FB14, DP_RECV_DB14;
Encodings for common start addresses
| Source address | ByteAddressLSB (WORD) | Comments |
|---|---|---|
| DB1.DBX0.0 | 16#0000 | Buffer starts at DBW0 |
| DB1.DBX5.0 | 16#0028 | 5 * 8 + 0 = 40 |
| DB1.DBX10.0 | 16#0050 | 10 * 8 + 0 = 80 |
| DB1.DBX12.7 | 16#0067 | 12 * 8 + 7 = 103 |
| DB1.DBX100.3 | 16#0323 | 100 * 8 + 3 = 803 |
16#84 (DB) only. The transport-type byte is hard-coded to 16#02 (BYTE) for the DP_SEND / DP_RECV blocks because the CP does not interpret individual BOOL tags; it only transports a contiguous byte image. Programming a BOOL type (16#01) at byte 1 will be rejected with STATUS =16#8085 at runtime.Approach 2: Byte-Array DB as a Buffer (Recommended)
Rather than constructing the ANY from a user DB containing BOOL / WORD tags, define one or two byte-array DBs sized to the PROFIBUS I/O image and copy process data between the user DB and the byte buffer. This is the pattern recommended in the SIMATIC NET manual and is far easier to maintain in CFC because the buffer DB can be addressed symbolically and the DP_SEND / DP_RECV call accepts the symbolic array directly.
Buffer DB declaration
DATA_BLOCK DB_InputImage
STRUCT
bytes : ARRAY[0..275] OF BYTE; // 276 bytes input image
END_STRUCT
BEGIN
END_DATA_BLOCK
DATA_BLOCK DB_OutputImage
STRUCT
bytes : ARRAY[0..275] OF BYTE; // 276 bytes output image
END_STRUCT
BEGIN
END_DATA_BLOCK
SCL call with symbolic ANY (SCL auto-generates the 10 bytes)
CALL FB14, DB14_Inst
RECV := "DB_InputImage".bytes,
NDR := bNDR,
ERROR := bErr,
STATUS := wStatus;
CALL FB13, DB13_Inst
SEND := "DB_OutputImage".bytes,
DONE := bDone,
ERROR := bErr,
STATUS := wStatus;
Bit-level copy from byte buffer to user DB (BOOL tags)
// Example: copy first 8 DI bits from buffer byte 0 into user DB10
"User_DB".DI_00 := "DB_InputImage".bytes[0].%X0;
"User_DB".DI_01 := "DB_InputImage".bytes[0].%X1;
"User_DB".DI_02 := "DB_InputImage".bytes[0].%X2;
"User_DB".DI_03 := "DB_InputImage".bytes[0].%X3;
"User_DB".DI_04 := "DB_InputImage".bytes[0].%X4;
"User_DB".DI_05 := "DB_InputImage".bytes[0].%X5;
"User_DB".DI_06 := "DB_InputImage".bytes[0].%X6;
"User_DB".DI_07 := "DB_InputImage".bytes[0].%X7;
// Bit-level copy from user DB to buffer (DO bits)
"DB_OutputImage".bytes[0].%X0 := "User_DB".DO_00;
"DB_OutputImage".bytes[0].%X1 := "User_DB".DO_01;
...
Why this pattern wins
- No manual byte/bit packing, no endian mistakes, no off-by-one in the encoded address.
- SCL and CFC both accept the
ARRAY OF BYTEdirectly as the ANY parameter; the compiler emits the correct 10-byte ANY. - The buffer length is visible in HW Config (DP slave I/O size) and matches the ANY length automatically.
- BOOL / WORD tags in the user DB can be reordered without changing the DP_SEND / DP_RECV code.
- Trivial to use with CFC channel drivers: each CFC block simply reads/writes a
BYTE.xslice of the buffer.
FC1 DP_INIT Parameterisation
FC1 is the only block required at start-up. Its inputs are a 16-byte ANY pointer describing the CP start-up data. Leave the start-up ANY as a zero literal if the CP only operates as a DP master with default diagnostics.
| FC1 input | Type | Master mode value | Description |
|---|---|---|---|
| REQ | BOOL | TRUE (edge) | Start the initialisation |
| DP_INIT_DATA | ANY |
P#P 16#0 Byte 16 or empty pointer |
Pointer to 16 bytes of CP configuration |
| BUSY | BOOL | — | TRUE while CP is processing |
| DONE | BOOL | — | TRUE once CP is initialised |
| ERROR | BOOL | — | TRUE on error |
| STATUS | WORD | — | Return code, see table below |
The 16-byte DP_INIT payload for a CP 342-5 acting purely as a DP master is typically all zeros. If the CP is to act as a DP slave or to publish diagnostics, byte 0 must contain the role bits: 16#01 = master, 16#02 = slave, 16#03 = master + slave. See the CP 342-5 manual for the exact byte map.
Return Codes and STATUS Word
| STATUS (hex) | Meaning | Remedy |
|---|---|---|
| 0000 | No error, data transferred. | Continue normal polling. |
| 7000 | First call after DP_INIT; no data yet. | Issue a matching SEND or RECV and continue. |
| 7001 | First call after restart; buffer empty. | Call again on next cycle. |
| 7002 | Second call waiting for handshake completion. | Ensure RECV precedes SEND every cycle. |
| 8085 | ANY pointer transport type is not BYTE (16#02). | Set S7Code/DataType fields per Section "Understanding the 10-Byte ANY Pointer". |
| 8090 | Configured module does not exist or wrong slot. | Recompile HW Config; re-load CP configuration. |
| 8091 | Logical address mismatch with HW Config. | Verify the I-address / Q-address of the DP slave. |
| 80A1 | DP slave diagnostic pending. | Read slave diagnostics, check wiring. |
| 80A3 | DP master not yet started or slave failed. | Check FC1 return code and bus termination. |
| 80B0 | DP slave does not respond. | Check slave address, baud rate, cable. |
| 80C0 | Configuration of DP slave differs from HW Config. | Compare GSD parameters against slave DIP / rotary. |
| 80C1 | Parameter assignment error. | Check user-parameter data length. |
| 80C3 | No DP master configuration present. | Re-compile and re-download HW Config for CP 342-5. |
| 80D0 | DP protocol error at layer 2. | Check baud rate and bus termination. |
Troubleshooting Matrix
| Symptom | Likely root cause | Diagnostic step | Fix |
|---|---|---|---|
| STATUS = 8085 on first cycle | Manual ANY uses 16#01 (BOOL) or wrong syntax-ID. |
Inspect bytes 0 and 1 in the populated UDT. | Force 16#10 at byte 0 and 16#02 at byte 1. |
| STATUS = 8090 after changing DP slave | CP configuration not reloaded after HW Config change. | Compare CP diagnostic buffer in STEP 7. | Re-compile HW Config and download to CP only. |
| Process data is one byte off | ByteAddressLSB does not account for bit position. | Recompute (Byte * 8) + Bit. |
Use the buffer-DB approach to avoid manual encoding. |
| CFC compile error "incompatible type" | Symbol passed as BYTE array but FB expects ANY. | Pass the entire array, not a slice. | Wire bytes (entire ARRAY) into RECV / SEND. |
| Outputs frozen, no error code | DP_RECV called before DP_SEND in cycle. | Check call sequence in OB1 / cyclic task. | Always RECV first, then SEND. |
| STATUS = 80B0 after hot-swapping slave | Slave address / baud-rate mismatch. | Compare GSD with physical DIP / rotary. | Match slave address and 1.5 Mbps max line. |
| DP_SEND returns 7002 forever | RECV was skipped or did not finish. | Read NDR / DONE flags. | Ensure RECV runs to completion each cycle. |
| Data is mirrored (input = output) | RECV buffer and SEND buffer share the same DB. | Inspect DB_Number in the populated ANY. | Use two separate DBs, one for input and one for output. |
Commissioning Procedure
- In HW Config, insert the CP 342-5 in the S7-300 rack and assign PROFIBUS master mode. Add the DP slave(s) with the appropriate I/O slot count.
- Create a buffer DB (DB_InputImage) with
ARRAY[0..N-1] OF BYTEwhere N equals the sum of slave input lengths. - Create a second buffer DB (DB_OutputImage) with the same structure for outputs.
- Add the SIMATIC NET blocks from the library to your program: FC1 DP_INIT, FC2 DP_CLEAR, FB13 DP_SEND, FB14 DP_RECV. Generate instance DBs.
- Call FC1 once in OB100 (warm restart) with
DP_INIT_DATAset to a 16-byte zero area or an ANY withP#P 16#0 Byte 16. - Insert FB14 (RECV) and FB13 (SEND) calls into OB1, RECV first.
- Wire the
bytesarray of DB_InputImage to the RECV ANY input and DB_OutputImage to the SEND ANY input. - Download HW Config and the S7 program. Watch STATUS of FC1, then STATUS of FB14/FB13 in VAT online.
- Use the CFC channel drivers or direct SCL assignment to map individual
bytes[x].%Xninto the user BOOL DB. - Verify in online > Monitor/Modify that the bytes update at the configured PROFIBUS update rate.
Edge Cases and Field-Proven Caveats
- Length must be even. Many PROFIBUS slave profiles require an even number of input / output bytes. The CP 342-5 pads with one fill byte automatically if the configured slot total is odd. Match the ARRAY length to the configured total plus 1 in that case.
- Consistent lengths. If the RECV and SEND ANY lengths differ from the configured DP image, STATUS returns 8085 or 8091. Always regenerate the buffer DB after changing HW Config.
-
CFC and symbolic ANY. In CFC the wire connecting
bytesto the RECV ANY must come from the array symbol; do not pass a singlebytes[i]element as the ANY because SCL generates a 1-byte ANY that will be rejected. - Use of global DBs vs instance DBs. The user BOOL DB and the buffer DB must be global DBs (not instance DBs) because the DP_SEND/DP_RECV ANY requires an absolute address.
-
Bit memory and process image. Never wire the standard process-image inputs (E area) directly to DP_SEND/DP_RECV. The CP 342-5 expects a DB-backed ANY, not a PI/PQ area pointer. The field report's manual packing into
16#82or16#81will be rejected with STATUS 8085. - Multiple cycles per OB1. If OB1 executes faster than the DP cycle, the CP repeats the last image; this is normal. Do not reduce the OB1 cycle time below 5 ms when polling a heavy DP segment.
- S7-400 migration. On S7-400 the same FBs are renamed (DPSEND / DPRECV for IF 964-DP) and use a different library. Do not copy the S7-300 FB13/FB14 instances to an S7-400 project.
Migration to TIA Portal
If the project is moved from STEP 7 V5.5 to TIA Portal V16 or later, the CP 342-5 is added as a "CP 342-5" PROFIBUS device rather than an S7-300 rack module. The official Siemens Support entry 109744374 describes the configuration steps. The ANY handling is identical once the buffer DBs have been migrated, but the call interface of FB13/FB14 is regenerated from the SIMATIC NET library inside TIA Portal. Manual ANY construction is therefore rarely needed in TIA Portal because the editor can complete the ANY from the symbolic buffer.
What is the difference between a standard S7 ANY pointer and the one used by DP_SEND/DP_RECV on a CP 342-5?
On a CP 342-5 the DP_SEND / DP_RECV FBs accept a standard S7-300/400 ANY (syntax-ID 16#10, transport-type BYTE 16#02, area byte 16#84 for DB) but the transport type is hard-coded to BYTE because the CP only transports a contiguous byte image. Using 16#01 (BOOL) at byte 1 produces STATUS = 16#8085.
How do I encode DB1.DBX5.0 into the ANY pointer in SCL?
Pack the byte/bit address into bytes 7-9 of the ANY as a 24-bit value where bit 0-2 is the bit number and bits 3-19 are the byte address. DB1.DBX5.0 encodes to (5 * 8) + 0 = 40 = 16#28, so ByteAddressMSB = 0 and ByteAddressLSB = 16#0028 in the UDT layout.
Why does my manual ANY in SCL differ from the Siemens FAQ snippet?
The two layouts are equivalent, just split differently. The FAQ uses a 5-field STRUCT (id, datatype, length, db_number, byte_pointer) where the byte_pointer DWORD packs area (16#84) in the high byte and the encoded byte/bit address in bytes 1-3. The SCL code in the source thread uses a 7-field STRUCT that splits out the area byte and the address MSB/LSB separately. Both layouts produce the same 10-byte image if the values are correct.
Is it possible to use BOOL or WORD variables in a DB directly with DP_SEND/DP_RECV?
No. DP_SEND and DP_RECV on CP 342-5 require a BYTE-contiguous source/destination area. Use a separate user DB with BOOL/WORD tags and copy the bits to/from a byte-array buffer DB before/after the SEND/RECV calls, or build the ANY manually with transport-type 16#02 and point it at a byte-area slice of the user DB.
Why does DP_SEND return STATUS 7002 every cycle?
STATUS 16#7002 means the CP is waiting for the matching DP_RECV to complete first. The handshake rule for CP 342-5 requires one DP_RECV call to precede every DP_SEND call within a cycle; place FB14 RECV above FB13 SEND in OB1 (or in the same cyclic task executed before SEND) and ensure neither call is conditionally skipped.
What buffer DB size should I declare for a 32-byte input / 16-byte output DP slave?
Declare DB_InputImage as ARRAY[0..31] OF BYTE and DB_OutputImage as ARRAY[0..15] OF BYTE. The ANY length field (bytes 2-3 of the pointer) will then automatically be 32 and 16 when the symbolic array is wired into FB14/FB13.