Understanding Microcontroller Pin Input/Output Modes

GPIO (aka General Purpose input/output) is the simplest of microcontroller IO. Even so, GPIO comes in various types and varieties. There is input, output, pull-up, pull-down, push-pull, high-drive, open-drain, and more. We will take a look at each of these and cut through the confusion so you know exactly how you need to configure your pins.

Input Modes

GPIO input modes include

  • high impedance
  • pull-up
  • pull-down
  • repeater
  • hysteresis (not usually optional, but we will talk about it anyway)

Floating, High Impedance, Tri-Stated

Floating, high impedance, and tri-stated are three terms that mean the same thing: the pin is just flopping in the breeze. Its state is indeterminate unless it is driven high or low externally. You only want to configure a pin as floating if you know it will be driven externally. Otherwise, configure the input using pulling resistors.

A Word on Impedance. Impedance is very similar to resistance but considers how a circuit reacts when a changing voltage is applied. A resistor only has resistance. But inductors and capacitors have impedance (resistance + reactance). Now you know!

Pull Up/Down

If an input is configured with an internal pull-up, it will be high unless it is externally driven low. Pull-down inputs do the opposite ( they’re low unless driven high). Some GPIO pins also support changing the pull-up and pull-down settings dynamically using repeater mode (but truth be told, I have never configured a pin that way).

Read more about pull-up and pull-down resistors.

Repeater

When a GPIO is configured in repeater mode, the pull-up is enabled when the pin is driven high, and the pull-down is enabled when the pin is driven low. If nothing is driving the pin, the pin will retain its last known state (so I guess “repeater” isn’t just a clever name). In some cases, this can prevent a pin from floating.

You might be wondering why pins shouldn’t be floating. When pins are floating, current can leak in and out of the pin. \( leaky+current = bad \). So, don’t leave pins floating.

Hysteresis

Virtually all GPIO inputs use a principle called hysteresis to prevent spurious changes in the state when an input changes. I think of hysteresis as having a low threshold to go low and a high threshold to go high. So if you are somewhere in the middle, nothing changes. You can see this in the graph below where A (with no hysteresis) has some state changes on that B (with hysteresis) filters out.

Hysteresis Graph

The low threshold can be found in the datasheet in the “Electrical Characteristics” section as \( V_{IL}\) and the high threshold is \( V_{IH}\).

Output Modes

Push-Pull

A push-pull output is another aptly-named GPIO mode. The pin can “push” the signal high or “pull” it low. It does this using a pair of complementary transistors. You have probably heard of “CMOS” technology. The C stands for “complementary”. A CMOS device has a pushing transistor (PMOS) and a pulling transistor (NMOS).

In the circuit below where I is the input and O is the output

  • when I is 1, PMOS is off and NMOS is on which makes O be 0
  • when I is 0, PMOS is on and NMOS is off which makes O be 1 (kanobi)
PMOS
PMOS
NMOS
NMOS
I
I
O
O
1
1
0
0

Open-Drain

To understand what open-drain means, we need to look at the anatomy of a MOSFET transistor. The MOSFET (NMOS in this case) has three terminals.

  • Drain (spoiler-alert this is the “drain” part of “open-drain”)
  • Gate
  • Source
NMOS
NMOS
I
I
O
O
0
0
Drain
Drain
Gate
Gate
Source
Source

On an open-drain pin, there is no “push” transistor. So

  • when I is 1, O is pulled to 0
  • when I is 0, O is “open” (get it? The drain is open as in open-drain pin)

If you recall about 2 minutes ago, we don’t want to leave pins floating so in most cases open-drain pins will have an external pullup resistor. If you are tricky (of course, you are), you can configure the MCU’s pull-up resistor and use the pin in open-drain output mode.

One of the cool things about open-drain pins is that you can have more than one open-drain output connected to an MCU input. If any of the open-drains are pulling the line to zero, the input will be zero. Since none are ever pushing, you won’t have any digital infighting (which is worse than floating pins). This is why many sensors have open-drain outputs for signaling events. You can connect a bunch of them to one microcontroller interrupt then use the I2C (or another bus) to see which one is active.

High Drive

When a GPIO has high drive capability, it is just a push-pull pin that can source or sink more current than usual. A typical push-pull output can source/sink around +/-8ma where a high drive output may be up to +/-40ma. Again, that “Electrical Characteristics” section of the datasheet is your go-to source for the details.

Understanding the current capabilities of pins is important if you are trying to drive LEDs or do anything more than just send data back and forth. If you want a nice bright LED indicator, you will use about 20ma which is more than a run-of-the-mill GPIO pin can provide.

The End

For a brief re-cap, GPIO is the simplest IO on microcontrollers. However, it turns out it isn’t that simple. You will want to be deliberate about setting input pins with (or without) pulling resistors. For outputs, remember push-pull vs open-drain and make sure you have enough drive current for the task at hand.

Readability changes published on September 11 (never forget), 2019