How it works
Each GPIO port has several control registers: CRL (configuration low, pins 0–7), CRH (configuration high, pins 8–15), IDR (input data), ODR (output data), BSRR (atomic set/reset), BRR (bit reset only). Each pin occupies 4 bits in CRL/CRH: MODE bits (00 = input, 01/10/11 = output at 10/2/50 MHz max speed) and CNF bits (in output mode: 00 = push-pull, 01 = open-drain, 10/11 = alternate function push-pull/open-drain; in input mode: 00 = analog, 01 = floating, 10 = pull-up/pull-down). Alternate function (AF) mode is required for USART, SPI, I2C, and timer PWM pins — a pin used as USART1_TX (PA9) must be configured as AF push-pull output at 50 MHz.
Key points to remember
Pull-up resistors (internal, typically 30–50 kΩ on STM32) prevent floating inputs from toggling randomly — any unconnected digital input must be pulled up or down. Output drive strength: 2 MHz mode reduces switching noise and EMI, suitable for slow signals like LEDs; 50 MHz mode is needed for SPI clock up to 18 MHz or SDIO. Open-drain output can be wire-OR'd with other open-drain pins (I2C uses this). BSRR provides atomic bit manipulation: upper 16 bits reset pins, lower 16 bits set pins — a single 32-bit write both sets and clears different pins simultaneously, avoiding read-modify-write race conditions in ISRs. For STM32F4/F7, GPIO is reorganised into MODER, OTYPER, OSPEEDR, PUPDR, and AFR registers.
Exam tip
The examiner always asks you to write the C code (or register values) to configure a specific STM32 pin as push-pull output and toggle it — show the RCC clock enable, CRL/CRH mode and CNF bits setting, and the BSRR write in sequence.