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.
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.
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
- Insert the CP341 in the S7-300 rack configuration at the desired slot.
- Open the CP341 properties dialog.
- Select the Parameter tab.
- Under Loadable Driver, select Modbus Master (or Modbus Slave if implementing slave mode).
- Configure the interface parameters: baud rate, parity, data bits, stop bits.
- 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 |
Function Block Installation
- Open the SIMATIC Manager.
- Navigate to Options > Install Library (or insert the library from the Modbus driver installation media).
- Open the library and copy the required FBs to the project's master data library or directly to the S7 program blocks container.
- 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:
-
W#16#2462interprets 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. -
W#16#82is 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
- Initialize CRC register to 0xFFFF.
- For each byte in the PDU: XOR the byte into the CRC low byte.
- Shift the CRC right 8 times; after each shift, if the LSB shifted out is 1, XOR the CRC with 0xA001.
- After processing all bytes, the CRC register contains the checksum.
- 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
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
- Check the CP341 diagnostic buffer in STEP 7 (PLC > Module Information > Diagnostic Buffer).
- Verify the
STATUSoutput of the Modbus master FB using a VAT (Variable Table). - 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.
- 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.
- 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
- Hardware check: Verify wiring polarity, termination resistors (for RS485), and shield grounding at one end only.
- Communication parameters: Confirm baud rate, parity, and stop bits match the slave exactly.
- Slave address: Verify the slave address in the CP341 request matches the physical slave configuration (DIP switches or software setting on the slave).
- Start address: Confirm the data link layer offset is correct: subtract 30001 from the application-layer address stated in the slave documentation.
- Register count: Verify the count is ≤125 and does not exceed the slave's actual register count.
- Frame integrity: Use a serial analyzer to confirm the CRC is correct and the frame is well-formed (slave address, FC, address, count, CRC).
- 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.