Siemens CP341 Modbus Master FC04: Register Address Mapping

David Krause17 min read
ModbusSiemensTechnical Reference
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

Siemens CP341 Modbus Master FC04: Register Address Mapping

Overview

The Siemens CP341 is a point-to-point (PtP) communication module for the S7-300 family that supports Modbus RTU master and slave protocols through a loadable firmware driver. One of the most common integration issues encountered when commissioning a CP341 Modbus master is the incorrect calculation of the starting register address for Function Code 04 (Read Input Registers). The CP341 reports a slave timeout, a no-response condition, or a Modbus exception 02 (Illegal Data Address) not because the slave device is defective, but because the master frame contains a data-link-layer address that the slave cannot resolve to a physical register.

This reference documents the two-layer Modbus addressing model, the FC04 PDU structure, the CP341 hardware and software prerequisites, the STEP 7 configuration flow, and the byte-level corrections required when a Modbus slave vendor specifies input registers by their application-layer number (30001-based) rather than the data-link-layer offset expected by the Siemens Modbus driver.

Scope: This article covers Modbus RTU (binary) on the CP341 serial module. Modbus ASCII is not supported by the CP341 loadable Modbus driver. Modbus TCP requires the CP343-1 Lean/Advanced Ethernet module or a current S7-1200/1500 communication processor.

Modbus Addressing Model: Data Link vs Application Layer

Modbus defines two distinct address reference layers. The distinction is the single most common source of FC04 communication failures on the CP341, and the root cause of nearly every "slave timeout" report encountered during commissioning.

Application Layer Address

The application layer is the human-readable register number used in device datasheets, vendor documentation, and operator interfaces. For each Modbus function code family, the application layer uses a fixed numerical range:

Register Type Application Range Function Codes
Coils 00001 to 09999 01, 05, 15
Discrete Inputs 10001 to 19999 02
Holding Registers 40001 to 49999 03, 06, 16
Input Registers 30001 to 39999 04

When a slave vendor states that input registers are "at address 30001 to 39999" or specifies a starting register such as "32462", they are referring to the application-layer address.

Data Link Layer Address

The data link layer (PDU addressing) is the zero-based offset actually transmitted in the Modbus frame. The conversion is:

data_link_address = application_address - base_offset

Where base_offset equals:

Register Type Base Offset
Coils 1
Discrete Inputs 10001
Holding Registers 40001
Input Registers 30001

For example, application address 32462 corresponds to data link address 32462 - 30001 = 2461.

Siemens CP341 Convention

The CP341 Modbus RTU master driver uses the data link layer offset as the DATA_ADDR parameter. When the slave documentation states "input registers 2462 to 2544", the integrator must interpret this as the data-link offset (or as application addresses 32462 to 32544, depending on the vendor's documentation convention). The Siemens driver then transmits the data link address in the Modbus PDU.

The Beijer Electronics Modbus Interface reference and the Modbus Application Protocol Specification both confirm that FC04 input registers are addressed as a contiguous block starting from a 0-based data link address. The Siemens Industry Online Support portal hosts the CP341 manual and Modbus driver documentation that describe this addressing convention in detail.

Siemens offset nuance: Some Siemens documentation describes the input register base as 30000 rather than 30001. In practice, when a vendor says "starting at 2462", the value 2462 is entered directly in the CP341 start address parameter (equivalent to data link 2462 = application 32462 in a 30000-base interpretation, or data link 2462 = application 32463 in a 30001-base interpretation). Verify against the slave's actual register map if the address boundary is ambiguous.

Function Code 04 Specification

Function Code 04 (Read Input Registers) reads from 1 to 125 contiguous input registers (16-bit each) in a remote device. The PDU is:

Field Size (bytes) Description
Function Code 1 0x04
Starting Address 2 Data link address, high byte first
Quantity of Registers 2 1 to 125, high byte first

For a request to read 83 input registers starting at data link address 2462 (covering 2462 through 2544), the complete Modbus RTU frame is:

Byte Value (hex) Description
0 0x02 Slave address (example)
1 0x04 Function code 04
2 0x09 Starting address high (2462 = 0x099E)
3 0x9E Starting address low
4 0x00 Quantity high (83 = 0x0053)
5 0x53 Quantity low
6 0xCRC_L CRC-16 low byte
7 0xCRC_H CRC-16 high byte

The response PDU contains the function code echoed, a byte count (2 × number of registers), and the register values in network byte order (high byte first).

Maximum Register Count

The Modbus specification limits FC04 to 125 registers per request (250 bytes of payload). Exceeding this limit causes the slave to return exception code 03 (Illegal Data Value) or to ignore the request entirely. If more than 125 registers are required, split the read into multiple FC04 transactions.

Inter-Frame Silence

Modbus RTU requires a silent interval of at least 3.5 character times between frames to mark frame boundaries. The CP341 Modbus driver handles this timing automatically; manual frame transmission via P_SND_RK (FB8) does not enforce the silence interval and may cause the slave to misinterpret concatenated frames.

CP341 Hardware and Modbus Driver Requirements

CP341 Order Numbers

The CP341 is available in three interface variants:

Order Number Interface Typical Application
6ES7341-1AH02-0AE0 RS232C Point-to-point to a single slave
6ES7341-1BH02-0AE0 TTY (20 mA) Legacy current-loop devices
6ES7341-1CH02-0AE0 RS422/RS485 Multi-drop bus with up to 32 slaves

All three variants support the loadable Modbus RTU master and slave drivers.

Modbus Driver Order Numbers

The Modbus RTU driver is a separate licensed firmware that must be loaded into the CP341 module flash memory:

Driver Order Number
Modbus Master RTU 6ES7870-1AA01-0YA0
Modbus Slave RTU 6ES7870-1AB01-0YA0

The driver is downloaded to the CP341 along with the STEP 7 hardware configuration.

STEP 7 Version

The CP341 with Modbus driver is supported in STEP 7 V5.x (Classic) with SP2 or later. It is not configured in TIA Portal via the same flow; users migrating to TIA Portal must select an ET 200SP CM PtP module (e.g., 6ES7137-6AA00-0BA0) or a current S7-1200/S7-1500 communication module with the Modbus master library.

Library

The Modbus master driver includes a function block library (typically named "MODBUS" or "MODB_341" depending on the version) that provides:

  • Modbus master FB (e.g., MODB_MAST) - High-level Modbus transaction handling
  • P_SND_RK (FB8) - Send raw data to CP341 (standard SIMATIC library)
  • P_RCV_RK (FB7) - Receive raw data from CP341 (standard SIMATIC library)

The P_SND_RK and P_RCV_RK blocks are required for raw frame transmission when the integrator constructs the Modbus PDU manually (e.g., to integrate a non-standard slave or to implement a custom diagnostic function).

STEP 7 Project Configuration

Hardware Configuration

  1. Insert the CP341 in the S7-300 rack configuration at the desired slot.
  2. Open the CP341 properties dialog.
  3. Select the Parameter tab.
  4. Under Loadable Driver, select Modbus Master (or Modbus Slave if implementing slave mode).
  5. Configure the interface parameters: baud rate, parity, data bits, stop bits.
  6. Save and download the hardware configuration to the PLC.

The Modbus driver is transferred to the CP341 flash memory during the download. A restart of the CP341 may be required to activate the new driver.

Communication Parameters

The CP341 must match the slave's communication parameters exactly. Typical Modbus RTU settings:

Parameter Common Value Notes
Baud rate 9600 or 19200 Must match slave exactly
Parity None (8N1) or Even (8E1) None requires 2 stop bits; Even/Odd uses 1 stop bit
Data bits 8 Fixed for Modbus RTU
Stop bits 1 or 2 Depends on parity selection
RS485 termination: For multi-drop RS485 networks, install 120 Ω termination resistors at both ends of the bus. The CP341 RS422/485 variant does not include internal termination; external resistors are required for baud rates above 19200 or for cable lengths exceeding 50 m.

Function Block Installation

  1. Open the SIMATIC Manager.
  2. Navigate to Options > Install Library (or insert the library from the Modbus driver installation media).
  3. Open the library and copy the required FBs to the project's master data library or directly to the S7 program blocks container.
  4. Instantiate the FBs in OB1 with appropriate instance DBs.

Building the Modbus Request Frame

When using the high-level Modbus master FB, the integrator provides the slave address, function code, starting address, and register count. The FB internally constructs the request frame, appends the CRC-16, transmits the frame, waits for the response, validates the CRC, and returns the data.

High-Level Modbus Master FB Call

CALL "MODB_MAST"
  REQ       := M0.0          // Trigger request (rising edge)
  ID        := 2             // Slave address
  FUNC      := 4             // Function code 04 (Read Input Registers)
  DATA_ADDR := 2462          // Data link start address
  DATA_LEN  := 83            // Number of registers to read
  DATA_PTR  := P#DB42.DBX0.0 BYTE 166  // Receive data buffer (2 bytes per register)
  DONE      := M10.0         // Request complete (no error)
  ERROR     := M10.1         // Error occurred
  STATUS    := MW12          // Error/status code

The DATA_PTR parameter must point to a data area large enough to hold the response: 2 bytes per register for FC04, so 83 registers require 166 bytes of buffer space.

Manual Frame Construction (Low-Level)

If constructing the request frame manually using P_SND_RK and P_RCV_RK, the integrator must build the Modbus PDU in a data block and calculate the CRC-16 checksum manually. The CP341 transmits the raw bytes; it does not append Modbus CRC automatically in this mode.

The correct data area layout for a manual FC04 request (without CRC) is:

DB Offset Size (bytes) Content
DBB0 1 Slave address
DBB1 1 Function code
DBW2 2 Starting address (high byte first)
DBW4 2 Quantity of registers (high byte first)
DBW6 2 CRC-16 (calculated by user)

Sample STL Code for Modbus Master Request

The following STL excerpts demonstrate the common mistake and the corrected approach for a manual FC04 request frame construction. The scenario is a Modbus slave at address 2 with input registers at data link offset 2462 through 2544 (83 registers).

Incorrect Approach (Common Mistake)

L B#16#2
T DB42.DBB0    // Slave address = 2
L B#16#4
T DB42.DBB1    // Function code = 4
L W#16#2462
T DB42.DBW2    // Start address = 0x2462 (9282 decimal) - WRONG
L W#16#82
T DB42.DBW4    // Quantity = 0x82 (130 decimal) - WRONG
L W#16#6
T DB40.DBW10   // Length = 6 bytes

This attempt fails for two reasons:

  1. W#16#2462 interprets the value as hexadecimal, producing 9282 decimal on the wire. The slave expects 2462 decimal = 0x099E. The slave will respond with exception 02 (Illegal Data Address) or simply ignore the request.
  2. W#16#82 is 130 decimal, which exceeds the FC04 maximum of 125 registers per request. Even if the address were correct, the slave would respond with exception 03 (Illegal Data Value). The actual register count is 2544 - 2462 + 1 = 83.

Corrected Approach (Decimal Load)

L B#16#2
T DB42.DBB0    // Slave address = 2
L B#16#4
T DB42.DBB1    // Function code = 4
L 2462
T DB42.DBW2    // Start address = 2462 decimal (0x099E) - CORRECT
L 83
T DB42.DBW4    // Quantity = 83 decimal (0x0053) - CORRECT
// CRC calculation follows here (see CRC-16 section)

The decimal value 2462 is loaded as an integer; STEP 7 stores it as 0x099E in the word, which is the correct data link address for FC04.

Alternative Hex Notation

If hexadecimal notation is preferred for code clarity, the hex digits must represent the actual numeric value, not the decimal digits re-typed as hex:

L W#16#099E
T DB42.DBW2    // Start address = 0x099E = 2462 decimal - CORRECT
L W#16#0053
T DB42.DBW4    // Quantity = 0x0053 = 83 decimal - CORRECT

The key distinction: W#16# followed by the decimal value written in hex (e.g., W#16#99E for 2462) versus L 2462 (integer load). Both produce the same bit pattern if the hex representation is correct. The error W#16#2462 is a hex interpretation of the decimal digits "2462", which yields 9282, not 2462.

CRC-16 Calculation for Modbus RTU

Modbus RTU frames require a CRC-16 checksum using the polynomial 0xA001 (reflected representation of 0x8005). The CRC is calculated over the entire PDU (slave address through last data byte) and appended low-byte first.

Algorithm Summary

  1. Initialize CRC register to 0xFFFF.
  2. For each byte in the PDU: XOR the byte into the CRC low byte.
  3. Shift the CRC right 8 times; after each shift, if the LSB shifted out is 1, XOR the CRC with 0xA001.
  4. After processing all bytes, the CRC register contains the checksum.
  5. Append CRC low byte, then CRC high byte to the frame.

STL Implementation Pattern

// CRC-16 calculation in STL (call as FB for reuse)
// Input: DB42 starting at DBB0, length 6
// Output: CRC appended at DB42.DBW6

      L    0xFFFF
      T    LW20              // CRC accumulator

NEXT: L    LW20
      L    DB42.DBB[LW22]   // Load current byte (index in LW22)
      XOW                    // XOR byte into CRC low byte
      T    LW20

      L    8                 // 8 shifts per byte
      T    LW24

SHIFT: L    LW20
      SRW  1                 // Shift right with carry
      T    LW20
      JC   XOR_POLY          // If carry set, XOR with polynomial
      JU   CONT

XOR_POLY:
      L    LW20
      L    W#16#A001
      XOW
      T    LW20

CONT: L    LW24
      LOOP SHIFT             // Decrement and loop if > 0

      L    LW22
      +    1
      T    LW22              // Increment byte index
      L    LW22
      L    6                 // PDU length (slave + FC + addr + count)
      <I                      // If index < 6, continue
      JC   NEXT

      L    LW20
      T    DB42.DBW6          // Append CRC to frame
Production recommendation: For production code, use the Siemens Modbus library's high-level FB (which handles CRC automatically) or a tested CRC function block from the Siemens standard library. Manual CRC implementation is error-prone and should be avoided in shipping code unless required for a non-standard integration.

Common Addressing Mistakes and Corrections

Mistake Symptom Correction
Loading W#16#2462 (interprets decimal digits as hex) Slave receives 0x2462 (9282) as start address; returns exception 02 (Illegal Data Address) or no response Use L 2462 or L W#16#099E
Using application address 32462 directly Slave receives 0x7EC6 (32462) as start address; returns exception 02 Subtract 30001 (or 30000, per Siemens convention) to get data link offset 2461 or 2462
Loading quantity as W#16#82 (130) Exceeds 125-register FC04 limit; slave returns exception 03 or ignores Use 83 (the actual count) or split into multiple requests of ≤125 registers
Mismatched baud rate/parity CP341 reports timeout or frame error in STATUS Verify slave parameters match CP341 configuration exactly
Wrong slave address CP341 reports no response; no exception returned Verify slave address matches the physical slave's configured address
Missing CRC-16 Slave ignores frame or returns framing error Ensure CRC-16 is appended (automatic with high-level Modbus FB, manual with P_SND_RK)
Inter-frame silence violation Slave concatenates frames, returns garbage or exception Use high-level Modbus FB which enforces 3.5 character times; add delay between manual P_SND_RK calls
Big-endian vs little-endian confusion Register values appear swapped or scrambled Modbus RTU uses big-endian (high byte first); ensure DB layout matches network byte order

CP341 Modbus Error Codes and Diagnostics

The CP341 Modbus driver reports status information in the STATUS output of the master FB. Common status codes include:

Status (hex) Meaning Corrective Action
0x0001 Slave did not respond within timeout Check slave address, wiring, and baud rate
0x0002 Frame error (parity, stop bit, or overrun) Verify communication parameters match slave
0x0003 CRC error in received frame Check for electrical noise, shielding, termination
0x0004 Buffer overflow Reduce request frequency or increase CP341 buffer size
0x0005 Invalid function code or parameters Verify FUNC and DATA_LEN parameters
0x0006 Slave returned Modbus exception Check exception code in STATUS low byte
0x0E01 Driver not loaded or CP341 not ready Re-download hardware configuration with Modbus driver selected

Modbus Exception Codes

When the slave returns an exception, the CP341 status reflects the exception code in the low byte:

Exception Meaning Typical Cause
0x01 Illegal Function Slave does not support FC04
0x02 Illegal Data Address Start address or address range not present in slave
0x03 Illegal Data Value Quantity out of range or exceeds FC04 limit of 125
0x04 Slave Device Failure Internal slave hardware or firmware error
0x05 Acknowledge Slave is processing a long-duration command
0x06 Slave Device Busy Slave processing another request; retry after delay
0x08 Memory Parity Error Slave internal memory fault
0x0A Gateway Path Unavailable Router or gateway cannot reach the target device
0x0B Gateway Target No Response End device behind gateway is offline

Diagnostic Procedure

  1. Check the CP341 diagnostic buffer in STEP 7 (PLC > Module Information > Diagnostic Buffer).
  2. Verify the STATUS output of the Modbus master FB using a VAT (Variable Table).
  3. Use a Modbus RTU sniffer (serial port tap with terminal software such as Docklight, Modbus Poll, or a protocol analyzer) to observe the raw frames on the bus.
  4. Test with a known-good Modbus slave simulator (e.g., Modbus Poll in slave mode, or Diagslave) to isolate master-side issues from slave-side issues.
  5. Verify the slave's actual register map by reading a known register (e.g., start at address 0) and incrementing until the slave returns an exception 02, which marks the end of the valid address space.

Verification, Testing, and Migration Paths

Step-by-Step Verification

  1. Hardware check: Verify wiring polarity, termination resistors (for RS485), and shield grounding at one end only.
  2. Communication parameters: Confirm baud rate, parity, and stop bits match the slave exactly.
  3. Slave address: Verify the slave address in the CP341 request matches the physical slave configuration (DIP switches or software setting on the slave).
  4. Start address: Confirm the data link layer offset is correct: subtract 30001 from the application-layer address stated in the slave documentation.
  5. Register count: Verify the count is ≤125 and does not exceed the slave's actual register count.
  6. Frame integrity: Use a serial analyzer to confirm the CRC is correct and the frame is well-formed (slave address, FC, address, count, CRC).
  7. Response handling: Verify the receive DB is large enough (2 bytes per register for FC04) and the data is interpreted correctly (high byte first per Modbus byte order).

Test with Modbus Simulator

Before connecting to the production slave, test the CP341 master with a Modbus RTU slave simulator running on a PC with a serial port or USB-to-RS485 converter. This isolates the master configuration from slave-specific issues and confirms the addressing logic before field deployment.

Online Monitoring

In STEP 7, use a VAT to monitor in real time:

  • The request DB contents (DB42 in the examples above)
  • The Modbus master FB status outputs (DONE, ERROR, STATUS)
  • The receive data area (first few words to confirm valid data)

This provides immediate visibility into the communication state during commissioning and troubleshooting.

Migration to Current Siemens Platforms

The CP341 with STEP 7 V5.x is a legacy platform. For new installations, consider:

Platform Modbus RTU Master Module Configuration Tool
S7-1200 CM 1241 RS232 / RS422/485 TIA Portal, Modbus_Comm_Load + Modbus_Master instructions
S7-1500 CM PtP RS232 / RS422/485 or ET 200SP CM PtP TIA Portal, Modbus_Comm_Load + Modbus_Master instructions
ET 200SP 6ES7137-6AA00-0BA0 (CM PtP) TIA Portal, same Modbus library

The TIA Portal Modbus master library uses the same data link layer addressing convention as the CP341, so the addressing logic developed for the CP341 transfers directly to current platforms.

Frequently Asked Questions

Why does my CP341 report a slave timeout when reading FC04 input registers?

The slave timeout indicates the master transmitted a request that the slave did not recognize or could not answer. The most common causes are incorrect data-link-layer start address (slave returns exception 02 silently or discards the frame), mismatched baud rate or parity, or wrong slave address. Verify the start address by subtracting 30001 from the application-layer address stated in the slave documentation, confirm the slave address matches the physical device configuration, and use a serial analyzer to observe the raw frame and CRC.

What is the difference between Modbus data link and application layer addressing?

The application layer is the human-readable register number (e.g., 30001 to 39999 for input registers). The data link layer is the zero-based offset actually transmitted in the Modbus PDU. The CP341 Modbus driver uses the data link layer address. For FC04, the conversion is: data_link_address = application_address - 30001. For example, application address 32462 corresponds to data link address 2461.

How do I calculate the start address when the vendor says "register 2462 to 2544"?

For FC04, if the vendor means the data link offset, enter 2462 directly in the start address parameter. If the vendor means the application address 32462 to 32544, subtract 30001 to get the data link address 2461 to 2543 and enter 2461. In STEP 7 STL, use L 2462 or L W#16#099E for the data link start address. Avoid L W#16#2462, which interprets the decimal digits as hex and transmits 9282.

What is the maximum number of registers I can read in one FC04 request?

The Modbus specification limits FC04 to 125 contiguous input registers per request (250 bytes of payload). If more than 125 registers are needed, split the request into multiple FC04 calls with adjusted start addresses. The CP341 Modbus master FB will return a status error if DATA_LEN exceeds 125.

Can the CP341 communicate with a Modbus TCP slave over Ethernet?

No. The CP341 is a serial point-to-point module and supports only Modbus RTU over RS232C, TTY, or RS422/RS485. For Modbus TCP communication from an S7-300, use the CP343-1 Lean or CP343-1 Advanced Ethernet module with the Modbus TCP library. For new installations, use an S7-1200/S7-1500 with a CM/CP for Ethernet and the TIA Portal Modbus library.

Do I need to calculate the CRC-16 manually when using the CP341 Modbus driver?

No. When using the high-level Modbus master FB (e.g., MODB_MAST), the driver automatically calculates and appends the CRC-16 to the request and validates the CRC on the response. Manual CRC calculation is only required when constructing raw frames with P_SND_RK (FB8) and P_RCV_RK (FB7), which is not recommended for production code.

Back to blog