Problem Overview
On a Siemens SIMATIC S7-300 CPU 314C-2 PN/DP (order number 6ES7314-6EH14-0AB0) or the older DP variant (6ES7314-6CH04-0AB0) with integrated high-speed counters, one HSC channel counts pulses correctly during RUN but resets to 0 after every PLC restart (power-off/power-on, STOP→RUN, or warm restart), while a second channel configured identically retains its value or behaves as expected. The two channels are configured in HW Config with identical count modes, gate functions, and set/reset behavior, yet the symptom appears only on one.
This is a well-known behavior of the integrated counters on the 314C family and is not a hardware defect. The root cause is the default initialization behavior of the integrated counter block on a CPU restart, combined with the way the "Set function" and the hardware gate interact during OB100 execution. The article walks through the diagnosis and provides three field-proven remedies.
Affected Hardware and Firmware
| Component | Order Number (MLFB) | Notes |
|---|---|---|
| CPU 314C-2 PN/DP | 6ES7314-6EH14-0AB0 | 4 HSC, 4 DI, 16 DO integrated |
| CPU 314C-2 DP | 6ES7314-6CH04-0AB0 | 4 HSC, 4 DI, 16 DO integrated |
| CPU 314C-2 PtP | 6ES7314-6BF04-0AB0 | 4 HSC, 4 DI, 16 DO integrated |
Firmware versions known to be affected or partially affected:
- V3.3 (6ES7314-6EH14-0AB0) — most commonly reported
- V3.2 and earlier on the -0AB0 chassis
- Earlier -0AB0 firmware versions (V2.x) where the set function was not always latched through OB100
Siemens entry point for the manual is the support page at S7-300 CPU 314C-2 PN/DP Manual (Entry ID 109479392). The chapter "Integrated Functions" describes the four HSC channels and the gate/set function behavior.
Root Cause Analysis
The integrated HSC of the 314C is a hardware counter on the CPU front connector, but its load value, current count, and gate state are stored in the I/O process image and re-initialized on every CPU restart. Specifically, the following events occur in the listed order on a power-up or warm restart:
- CPU completes self-test, runs OB100 (restart OB).
- HW Config parameters are pushed to the integrated I/O. The HSC is armed with the configured initial count value — by default
0, regardless of what the count was before the restart. - SFB 47 ("COUNT") is not automatically called by the CPU. Unless the user program calls it in OB1 / OB35 and reads the actual count via
LADDER/FBD/STL, the current count is only the value that the firmware loaded in step 2. - If the hardware gate opens (or is forced open) before the user program gets a chance to call SFB 47 and write back a retained value, the counter starts at 0.
The two channels behaving differently is a strong hint that the set/reset function on gate stop, the gate control source (digital input vs. user program), and the Set Value parameter are not configured identically. Common mistakes that cause one channel to reset and the other to hold:
- One channel has "Load counter value at gate start" ticked, the other does not.
- One channel's hardware gate is wired to a DI that is low at restart (gate closed, count frozen), the other is wired to a DI that is high (gate open, count starts from initial value).
- One channel uses "Set function on gate stop" (which sets a non-zero value), the other uses "Reset on gate stop" (which forces 0).
- One channel was edited and re-compiled in HW Config, the other was left untouched, leaving a stale SDT block that the editor treats as identical.
HSC Configuration in STEP 7 (HW Config)
Open HW Config, double-click the 314C, switch to the Count tab. For each of the four channels you will see the following parameters that are relevant to the reset-on-restart behavior:
| Parameter | Effect at Restart |
|---|---|
| Operating mode = Count continuously | Counter rolls over at upper limit, no automatic reset to 0. |
| Operating mode = Count once | Counter stops at the comparator and does not wrap. |
| Operating mode = Count periodically | Counter reloads the start value on overflow. |
| Set function = enabled, source = Digital Input | On selected edge, counter is forced to the Set Value. Behavior is edge-triggered, not level-triggered, so a static DI at restart does not set the value. |
| Set function = enabled, source = User program (SFB 47) | Only fires when SFB 47 is called with the corresponding control bit. |
| Gate control = Hardware gate (DI) | Counter only runs while the DI is high. At restart the DI may be low (gate closed) → counter holds its initial value of 0. |
| Gate control = Software gate (via SFB 47 SW_GATE) | Gate is closed by default at restart. SFB 47 must be called in OB100 or OB1 to open it. |
| Load counter value at gate start | If ticked, the start value is reloaded on every gate open. This is the most common cause of the "resets to 0" symptom, because the start value defaults to 0. |
| End value / Start value | Defines the counting range. Outside the range the counter is clamped. |
The reference chapter is "Integrated Counting and Frequency Measurement" in the S7-300 CPU 314C-2 PN/DP Manual.
SFB 47 "COUNT" — The Software Interface
Every 314C integrated counter is controlled by SFB 47 in the user program. The function block is part of the standard STEP 7 library and is documented in the STEP 7 online help (path: Standard Library → System Function Blocks → SFB 47 COUNT). The block is multi-instance capable and has the following I/O of interest for restart handling:
| Pin | Type | Meaning |
|---|---|---|
| LADDR | INPUT (WORD) | I/O base address of the channel, e.g. W#16#02EC for channel 0. Get it from HW Config → Count → Addresses. |
| SW_GATE | INPUT (BOOL) | Software gate. Counter only runs while TRUE. |
| SET_DO | INPUT (BOOL) | Forces the digital output of the channel. |
| JOB_REQ | INPUT (BOOL) | Trigger a one-shot job. |
| JOB_ID | INPUT (INT) | 00 = no job, 01 = write count, 02 = read count, 04 = read gate state, etc. |
| JOB_VAL | INPUT (DINT) | Value to write when JOB_ID = 01. |
| STS_GATE | OUTPUT (BOOL) | Internal gate status. |
| STS_DO | OUTPUT (BOOL) | Digital output status. |
| COUNTVAL | OUTPUT (DINT) | Current count value (only valid if JOB_ID = 02 was just executed). |
| JOB_DONE | OUTPUT (BOOL) | Job completed flag. |
| JOB_ERR | OUTPUT (BOOL) | Job failed flag. |
| JOB_STAT | OUTPUT (WORD) | Error code, see SFB 47 documentation. |
JOB_ID = 01 (write count) overwrites the live counter value atomically. JOB_ID = 02 (read count) only updates COUNTVAL at the rising edge of JOB_REQ — the value is not continuously updated on the output. This is the most common reason "the counter seems to ignore SFB 47" — engineers wire COUNTVAL into the program expecting it to track live, and it does not.Solution 1 — Retain the Value via OB100 (Recommended)
The clean fix is to read the count from a retentive DB before the CPU restarts (or in the same cycle, using a rising-edge detection to capture the last value) and to write it back in OB100 before the gate opens. The pattern below assumes one persistent DB storing the last good value per channel.
Persistent DB (e.g., DB200 "HSC_Retain")
DATA_BLOCK DB200
STRUCT
HSC0_LAST : DINT; // last good value for channel 0
HSC1_LAST : DINT; // last good value for channel 1
HSC0_VALID : BOOL; // TRUE after first valid sample
HSC1_VALID : BOOL;
HSC0_INIT : DINT; // initial value to write into channel 0 at restart
HSC1_INIT : DINT;
END_STRUCT
BEGIN
HSC0_LAST := 0;
HSC1_LAST := 0;
HSC0_VALID := FALSE;
HSC1_VALID := FALSE;
HSC0_INIT := 0;
HSC1_INIT := 0;
END_DATA_BLOCK
OB1 — Cyclic read of the live count and capture of the last good value
// Channel 0 — address 0x02EC, channel 1 — address 0x02F0
// (verify the addresses in HW Config → Count → Addresses)
// --- Channel 0 ---
CALL FB_HSC_CH0 , DB100
LADDR := W#16#02EC
SW_GATE := DB200.HSC0_VALID // gate is closed until we have a sample
SET_DO := FALSE
JOB_REQ := FALSE
JOB_ID := 0
JOB_VAL := 0
// Read the current value once at startup, then latch
A DB200.HSC0_VALID
SPB _SKIP0
// first pass: read and store
L 2 // JOB_ID = read count
T DB100.JOB_ID
SET
R DB100.JOB_REQ
S DB100.JOB_REQ // edge trigger
// wait for JOB_DONE in a cyclic check (omitted for brevity)
// on completion, copy COUNTVAL → DB200.HSC0_LAST, set HSC0_VALID
_SKIP0: NOP 0
OB100 — Write the retained value back into the counter before the gate is opened
// Channel 0
CALL FB_HSC_CH0 , DB100
LADDR := W#16#02EC
SW_GATE := FALSE // keep gate closed during write
SET_DO := FALSE
JOB_REQ := TRUE
JOB_ID := 1 // write count
JOB_VAL := DB200.HSC0_LAST
// in the next cycle, drop JOB_REQ and open the gate
// Channel 1 (same pattern, address 0x02F0)
To keep the DB200 contents across a power loss, declare it as non-volatile in the DB properties and enable Retain on the variables HSC0_LAST, HSC1_LAST, HSC0_INIT, HSC1_INIT. Note: a retain-capable DB requires that the CPU is configured with retain memory in the CPU properties. The 314C-2 PN/DP supports up to 8 KB of retentive DB content.
Solution 2 — Disable "Load Counter Value at Gate Start"
If the application can tolerate a single restart losing the value (cold-start use case, counter is only for diagnostics), the simplest fix is to clear the Load counter value at gate start checkbox in HW Config for the affected channel. The counter will then continue from whatever value the firmware left in the register — typically the last value from the previous RUN, unless the hardware gate was closed and re-opened.
- Open HW Config, double-click the 314C, switch to Count.
- Select the affected channel (e.g., Channel 0).
- Click Properties next to the Set function field.
- Uncheck Load counter value at gate start.
- Compile and download HW Config.
- Restart the CPU and observe the count.
Solution 3 — Firmware Update
Siemens released firmware V3.3.17 for the 6ES7314-6EH14-0AB0 and V3.3 for the older -0AB0 chassis that addressed a bug where the Set Function was not rearmed correctly after a warm restart. The fix is listed in the entry at Firmware Update CPU 314C-2 PN/DP (Entry ID 109751688). Procedure:
- Download the firmware file from the Siemens support portal (search for the MLFB).
- Open SIMATIC Manager → PLC → Update Firmware.
- Browse to the .upd file, select the CPU, click Update.
- Wait for completion; the CPU does a self-reset after the flash write.
- Re-test the restart behavior.
Diagnostic Procedure
Follow this sequence to isolate the cause in the field:
- Capture the symptom: With online monitoring, note the count value just before STOP. Note the count value 5 s after RUN is re-established. If the second value is 0, the symptom is reproduced.
- Compare the HW Config of both channels: Open the Count tab. Diff every parameter. The most common asymmetric parameter is Set function source (DI vs. SFB 47).
- Check the physical wiring of the gate input: Use a multimeter to verify the state of DI 124.0 (or whichever input is assigned to the gate) at the moment of restart. If the input is low (gate closed), the counter is frozen at 0; if it is high, the counter is running from 0.
- Check the user program: Cross-reference where SFB 47 is called. If the call is missing or only present for one channel, that channel will never update its retained value.
- Test a cold restart (MRES): Turn the mode switch to MRES and hold for 3 s. This clears all retentive memory and forces a full re-initialization. If the symptom persists on MRES, it is a HW Config issue, not a retentive memory issue.
- Test a warm restart (STOP→RUN): Toggle the mode switch without power cycling. This preserves retentive DB content. If the symptom differs between cold and warm restart, the issue is in the retentive setup.
Verification
After applying Solution 1, verify as follows:
- Force the counter to a non-zero value (e.g., 12345) by jogging the encoder.
- Monitor
DB200.HSC0_LASTin online view — it should track the live count. - Switch the CPU to STOP, then back to RUN.
- Wait 5 s, then read the live count. It should equal
DB200.HSC0_LAST, not 0. - Power cycle the CPU. Repeat steps 1–4. The same verification should pass.
If the live count is still 0 after a power cycle, check the Retain flag on the DB200 variables and the Retain memory setting in the CPU properties (Hardware → CPU → Retentive Memory). The 314C supports 8 KB of retentive DB by default; values outside this range are not retained.
Troubleshooting Matrix
| Symptom | Most Likely Cause | Fix |
|---|---|---|
| Both HSC channels reset to 0 on STOP→RUN | "Load counter value at gate start" is enabled and start value is 0 | Disable the load function or set a non-zero start value |
| Only one channel resets | Asymmetric Set Function or Gate Control parameters | Diff HW Config and equalize |
| Counter resets on STOP→RUN but not on power cycle | SFB 47 not called in OB100, gate opens before user program runs | Add SFB 47 call with JOB_ID = 01 in OB100 |
| Counter resets on power cycle but not on STOP→RUN | Retentive DB not configured, or DB is outside the retentive memory range | Enable Retain on the DB variables and verify CPU retain size |
| Counter holds its value but reads a stale value via SFB 47 | COUNTVAL is only updated on a rising edge of JOB_REQ, not continuously | Trigger JOB_REQ cyclically or use the input process image |
| Channel 0 works, channel 1 always reads 0 | Wrong LADDR in SFB 47 call, or channel 1 disabled in HW Config | Verify LADDR matches HW Config → Count → Addresses |
| Intermittent reset, ~1 in 10 restarts | DI assigned to gate is bouncy at power-up, opens the gate before the firmware loads the configured value | Use software gate (SW_GATE) instead of hardware gate, or add an RC filter to the gate DI |
Edge Cases and Field Notes
- CPU 314C-2 PtP variant: Same firmware family, same HSC behavior. The serial port does not affect counting.
- Frequency measurement mode: If a channel is configured for frequency measurement rather than counting, the "count value" is in Hz and the restart behavior is identical.
- OB80 / OB82 / OB121 handling: If you have error OBs that call SFB 47, the counter may be rearmed during error handling. Use a one-shot (rising edge) to avoid writing the value repeatedly.
- PROFINET IRT: On the 314C-2 PN/DP, the integrated PN interface and the integrated I/O share the backplane bus. Heavy PROFINET traffic during restart can delay OB100 execution, which in turn delays the SFB 47 write. Add a delay (e.g., 50 ms via SFC 47 "WAIT") in OB100 if the gate is software-controlled and the write is being overrun.
- Replacement CPU: After a CPU swap, the new CPU has the same firmware version but different non-volatile memory. The retentive DB content is lost on the first power-up of the new CPU. The first restart will therefore go through the "0 → reload" path; this is expected.
Standards and Documentation References
The integration of the 314C HSC with STEP 7 is documented in:
- S7-300 CPU 314C-2 PN/DP Manual (109479392) — chapter "Integrated Functions" and "Counting and Frequency Measurement".
- Firmware Update CPU 314C-2 PN/DP (109751688) — firmware V3.3.17 changelog.
- STEP 7 online help, SFB 47 COUNT — programming interface and error codes.
Why does one of my two HSC channels reset to 0 on CPU restart and the other does not?
The 314C integrated counters are reinitialized from the HW Config parameters on every restart. If the two channels have different "Set function" sources, different gate control sources (hardware DI vs. software via SFB 47), or one has "Load counter value at gate start" enabled while the other does not, only the channel that reloads its start value of 0 will appear to reset. Open HW Config, switch to the Count tab, and diff every parameter of both channels — most often the Set function source or the gate DI assignment is asymmetric.
How do I retain an HSC value across a power cycle on a 314C-2 PN/DP?
Use a persistent DB with the Retain attribute on the DINT variables, enable Retentive Memory in the CPU properties (HW Config → CPU → Retentive Memory, max 8 KB on the 314C), and call SFB 47 in OB100 with JOB_ID = 01 (write count) to restore the saved value into the counter before the gate opens. Verify with a power-cycle test that monitors both the live count and the DB value.
What is the LADDR for SFB 47 and where do I find it?
The LADDR is the I/O base address of the HSC channel. It is shown in HW Config → Count → Addresses for each channel, typically in hex (for example W#16#02EC for channel 0 of the 314C-2 PN/DP). It is not the same as the digital-input address; it is a separate address window for the counter registers. Use the value from HW Config; do not hard-code it from documentation because it shifts between firmware versions.
Does a firmware update fix the "HSC resets to 0 on restart" issue?
Siemens released V3.3.17 (and the matching V3.3 for the older -0AB0 chassis) which fixed a bug where the Set Function was not rearmed correctly after a warm restart. Updating to that firmware resolves the issue in many cases without code changes. The firmware file is available from the Siemens support portal; update via SIMATIC Manager → PLC → Update Firmware.
Can I use the S7-300 retentive bit memory (M flags) instead of a DB to store the last count?
Yes — MB, MW, and MD areas can be made retentive in the CPU properties and survive STOP→RUN and warm restarts. However, the maximum retentive M area on the 314C is 8 KB and is shared with the user program, so a dedicated retentive DB is the cleaner, scalable pattern, especially if multiple HSC channels or additional diagnostic data need to be preserved. Always use DINT (32-bit) variables for the count value; the counter is 32 bits wide.