This is a very common challenge when working with microcontrollers or FPGAs, because the number of available I/O pins often isn’t enough for all sensors, buttons, or displays you want to connect. The two classic solutions are shift registers and I/O expanders. Let’s go step by step:
1. Expanding I/O with Shift Registers
How It Works
A shift register takes serial data from the MCU and “shifts” it out bit by bit to multiple outputs.
You only need 3 MCU pins:
- Data (SER)
- Clock (SRCLK)
- Latch (RCLK)
Each clock pulse moves one bit into the register, and the latch updates the outputs.
Common Chips
- 74HC595 (8-bit serial-in, parallel-out): For expanding output pins.
- 74HC165 (8-bit parallel-in, serial-out): For expanding input pins.
Example (74HC595 for Output Expansion)
- Chain multiple 74HC595s together → 8, 16, 24, … outputs.
- Send 16 bits of serial data, and 2 cascaded chips will output 16 parallel signals.
- Useful for LED driving, digit displays, relays, etc.
Pros:
- Very cheap, widely available.
- Can cascade many for lots of outputs.
Cons:
- One-direction only (output OR input, not both at the same time).
- Requires fast MCU to keep updating outputs.
2. Expanding I/O with I/O Expanders
How It Works
An I/O expander is an IC that communicates over a serial bus (I²C or SPI) with the MCU and provides extra GPIOs that can be configured as input or output.
Common Chips
- MCP23017 (I²C, 16 I/O pins, up to 8 devices = 128 pins).
- PCF8574 (I²C, 8 I/O pins, very popular for LCD modules).
- MCP23S17 (SPI version of MCP23017, faster).
Example (MCP23017 on I²C Bus)
- Connect SCL and SDA to the MCU (just 2 pins).
- Each chip provides 16 extra pins.
- Address pins allow up to 8 MCP23017 devices on one bus = 128 pins total.
- Each pin can be input, output, or even have pull-ups.
Pros:
- Bi-directional I/Os.
- Easy to configure (libraries available for Arduino, STM32, etc.).
- Less CPU overhead compared to manually clocking shift registers.
Cons:
- Slightly more expensive.
- Slower than direct MCU I/O (because of I²C/SPI communication delays).
3. Comparison Table
4. When to Use Which
- Shift registers (74HC595/165): Best when you need lots of simple, fast outputs/inputs (e.g., LED matrices, 7-seg displays, button panels).
- I/O expanders: Best when you need true GPIO flexibility (input + output, pull-ups, interrupts), and want to save MCU pins with a simple I²C/SPI interface.
In short:
- Use 74HC595 (output) or 74HC165 (input) for fast, cheap expansion.
- Use MCP23017/PCF8574 for smarter, flexible GPIO expansion over I²C.
Top comments (0)