1. Topic

GPIO modes, pull-up/pull-down, floating inputs, push-pull/open-drain, output speed, alternate functions, analog mode and EXTI. Main idea: STM32 GPIO is not just 0/1; it is a configurable electrical interface.

2. Why this matters in a project

Signals include 220/24 V optocoupler inputs, comparators, Schmitt triggers, RS-485 DE/RE, CAN standby, PWRKEY/RESET, fault/ready, sync/PPS and HIL inputs.

3. Theory

GPIO modes:

text
Input
Output
Alternate Function
Analog

A floating input picks up noise. Optocoupler, open-collector and open-drain connections need a pull-up/pull-down, preferably external for industrial inputs. A typical optocoupler input is often active LOW:

c
#define RED_ACTIVE_STATE GPIO_PIN_RESET
static bool input_is_active(GPIO_TypeDef *port,
                            uint16_t pin,
                            GPIO_PinState active_state)
{
    return HAL_GPIO_ReadPin(port, pin) == active_state;
}

Push-pull suits reset/enable/sync/LED outputs. Open-drain suits I2C, wired-OR and fault lines. Output speed controls the electrical edge, not execution speed. LOW is usually sufficient for reset/enable/DE/LED to reduce ringing and EMI. EXTI reacts to an edge:

c
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

Keep the callback short: timestamp/flag/notify task. Do not perform HAL_Delay, I2C, MQTT, printf or Modbus work there. EXTI suits clean signals after a Schmitt trigger/comparator. Handle raw optocoupler AC with polling and a pulse filter instead.

4. Common mistakes

  1. Leaving an industrial input floating.
  2. Expecting EXTI to filter noise.
  3. Debouncing with HAL_Delay() inside the callback.
  4. Selecting Very High speed for every output.
  5. Confusing open-drain with push-pull.
  6. Reading a digital value from a pin in analog mode.
  7. Configuring GPIO_EXTI but forgetting NVIC.

5. Practical task

Create STM32_GPIO_EXTI_POLICY.md:

markdown
# STM32 GPIO / EXTI policy
GPIO rules:
1. No floating industrial inputs.
2. Optocoupler/open-collector inputs require pull-up/pull-down.
3. External pull resistors are preferred.
4. Output speed is minimal unless fast edge is required.
5. Open-drain only when topology requires it.
6. AF must match datasheet mapping.
7. Analog mode only for ADC/DAC/COMP/OPAMP or unused low-power pins.
EXTI rules:
1. EXTI only for clean digital signals.
2. Dirty AC optocoupler signals are filtered before EXTI or handled by polling.
3. Callback is short.
4. Debounce/phase logic outside ISR.

6. Further reading and experiments

ST AN4899, STM32 EXTI examples, CubeMX GPIO/EXTI and the exact series reference manual.

An open-drain output is released and has neither an external nor an internal pull-up. Is HIGH guaranteed?

Exercise

Design the software path for a clean active-LOW signal after a Schmitt trigger. What does the EXTI callback record, and what does the task do? Why should this not be applied unchanged to raw AC?

Self-check criteria: State active-LOW, a short ISR, task-owned processing and the distinction between clean digital input and raw AC.

Show the supplied answer

The callback records a timestamp and minimal raw/flag/notification, then exits. The task handles event policy, diagnostics and subsequent work. Raw AC pulsates and can have noisy edges; it needs conditioning and an AC window/filter, rather than treating every edge as a new phase.