Programming S7-200 Interrupts ATCH, DTCH, ENI, and Queue

David Krause12 min read
S7-200SiemensTutorial / How-to
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

Overview

The SIMATIC S7-200 (programmed with STEP 7 Micro/WIN) supports an event-driven interrupt model in which an internal or external event is associated with a dedicated program organization unit (POU). Once the association is in place, the CPU automatically services the event without polling from the main scan cycle. The interrupt subsystem is the right tool for time-critical tasks such as high-speed I/O, timed sampling, serial-port character reception, and PTO pulse counting, where the main OB1 scan time would otherwise introduce unacceptable latency.

Unlike the S7-1200 (which is configured in TIA Portal using OB blocks and hardware interrupt OBs), the S7-200 uses the Micro/WIN instruction set centered on four control instructions: ATCH, DTCH, ENI, and DISI. Because Micro/WIN does not natively integrate with TIA Portal, projects for the S7-200 must remain in the Micro/WIN V4.0 SP9 environment or be migrated via the SIMATIC S7-200 SMART toolchain if a S7-200 SMART replacement is acceptable. Reference the official S7-200 Programmable Controller System Manual for full device specifications and CPU derating tables.

Prerequisites

  • STEP 7 Micro/WIN V4.0 SP9 (or the matching firmware-appropriate service pack) installed on a Windows 10/11 PC with a PPI cable, USB-PPI cable, or Ethernet CP 243-1 for online communication.
  • An S7-200 CPU from the supported list: CPU 221, CPU 222, CPU 224, CPU 224XP, CPU 226, or CPU 226XM. Note that interrupt depth and queue widths differ by CPU; see the Queue Capacity section.
  • Firmware version consistent with the CPU model. The interrupt model is consistent across the 22x series; the 21x series (CPU 212, CPU 214, CPU 215, CPU 216) imposes a different timed-interval minimum (5 ms vs. 1 ms).
  • Project planning: identify the interrupt sources, the required event response time, and which shared variables will be touched by both the main program and the interrupt routines.

S7-200 Interrupt Architecture and Event Categories

The S7-200 CPU partitions interrupts into four categories that determine queue assignment and priority. Each event has a fixed interrupt event number that you pass to ATCH:

Category Event Numbers (typical) Description
I/O Interrupts 0 to 7 (rising edge), 8 to 15 (falling edge) on CPU 224/226; 0 to 15 on CPU 224XP HSC-capable inputs Rising-edge or falling-edge transitions on the dedicated high-speed inputs I0.0-I0.3 (and I0.4-I0.7 on HSC-capable CPUs).
Timed Interrupts 10 (INT0), 11 (INT1) Cyclic timed interrupts driven by SMB34 and SMB35 respectively.
Communication Port Interrupts 8 (Port 0), 9 (Port 1) on CPU 226/226XM with two ports; 8 only on single-port CPUs Receive-character, receive-message-complete, transmit-complete, and message-error events on the RS-485 port(s).
High-Speed Counter Interrupts 12 to 27 depending on HSC mode CV = PV, CV = CV (direction change), and input-edge triggered HSC events.
PTO Interrupts 30 (PTO0 complete), 31 (PTO1 complete) Pulse-train-output completion events used for stepper control.

The exact list and number of events vary by CPU; always cross-check the values in the Micro/WIN Interrupt dialog and the S7-200 System Manual appendix for the installed CPU.

Interrupt Instructions Reference

The Micro/WIN instruction tree exposes the following interrupt-related operations. All four are found under Program Control Instructions in the STL or LAD editor.

Instruction Operands Function
ATCH (Attach Interrupt) IN: INT (event number), INT (routine number) Associates an interrupt event with an interrupt routine. Attaching automatically enables that single event.
DTCH (Detach Interrupt) IN: INT (event number) Removes the association and returns the event to inactive/ignored state. Does not disable other attached events.
ENI (Enable Interrupt) None Globally enables processing of all attached interrupt events.
DISI (Disable Interrupt) None Globally disables all interrupt processing; queued events wait until re-enabled.
CRETI (Conditional Return from Interrupt) None Optional early exit from an interrupt routine. The unconditional RETI is inserted automatically by Micro/WIN.
Critical: ATCH, DTCH, ENI, and DISI are not permitted inside an interrupt routine. They must be called from the main program, from a subroutine, or from the startup OB.

CPU Models and Queue Capacity

The S7-200 maintains three hardware queues: a communications queue, an I/O interrupt queue, and a timed interrupt queue. Each queue has a fixed depth per CPU family. When a queue overflows, the corresponding overflow bit in Special Memory is latched until the queue is drained.

CPU Comm Queue I/O Interrupt Queue Timed Interrupt Queue
CPU 221 / CPU 222 4 16 8
CPU 224 8 16 8
CPU 224XP / CPU 226 / CPU 226XM 8 16 8

Interrupts are serviced on a strict first-come-first-served basis within their priority group. Only one user interrupt routine executes at any instant; higher-priority events cannot preempt a routine that is already running. Events that arrive while a routine is in progress are queued for later processing.

Queue Overflow Diagnostics

Use the following Special Memory bits to detect lost interrupt events. These bits are reset automatically when the queue is emptied and the CPU returns to the main program, so they are only valid inside an interrupt routine.

SM Bit Address Description Cleared When
SM4.0 Communications queue overflow 0 = no overflow, 1 = overflow Queue drained
SM4.1 I/O interrupt queue overflow 0 = no overflow, 1 = overflow Queue drained
SM4.2 Timed interrupt queue overflow 0 = no overflow, 1 = overflow Queue drained

Best practice is to copy SM4.0/SM4.1/SM4.2 into retentive V memory at the very top of the interrupt routine so the loss history survives the queue-drain cycle and can be inspected from the main scan.

Configuring Timed Interrupts (SMB34 and SMB35)

The S7-200 supports two timed interrupts, INT0 and INT1, driven by SMB34 and SMB35 respectively. The interval value is captured by the CPU at the moment the event is attached to a routine; subsequent changes require detaching and re-attaching to take effect.

Symbol Address Range Notes
Time_0_Intrvl SMB34 1 ms to 255 ms (22x); 5 ms to 255 ms (21x) Drives INT0 (event 10). Resolution: 1 ms increments.
Time_1_Intrvl SMB35 1 ms to 255 ms (22x); 5 ms to 255 ms (21x) Drives INT1 (event 11). Resolution: 1 ms increments.

Example STL to set INT0 to a 50 ms cycle:

NETWORK 1
LD    SM0.1        // First-scan bit
MOVB  50, SMB34    // 50 ms interval for INT0
ATCH  10, 0        // Attach event 10 (INT0) to INT_0
ENI               // Global enable

To terminate a timed interrupt, detach the event with DTCH 10. To change the interval while running, write the new value to SMB34, call DTCH 10, then call ATCH 10, 0 in the next scan.

Data Sharing Between Main Program and Interrupts

Because an interrupt can fire at any point in the main scan, naive access to shared variables produces torn reads and torn writes. Micro/WIN provides three documented techniques, ranked from safest to most general:

Technique 1: Single-variable sharing in STL

For a single byte, word, or double-word variable, store all intermediate computation in non-shared memory or the accumulators (AC0-AC3) only. Accumulators are saved and restored automatically by the CPU on interrupt entry and exit, so they are safe across the boundary.

// Interrupt routine — read counter atomically via accumulator
LD    SM0.0
MOVW  VW100, AC0     // shared counter → AC0 (one STL instruction, atomic)

Technique 2: Single-variable sharing in LAD

Ladder instructions are typically compiled to interruptible sequences of STL. The exception is the four move instructions (MOVB, MOVW, MOVD, MOVR), each of which compiles to a single non-interruptible STL instruction. Restrict LAD access to shared variables through these moves only.

// LAD only — single MOVW per shared variable access
NETWORK 1
LD     Always_On
MOVW   VW200, VW210  // copy shared word to local word

Technique 3: Multi-variable sharing via DISI/ENI

When the shared data is a multi-byte record (for example, a recipe of 16 bytes updated by the HMI and consumed by the interrupt), bracket the entire read or write sequence with DISI and ENI so the interrupt cannot fire mid-update.

// Main program — atomic multi-variable write
NETWORK 1
LD     Always_On
DISI               // no interrupts until ENI
MOVB   VB300, VB320
MOVW   VW302, VW322
MOVD   VD304, VD324
ENI                // resume interrupts
Caution: DISI/ENI delays interrupt response by the duration of the protected block. Keep the block short — ideally under one scan of the time-critical I/O — or accept longer worst-case latency in exchange for consistency.

Programming Restrictions Inside Interrupt Routines

The S7-200 CPU automatically saves and restores the logic stack, the four accumulators (AC0-AC3), and the special memory bits that indicate accumulator and instruction status whenever an interrupt fires. Despite this hardware protection, the instruction set is restricted inside interrupt routines:

  • Prohibited: DISI, ENI, HDEF, LSCR, END, and any indirect-address move that uses a pointer modified inside the routine.
  • Permitted but discouraged: communications instructions, math operations with high scan cost, and any routine whose execution time exceeds the expected interval of a timed interrupt.
  • Allowed: MOVB, MOVW, MOVD, MOVR, bit-logic contacts/coils, comparison instructions, increment/decrement, and one nesting level of subroutine calls.

Declare interrupt routine local variables in the Local Variable Table of the interrupt POU so that the routine does not inadvertently overwrite V memory or M memory used elsewhere.

Subroutine Calls from Interrupt Routines

One level of subroutine nesting is permitted from inside an interrupt routine. The subroutine must be present in the same project and its total execution time plus the interrupt routine's own time must remain below the worst-case latency budget. Because RETI (not RET) unwinds the interrupt stack, Micro/WIN automatically inserts RETI as the unconditional terminator of every interrupt POU.

Step-by-Step Programming Procedure

  1. Plan the event map. List each interrupt source, its event number, the priority group, and the routine that will service it. Verify that no two sources collide.
  2. Insert the interrupt POUs. In Micro/WIN, choose Edit > Insert > Interrupt (or right-click Program Block in the Instruction Tree). Name the routine, e.g. INT_0. Repeat for each event.
  3. Configure timed intervals. If using INT0 or INT1, write the desired interval into SMB34 or SMB35 before the ATCH call.
  4. Attach events. From the main OB1 (typically in the first-scan SM0.1 network), call ATCH for each event with the appropriate routine number.
  5. Enable globally. Place a single ENI after the last ATCH to start processing. Optionally surround critical shared-data regions with DISI/ENI as needed.
  6. Implement sharing discipline. Decide whether each shared variable uses single-variable Move discipline or multi-variable DISI/ENI bracketing, and document the convention in the program header.
  7. Capture overflow bits. At the top of each interrupt routine, copy SM4.0/SM4.1/SM4.2 into retentive V memory so that loss events are observable.
  8. Compile and download. Use PLC > Compile All followed by Download. Confirm SM0.7 (RUN mode) and that SM0.0 (always-on) is true.
  9. Verify live behavior. Open Status Chart in Micro/WIN, add the SMB overflow bits, the timed-interval registers, and one event-counter variable, then go online to watch behavior under load.

Verification and Commissioning Checks

Check Method Expected Result
Interrupt attached Status Chart on routine's first network reads a flag set by the routine Flag toggles per event
Timed interval accuracy Toggle a digital output inside INT0 and observe with an oscilloscope or counter on the HMI Period matches SMB34 ±1 ms
No queue overflow Monitor SM4.0/SM4.1/SM4.2 in the Status Chart during worst-case load Bits remain 0 throughout the test
Shared data integrity Force a high-frequency event while the main program writes the shared record, then read back Record is always internally consistent
Stack hygiene Force a long-running interrupt (simulate with a breakpoint-style delay loop only in test firmware) and observe main scan Main scan continues normally after routine returns

Troubleshooting Matrix

Symptom Likely Cause Corrective Action
Interrupt routine never executes ATCH never called, or ENI missing, or DTCH called accidentally Verify the first-scan network contains the ATCH and that ENI runs after the last attach
SM4.1 set under load I/O events arriving faster than the queue can drain Reduce event rate, shorten the I/O routine, or split work between an I/O and a timed interrupt
Timed interrupt runs at unexpected period SMB34/SMB35 was changed without re-attaching Call DTCH, update SMB34/SMB35, then ATCH again
Shared variable reads corrupted values Multi-byte access not protected by DISI/ENI Bracket the multi-byte access with DISI/ENI, or move to a single-Move discipline
Micro/WIN reports a compile error inside the interrupt Use of prohibited instruction (DISI, ENI, HDEF, LSCR, END) Remove the instruction and refactor the routine; move configuration into the main scan
Routine executes but main program is starved Routine duration exceeds the main scan budget or the timed interval Optimize the routine, reduce its body to essential operations, and benchmark with a status chart
CPU 21x rejects 1 ms timed interrupt 21x series minimum interval is 5 ms Set SMB34/SMB35 to a value of 5 or greater on 21x hardware
Port-0 receive-character event never fires Receive interrupt was not enabled in the port configuration (Freeport mode required) Switch the port to Freeport via SMB30/SMB130 and verify ATCH 8, <routine>

Field Notes and Common Pitfalls

  • The unconditional terminators END (main), RET (subroutine), and RETI (interrupt) are inserted automatically by Micro/WIN and should never be hand-edited inside a POU.
  • Place ENI after the last ATCH in the same network or scan. If the global-enable happens before an attach, the event is armed but not associated; an edge that arrives in that window will be queued and fire against the wrong routine once it is attached.
  • Local variable scope in an interrupt POU uses the temporary (L) memory range. Do not promote local variables to global V memory just because the main program needs to read them — use a controlled move instead.
  • Do not exceed 128 total interrupts in a single project. Micro/WIN will refuse to compile beyond this count.
  • For migration paths to newer platforms, note that the S7-200 is not supported in TIA Portal. Replacement candidates include the S7-200 SMART (still Micro/WIN based) or the S7-1200 (TIA Portal based with hardware interrupt OBs). See the Using a S7-200 with TIA discussion for migration constraints.

What is the maximum number of interrupts in an S7-200 program?

Micro/WIN enforces a hard limit of 128 interrupt routines per project. Each event must be attached with its own ATCH call before it can fire.

Can I use ENI or DISI inside an interrupt routine?

No. ENI and DISI are prohibited inside an interrupt POU, along with HDEF, LSCR, and END. These instructions must be issued from the main program or a subroutine.

How do I detect missed interrupts on the S7-200?

Read SM4.0 (comm overflow), SM4.1 (I/O overflow), or SM4.2 (timed overflow) at the top of the relevant interrupt routine and copy the bit to retentive V memory, because the bits reset when the queue drains.

What is the difference between timed interrupts on CPU 21x and 22x?

The 22x series accepts SMB34/SMB35 values from 1 ms to 255 ms in 1 ms increments. The older 21x series requires a minimum interval of 5 ms (still in 1 ms increments up to 255 ms).

Can subroutines be called from an S7-200 interrupt routine?

Yes, but only one nesting level is supported. The subroutine must be present in the project and the combined execution time must remain below the interrupt interval, otherwise the timed queue will overflow (SM4.2 set).

Back to blog