First, What Is It
- GPIO (General-Purpose Input/Output): pins that can be read and written — output high/low to light an LED, or sample an external level to detect a button press. It is the most basic "switch and eye" of an MCU.
- Read vs write: writing a pin controls the output level (like flipping a switch); reading samples the external level (like checking the switch state).
- Why start with GPIO: it covers output, input, pull-up/pull-down, and interrupts — the four fundamentals that every other peripheral builds on.
Breaking Down the Principle
1. Internal Structure: Output Driver and Input Sampler
Each GPIO pin internally contains an "output driver + input sampler + optional pull resistors". Configuring modes switches these internal circuits:
2. Output Modes: Push-Pull and Open-Drain
| Mode | Structure | Features | Typical use |
|---|---|---|---|
| Push-pull | Drives high and low actively | Strong drive, fast | LEDs, buzzers |
| Open-drain | Can only pull low; high level needs an external pull-up | Different voltages, wired-AND | I2C, shared buses, level shifting |
The open-drain "wired-AND" property: when several open-drain outputs are wired together, the bus is low if any of them drives low — the physical basis for I2C multi-device sharing.
3. Input Modes: Floating / Pull-Up / Pull-Down
- Floating: the level is undefined when the pin is not driven — easily disturbed, generally avoided.
- Pull-up: a resistor pulls the default level high; a button to ground pulls it low when pressed — the most common button wiring.
- Pull-down: the default level is low; a button to VCC pulls it high when pressed.
Whether "pressed" is high or low depends on where the other end of the button is connected and the pin's default level — wiring it backwards gives "pressed without touching" or "pressed but no response".
4. Alternate Function (Pin Mux)
GPIO is not only GPIO: UART TX/RX, SPI clocks, PWM outputs, etc., all occupy pins. Each pin can be muxed to multiple peripheral functions, chosen via pin-function configuration (in the SDK, commonly interfaces like GLB_GPIO_Func_Init). When you want to move a signal to another pin, first check which functions that pin supports.
5. Levels and Drive Strength
- High/low are relative: in a 3.3 V system, "1" ≈ 3.3 V and "0" ≈ 0 V, but the threshold to read as "1" is usually lower than 3.3 V (e.g., ≥2.0 V).
- Drive strength limits the load: lighting an LED needs a few milliamps; driving a relay or motor directly requires a transistor or driver chip, otherwise the pin can be damaged.
How the SDK Implements It
- Related pages: GPIO Output (LED), GPIO Input (Button), EXTI Interrupt
In the LED example, the SDK configures a GPIO output as "define device struct → configure mode → write level" (the WB2 SDK uses the HOSAL unified peripheral layer: define a hosal_gpio_dev_t struct variable and pass it to init — there is no "get device handle" model):
hosal_gpio_dev_t led; /* Define the device struct directly — no get_by_name */
/* Configure GPIO3 as output (Ai-WB2-32S-Kit onboard blue LED, active high) */
led.config = HOSAL_GPIO_OUTPUT_PUSH_PULL; /* Push-pull output */
hosal_gpio_init(&led);
hosal_gpio_output_set(&led, 1); /* Output high, LED on */Button input first configures the pin as input with pull-up, then reads the level (or uses an interrupt):
hosal_gpio_dev_t btn; /* Define the device struct directly — no get_by_name */
/* Button to ground, configured as input with pull-up: default high, low when pressed */
btn.config = HOSAL_GPIO_INPUT_PULL_UP;
hosal_gpio_init(&btn);
uint8_t val;
hosal_gpio_input_get(&btn, &val); /* 0 means pressed */(Underneath, HOSAL also wraps the register-level API, e.g., bl_gpio_enable_output(pin, pullup, pulldown) and bl_gpio_output_set(pin, value) — a style commonly seen in the SDK's basic examples.)
Common Exam & Interview Questions
Difference between push-pull and open-drain? When to use open-drain?
Push-pull actively drives high and low with strong drive; open-drain can only pull low and needs an external pull-up for high. Use open-drain for I2C, shared buses, and cross-voltage level shifting.
Why add a pull-up resistor to a button?
The pull-up keeps the pin high by default; pressing the button to ground makes it low, so "released = 1, pressed = 0" is well defined and the pin is never floating.
What is pin muxing (alternate function)?
A pin can switch between GPIO and multiple peripheral functions. Because pins are limited, muxing lets UART, SPI, PWM, etc., share pins; configuration selects the current function.
Can GPIO drive a relay or motor directly?
No. Relays/motors need more current — use a transistor, MOSFET, or a driver chip (add a flyback diode for inductive loads), otherwise the pin can be damaged or the system may reset.
Software debounce vs hardware debounce?
Software: confirm the level after a few milliseconds of delay or sample periodically; hardware: parallel capacitor or RC filter on the button. Both prevent mechanical bounce from causing multiple triggers.
Have questions?
For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

