1. Application Overview
The Siemens S7-200 family does not ship with a built-in radio-clock decoder, a weekly timer function block, or a dedicated astronomical-time instruction. Anything beyond a one-shot TON/TOF pair must be built by the programmer. This article covers two related tasks on a CPU 224 (typical order number 6ES7 214-1BD23-0XB0, also valid for 221/222/224XP/226):
- Decoding a 24 V DC level from an external DCF77 receiver into a 59-bit minute frame and using it to overwrite the PLC's real-time clock (RTC) with
SET_RTC. - Using
READ_RTCplus a 7-day schedule table in V-memory to drive an output between arbitrary on/off times (for example, "energize Q0.0 Monday through Friday from 10:00 to 10:15"), with optional date-specific overrides for holidays.
The approach uses only standard S7-200 instructions: BGN_ITIME/CAL_ITIME for interval timing, SHRB for the bit table, READ_RTC/SET_RTC for the clock, and a small scheduler subroutine driven from the main scan or from a timed interrupt attached to SMB34.
2. Prerequisites
| Item | Specification |
|---|---|
| CPU | S7-200 CPU 224 (or 221/222/224XP/226), 24 V DC powered |
| Firmware | CPU 224 REL 02.01 or later recommended for SHRB/BCD performance |
| Programming tool | STEP 7 Micro/WIN V4.0 SP9 (final release for the S7-200 line) |
| PC interface | USB-PPI cable (6ES7 901-3DB30-0XA0) or RS-232 PPI Multi-Master cable |
| Receiver | DCF77 module with 24 V DC logic output, optocoupled, e.g. ELV DCF-77-Empfangsmodul or Reichelt MOD-TC |
| Free inputs | 1 digital input (I0.0-I0.7 high-speed capable) plus 1 output for the scheduled load |
| Memory budget | ~3 KB program, ~1 KB V-memory for frame + 7-day table |
3. DCF77 Frame Architecture and Bit Map
DCF77 is a 77.5 kHz amplitude-modulated long-wave signal broadcast by Deutsche Funkturm on behalf of the Physikalisch-Technische Bundesanstalt (PTB) from Mainflingen, Germany. Each minute is encoded as 59 amplitude-keyed 1-second intervals. The carrier is reduced by ~25% during the first 100 ms (logical 0) or 200 ms (logical 1) of every second; the remaining 800/700 ms is full carrier. The 60th second carries no reduction, which the decoder uses to detect a clean start-of-minute.
Encoding rules:
- Bits 0-14: miscellaneous (minute marker, civil warning bits, transmitter ID).
- Bit 15: call bit (antenna change-over), normally 0.
- Bit 16: A1 = announcement of upcoming DST change.
- Bits 17-24: minutes tens/ones (BCD, bits 21-24 unused/zero), P1 = even parity of bits 17-24.
- Bits 25-35: hours tens/ones (BCD, bits 29-35 unused/zero), P2 = even parity of bits 25-35.
- Bits 36-58: day-of-week (3 bits), day tens/ones (BCD, 6 bits), month tens/ones (BCD, 5 bits), year tens/ones (BCD, 8 bits), P3 = even parity of bits 36-58.
- Bit 59 is the start-of-minute separator (no pulse); the decoder uses the 2 s carrier gap to resynchronize.
4. Receiver Wiring and Signal Conditioning
Pin assignments for a CPU 224 with the standard 35 mm DIN-mounted terminal block:
| CPU 224 terminal | Signal | Connection |
|---|---|---|
| 1M | 0 V reference for inputs 0.0-0.7 | Common to receiver GND and 24 V PSU 0 V |
| I0.0 | DCF77 data | Open-collector output of level shifter (use I0.0 for HSC compatibility if you later switch to interrupt-driven measurement) |
| I0.1 | Status / lost-signal | Optional: RSSI or power-good from receiver |
| L+ / M | 24 V sensor supply | 24 V DC for the receiver board if it requires it |
| 1L | 24 V for inputs 0.0-0.7 | Common +24 V (use the same PSU feeding the PLC inputs) |
For CPU 224, inputs 0.0-0.7 are type-1 24 V inputs. A 13-30 V level reads as "1", a -5 to +5 V level reads as "0". The level shifter must therefore convert the receiver's 5 V (or 3.3 V) logic into a 24 V signal that swings clean above 13 V during the carrier-reduction (or non-reduction) window. A simple 74HC14 hex inverter with a pull-up to 24 V and a 2N2222 open-collector driver is a proven arrangement.
5. Pulse Width Measurement in Micro/WIN
Two implementation paths are practical on the S7-200:
- Cyclic scan with BGN_ITIME / CAL_ITIME: simplest, runs in the main OB1. Effective up to about 5-10 ms scan time before pulse-edge resolution suffers. For DCF77 (1 Hz nominal) this is more than enough.
- Timed interrupt on SMB34 (1-255 ms): recommended if your scan time exceeds 50 ms or if you have other heavy logic. Sample the input at a fixed 10 ms cadence and reconstruct the high/low interval from the sample count.
The subroutine below measures the width of the active-high pulse on I0.0 and classifies it as bit 0 (100 ms) or bit 1 (200 ms). The third case, an interval greater than 1.5 s with no edge, signals the start-of-minute marker.
// Subroutine SBR_0: DCF77 pulse width to bit
// Inputs : I0.0 (DCF77 data, level = carrier present)
// Outputs: V100.0 (bit value 0 or 1), V102 (pulse width ms)
// Globals: VB101 = sample counter, VW103 = last edge timestamp
NETWORK 1 // Detect rising edge of I0.0
LD I0.0
EU
CALL SBR_MarkEdge // store current 10 ms tick count in VW103
NETWORK 2 // Detect falling edge
LD I0.0
ED
CALL SBR_Classify // VW103 -> pulse width VW104
NETWORK 3 // Classify pulse width: 0 if < 150 ms, 1 if 150-300 ms
LDW>= VW104, 150
AW< VW104, 300
S V100.0, 1 // bit = 1
NETWORK 4
LDW< VW104, 150
R V100.0, 1 // bit = 0
NETWORK 5 // Start-of-minute: no edge for > 1500 ms
LDW>= VW106, 1500 // VW106 = ms since last falling edge
S M0.1, 1 // M0.1 = SOM (start of minute flag)
Tune the 150/300 ms thresholds empirically. PTB specifications allow ±10 ms jitter, so 100-150 ms maps to logical 0 and 180-300 ms maps to logical 1. Anything outside 100-300 ms should be discarded as noise rather than committed to the bit table.
6. Building the 59-Bit Frame Table
Allocate a 60-bit shift register in V-memory starting at V200.0. Use SHRB with a positive count of +59 so each new bit shifts toward the high-order end and bit 58 lands in V207.4 (V200 = bits 0-7, V201 = bits 8-15, ..., V207 = bits 56-59).
// SBR_Frame: shift one classified bit into the 59-bit table on every SOM
NETWORK 1 // Load V100.0 into the SHRB DATA input on every falling edge
LD I0.0
ED
SHRB V100.0, V200.0, +59 // shift in 1 bit, oldest bit at V200.0
NETWORK 2 // On start-of-minute, freeze the table for decoding
LD M0.1 // SOM flag set in pulse-width section
EU
MOVB 59, VB210 // bit counter starts at 59
S M0.2, 1 // M0.2 = decode enable
The bit map V200.0-V207.4 now holds one complete minute frame. Bit 0 (M = minute marker) is at V200.0; bit 58 (year ones) is at V207.2; bit 59 (always 0) is the implicit SOM separator. Note that the SHRB index for bit n is V(200 + n/8).bit(n%8).
7. Decoding Time and Date from BCD
The minute, hour, day-of-week, day, month, and year fields are BCD-packed across the relevant spans. The decoder below pulls each field into a byte, validates the digit ranges, and stores them in a temporary RTC image starting at VB220.
// SBR_Decode: run when M0.2 is set, freeze frame in V200.0..V207.4
NETWORK 1 // Minutes tens/ones (bits 17..24, valid bits 17..20 = tens, 21..24 = ones)
LD M0.2
EU
CALL SBR_BCD // inputs: VW200 offset, returns byte in VB220
// minute_tens = BCD(bit 17..19) ; minute_ones = BCD(bit 20..23)
MOVB VB220, VB221 // minute byte
| Field | Bit span | BCD layout (MSB..LSB) | Decode result | Byte address |
|---|---|---|---|---|
| Minute tens | 17-19 | 0 0 0 d2 d1 d0 0 0 | 0-5 | VB221 (high nibble) |
| Minute ones | 20-23 | d3 d2 d1 d0 0 0 0 0 | 0-9 | VB221 (low nibble) |
| Hour tens | 25-26 | 0 0 0 0 0 0 d2 d1 | 0-2 | VB222 (high nibble) |
| Hour ones | 27-28 | d3 d2 d1 d0 0 0 0 0 | 0-9 | VB222 (low nibble) |
| Day-of-week | 29-31 | 0 0 0 0 0 d2 d1 d0 | 1-7 | VB223 (low nibble) |
| Day tens | 32-33 | 0 0 0 0 0 0 d2 d1 | 0-3 | VB224 (high nibble) |
| Day ones | 34-37 | d3 d2 d1 d0 0 0 0 0 | 0-9 | VB224 (low nibble) |
| Month tens | 38-39 | 0 0 0 0 0 0 0 d1 | 0-1 | VB225 (high nibble) |
| Month ones | 40-43 | d3 d2 d1 d0 0 0 0 0 | 0-9 | VB225 (low nibble) |
| Year tens | 44-47 | 0 0 0 0 0 0 d2 d1 | 0-9 | VB226 (high nibble) |
| Year ones | 48-51 | d3 d2 d1 d0 0 0 0 0 | 0-9 | VB226 (low nibble) |
A practical decoder uses a small lookup table in a data block rather than 50+ ladder rungs. The block holds a precomputed 256-byte BCD-to-binary conversion or, more compactly, an 11-entry array mapping each 4-bit nibble to its binary value 0-9. Anything above 9 (illegal BCD) is rejected as a frame error and the new RTC write is suppressed for that minute.
8. Parity and Validation
Three even-parity bits protect the three spans. Implement parity with a simple XOR reduction over the bit range:
// Parity check (even parity: XOR of all data bits plus parity bit = 0)
NETWORK 1 // P1: bits 17..24, even parity
LD M0.2
EU
CALL SBR_Parity // computes XOR of V(200+floor(n/8)).bit(n%8) for n=17..24
// returns 0 in VB230 if parity is even, 1 if odd
AB= VB230, 0
S M0.3, 1 // P1 OK
| Span | Bit range | Parity bit | Even parity test |
|---|---|---|---|
| P1 (minutes) | 17-24 (incl. parity bit 24) | V203.0 | XOR(V200.b2..V203.b0) = 0 |
| P2 (hours) | 25-35 (incl. parity bit 35) | V204.3 | XOR(V203.b1..V204.b3) = 0 |
| P3 (date) | 36-58 (incl. parity bit 58) | V207.2 | XOR(V204.b4..V207.b2) = 0 |
9. Writing the S7-200 Real-Time Clock
On a clean frame (parity OK, BCD OK, day-of-week in 1-7, day in 1-31, month in 1-12), call SET_RTC with the decoded fields. The S7-200 RTC format expected by SET_RTC is a T-format byte: T followed by year, month, day, hour, minute, second, and a reserved zero byte (8 bytes total).
// SBR_SetRTC: write decoded time to PLC
NETWORK 1 // All three parity flags set?
LD M0.3 // P1 OK
A M0.4 // P2 OK
A M0.5 // P3 OK
A M0.6 // BCD OK
CALL SBR_PackT // build T-format buffer at VB250..VB257
SET_RTC VB250 // overwrite S7-200 RTC with decoded time
Important behaviors of SET_RTC on CPU 224:
- Writes are applied within one PLC scan; the new value is readable with
READ_RTCon the next scan. - The buffered clock accuracy is typically ±2 min/month at 25 °C, drifting to ±5 min/month at 0-55 °C. With DCF77 sync, the PLC will only accumulate at most a few minutes of drift between good frames.
- Day-of-week 1 = Sunday in DCF77; S7-200 internal
READ_RTCalso returns 1 = Sunday, so the value passes through unchanged.
10. Weekly Schedule Data Block
Place a 7-day schedule in a data block (DB1). Each day holds up to 8 on/off pairs. A pair is two bytes: on-time (HH:MM packed as 0xHHMM) and off-time (same format). The block also carries an enable mask, so any day can be globally disabled without erasing the entries.
| DB1 offset | Symbol | Type | Description |
|---|---|---|---|
| VB0 | SchedEnable | BYTE | Bit mask: b0=Sun, b1=Mon, ... b6=Sat. 1 = schedule active. |
| VB1..VB8 | SunOn1..SunOff4 | WORD x8 | 4 on/off pairs for Sunday |
| VB17..VB24 | MonOn1..MonOff4 | WORD x8 | 4 on/off pairs for Monday |
| ... | ... | ... | ... |
| VB57..VB64 | SatOn1..SatOff4 | WORD x8 | 4 on/off pairs for Saturday |
For a schedule of "Monday through Friday, 10:00 to 10:15", set:
// DB1 initial values (Micro/WIN data block editor)
SchedEnable = 0x3E // b1..b5 set: Mon..Fri
MonOn1 = 16#0A00 // 10:00
MonOff1 = 16#0A15 // 10:15
TueOn1 = 16#0A00
TueOff1 = 16#0A15
WedOn1 = 16#0A00
WedOff1 = 16#0A15
ThuOn1 = 16#0A00
ThuOff1 = 16#0A15
FriOn1 = 16#0A00
FriOff1 = 16#0A15
11. Date-Specific Schedule Override
To handle "every Monday, except holidays", reserve a second data block (DB2) for exception dates. The PLC reads the current day/month from READ_RTC, scans DB2 for a match, and if found uses the override schedule (or forces the output off for that day).
// SBR_Sched: main weekly scheduler, called once per minute from OB1
NETWORK 1 // Read current RTC into VW300..VW307
READ_RTC VW300 // T-format buffer: year, month, day, hour, min, sec, reserved
| DB2 offset | Symbol | Type | Description |
|---|---|---|---|
| VB0 | NumExceptions | BYTE | 0-50 exceptions supported |
| VB1..VB100 | ExDate[1..50] | WORD x50 | High byte = month, low byte = day |
| VB101..VB200 | ExMode[1..50] | BYTE x50 | 0 = force OFF, 1 = force ON, 2 = use alternate pair |
The weekly scheduler evaluates DB1 first, then checks DB2 for a same-month-day match. An exception with mode 0 or 1 overrides the weekly result; mode 2 reads an alternate on/off pair from DB3.
12. STEP 7 Micro/WIN on Windows 10/11
Micro/WIN V4.0 SP9 is the final release for the S7-200 line and was developed against Windows XP/7. On Windows 10 and Windows 11 several symptoms are common: F1 (context help) opens a blank window or returns "Help not found"; the programming software occasionally loses the PPI port after sleep; and large project uploads may fail on first attempt.
Workarounds that do not require an additional tool:
- Install Micro/WIN to a non-default path (for example
C:\S7200\) so that the help file path is short enough to register cleanly with the Windows help engine. - Launch Micro/WIN as administrator; this restores the F1 lookup into the local
.chmfile. Windows 10/11 block.chmcontent from UNC paths or from paths underProgram Fileswithout elevation. - Set the launch compatibility to Windows 7 via the executable's Properties > Compatibility tab.
- If F1 still fails, use the bundled
readme.chmdirectly: it contains the same instruction reference as the F1 lookup but is opened by Explorer and bypasses the broken help-engine integration.
13. Commissioning Procedure
- Connect the receiver antenna away from switch-mode PSUs, VFDs, and fluorescent lamps. Aim for a clear line-of-sight to Frankfurt (Mainflingen) and at least 1-2 m of separation from any 24 V cable run.
- Power up and verify the receiver LED blinks once per second. A clean blink = carrier present, no blink = carrier reduced (data 0 or 1) and a 2 s gap = start of minute.
- Download the project to the CPU 224. Place a breakpoint or single-step on the falling-edge network in SBR_0 and confirm VW104 cycles through 100 and 200 within ±20 ms of the receiver LED.
- Force M0.0 to enable decoding. Use a status table to monitor VB200..VB207: the bits should populate from the SOM marker (bit 0) upward to bit 58 over 59 seconds.
- Use a watch table to call
SBR_Decodeand inspect VB220..VB226. Cross-check with a phone app that displays DCF77 frame decode live. - Confirm the three parity bits on three consecutive minutes. If parity is intermittently wrong, increase the 10 ms interrupt to 5 ms to improve edge resolution, or add a 200 ms blanking window after each edge to reject switch-bounce artefacts.
- Force a known good frame and confirm
SET_RTCupdates the PLC clock. Power-cycle the PLC and confirm the clock retains the time (CPU 224 has a super-cap-backed RTC that holds for ~100 hours at 25 °C). - Activate the scheduler, set DB1 to a 1-minute test window ("fire the output for 60 seconds starting now"), and verify Q0.0 energizes at the second mark and drops at the off-time mark.
- Run for 24 hours and log parity failures. A clean DCF77 signal at good reception should produce fewer than 2 bad frames per 24 hours.
14. Troubleshooting Matrix
| Symptom | Likely root cause | Diagnostic | Fix |
|---|---|---|---|
| VB104 always zero; no pulses decoded | Wiring polarity; level shifter inverting the wrong way; input 1M not tied to PSU 0 V | Watch I0.0 in status table; LED on input module | Re-wire; add 10 kΩ pull-up to 24 V on I0.0; verify 1M is on 0 V |
| VB104 always one constant (e.g., 1000) | SBR_MarkEdge never called; rising-edge detector not firing | Force a rising edge manually in Micro/WIN | Replace EU with a one-shot built from a flip-flop; check scan time < 50 ms |
| Pulse widths jitter 80-250 ms on every cycle | Receiver picking up noise; antenna misaligned | Place a scope on the open-collector output | Re-orient antenna; add 100 nF across receiver supply; use shielded cable |
| Parity always fails on P1 only | Bit ordering reversed in SHRB; counted from wrong end | Inspect V200.0..V200.7 in status table | Confirm SHRB count polarity and start bit; reverse the table if bit 0 is at the MSB |
| Hour always reads 0-3 even on successful frames | BCD decoder pulling wrong nibble; hour tens is on bits 25-26, not 27-28 | Compare decoded value to a reference decoder | Re-issue bit-map; document the exact 4 bits that carry hour tens |
| SET_RTC applies the wrong day-of-week | Day-of-week bit span (29-31) misinterpreted as a BCD nibble | Inspect VB223 (should be 1-7, not 0-6) | Convert binary (not BCD) for the day-of-week field; remember 1 = Sunday |
| Scheduler output Q0.0 never energizes | SchedEnable mask is 0; day-of-week from READ_RTC does not match DB1 row index | Watch VB300 and DB1 in a status table | Set SchedEnable to 0x7F for first test; verify byte alignment of DB1 entries |
| Scheduler output stays on across midnight | On-time > Off-time causes the inequality to be true for the entire 24 h span | Force an on/off pair where on > off | Swap on/off if the intent is a wrap-around window; or split into two pairs |
| F1 help does not open | Windows 10/11 blocks .chm registration under Program Files | Try F1 after right-click > Run as administrator | Reinstall to C:\S7200\; run as administrator; open readme.chm directly |
| RTC drifts more than 1 s per hour | CPU super-cap exhausted (typical after > 5 years unpowered) | Power down for 5 minutes, power up, check time | Replace the super-cap on the CPU board, or move to DCF77-only operation with no RTC retention |
Does the S7-200 have a built-in weekly timer instruction?
No. The S7-200 has no native weekly scheduler. Implement it as a data block in V-memory holding on/off pairs per day, plus a routine that calls READ_RTC and compares the current day-of-week, hour, and minute against the active entries. The pattern in Section 10 fits in roughly 1 KB of program memory on a CPU 224.
What is the minimum DCF77 receiver I can wire to a CPU 224?
A module with an open-collector or push-pull output that swings to the receiver's logic level (5 V or 3.3 V typical), plus a level shifter (74HC14 + 2N2222) to present a clean 24 V signal to I0.0. Tie 1M to the 24 V PSU 0 V return, and add a 100 nF decoupling cap across the receiver supply to reject conducted noise.
How accurate will the PLC clock be after DCF77 sync?
Inside reception range the S7-200 RTC tracks DCF77 to within one frame (1 minute). A clean signal produces fewer than 2 bad frames per 24 hours, so the PLC is effectively free-running against the broadcast for at most 1-2 minutes between good syncs. The S7-200 internal RTC itself drifts ±2 min/month at 25 °C, so DCF77 overrides that drift several times per hour.
Why does F1 help not work on Windows 10 or 11?
Micro/WIN V4.0 SP9 uses the Windows .chm help engine, which Windows 10 and Windows 11 block from Program Files and from UNC paths without elevation. Install Micro/WIN to a short path such as C:\S7200\ and launch it as administrator, or open readme.chm from the install directory directly via Explorer.
Can the same project be reused on a S7-200 SMART?
No. The S7-200 SMART uses a different instruction set, different memory map, and the Micro/WIN SMART programming tool. The DCF77 decoder, weekly scheduler, and exception table must be rewritten against the SMART's LAD/FBD/ST editor and the SMART's READ_RTC/SET_RTC equivalents. The hardware-receiver wiring and the 24 V level shifter carry over unchanged.