Instiq
Chapter 4 · Hardware & interfaces·v1.0.0·Updated 7/10/2026·~14 min

What's changed: Initial version

4.5GPIO, buses, and timers

Key points

Covers input circuit design for the general-purpose I/O pin, GPIO (pull-up, open-drain); the address bus/data bus/control bus connecting the CPU to peripheral devices; and the input capture, output compare, and PWM timer functions that handle time measurement and waveform generation, building basic judgment for embedded hardware I/O design.

GPIO (general-purpose I/O pins), the bus (the wiring between the CPU and peripheral devices), and the timer (time measurement and waveform generation) form the foundation of an embedded device's basic I/O. Though they may look mundane, these are the technologies that underpin embedded design: getting the input circuit design wrong causes malfunctions, getting the bus design wrong hurts performance, and failing to use the right timer function wastes CPU load on time measurement or waveform generation. This section covers the correct usage and design judgment for each.

4.5.1GPIO and pull-up/open-drain

  • GPIO (general-purpose input/output) is a general-purpose pin whose input/output direction and High/Low level can be set from software. When used as an input, an unconnected (Hi-Z, or high-impedance) pin's potential is undefined, which can pick up external noise and cause a false High/Low reading. Adding a pull-up resistor (weakly pulling the pin toward the supply voltage) or a pull-down resistor (pulling it toward ground) fixes the default potential for when the switch is open (unconnected), preventing malfunction.
  • Open-drain (open-collector) output is an output stage that has no transistor for the High side, so it can only pull the line toward Low (an external pull-up resistor is required to reach High). Its advantage is that connecting several devices' outputs to a single signal line still lets the line go Low if any one device drives it Low (a wired-AND), which suits a bus, such as I2C's, where multiple devices share the same line. Unlike push-pull output (which actively drives both High and Low), it avoids a short circuit from contending outputs (a bus conflict) when multiple devices assert the line at once.

4.5.2Address bus, data bus, and control bus

  • The bus connecting the CPU to peripheral devices (memory, I/O) is broadly divided into three kinds. The address bus is the set of signal lines by which the CPU specifies which memory location/device to access, and its bit width determines the size of the address space (the maximum accessible memory capacity) (e.g., an n-bit address bus can specify up to 2^n locations). The data bus is the set of signal lines actually carrying data, and its bit width determines how much data can be transferred at once (throughput).
  • The control bus is the set of signal lines carrying the read/write distinction (R/W), data-valid timing, interrupt requests, bus arbitration signals, and the like. The essential difference is that while the address bus and data bus carry "where" and "what," the control bus carries the instructions for timing and operation—"when and how" to handle it. All three buses must be present together for memory-mapped I/O access between the CPU and a peripheral device to work correctly.
Exam point

Most-tested: "pull-up/pull-down = fixes the potential when unconnected, preventing malfunction", "open-drain = drives only Low, wired-AND, suited to a shared bus", and "address bus width = address space, data bus width = transfer throughput, control bus = timing/operation instructions". Do not mistakenly believe open-drain can "also actively drive High"—returning to High relies on the pull-up resistor.

4.5.3Input capture, output compare, and PWM timer functions

  • Input capture automatically records the timer counter's value at the instant an external signal edge (rising or falling) occurs, into a register. There is no need for the CPU to monitor the signal change by polling; simply reading the captured value in an interrupt handler yields an accurate timing measurement (pulse width or period), allowing high-precision time measurement without loading the CPU.
  • Output compare automatically changes a pin's output level (or generates an interrupt) at the instant the timer counter reaches a preset value. There is no need for the CPU to monitor time in a loop and manually toggle the pin; it can generate a square wave or pulse at precise timing. The PWM timer function is an application of this output-compare mechanism, repeating it periodically and varying the duty cycle to control the effective voltage.

Suppose an embedded engineer is implementing a driver for an ultrasonic distance sensor (a sensor that transmits a pulse and computes distance from the time until the reflected wave is received). The initial implementation had the CPU continuously poll the receive pin's state in a software loop, recording the time of the instant it went High using a millis() function, but this ran into a defect: when other processing (communication, sensor reads, etc.) delayed the loop, a gap of several milliseconds arose between the actual edge occurrence and its detection, causing the distance calculation's precision to vary wildly. The cause is an essential weakness of the polling approach: the timing of an edge occurrence cannot be captured accurately while the CPU is doing something else. The fix is to switch to the MCU's input capture function—assigning the receive pin to a timer's input capture channel means the timer counter's value at the instant of the edge is automatically recorded into a register by hardware, so the captured value itself is accurate no matter how delayed the CPU is by other processing. The CPU only needs to read the capture register inside an interrupt handler whenever convenient, and can compute an accurate pulse width (i.e., the time to reflection). Likewise, generating the ultrasonic transmit pulse itself with an accurate width (say, 10 microseconds) is difficult if the CPU toggles the pin High/Low in a software loop, but designing it so the output compare function automatically returns the pin to Low the instant the timer counter reaches the target value achieves accurate pulse-width generation unaffected by CPU load or software delay. The trap to avoid here is the misconception that "writing a sufficiently fast polling loop can achieve the same precision as input capture"—even interrupt-driven polling can, in principle, miss an edge while the CPU is executing some other task, whereas input capture operates independently in hardware, so using the dedicated timer function rather than polling is the correct design decision for applications requiring timing precision.

FunctionBehaviorUse case
Input captureAutomatically records the counter value at the instant of an edgeHigh-precision measurement of pulse width or period
Output compareAutomatically toggles the pin/fires an interrupt when the counter reaches a set valuePrecisely timed square-wave/pulse generation
PWMRepeats output compare periodically, varying the duty cycleEffective-voltage control such as motor speed or LED brightness
Warning

Trap: "writing a sufficiently fast polling loop achieves the same timing precision as input capture" is wrong—polling can, in principle, miss an edge while the CPU is executing some other task, whereas input capture operates independently in hardware and is unaffected by CPU load. Also wrong: "an open-drain output can drive High even without a pull-up resistor"—open-drain can only pull the line toward Low; returning to High relies on an external pull-up resistor.

GPIO/pull-up/bus.
Wiring the basics

4.5.4Section summary

  • Pull-up/pull-down fixes the potential when unconnected; open-drain drives only Low, and its wired-AND behavior suits a shared bus
  • Address bus width determines the address space; data bus width determines transfer throughput; the control bus carries timing/operation instructions
  • Input capture/output compare/PWM operate independently in hardware, achieving high-precision measurement/generation unaffected by CPU load or software delay

Sign in to track progress — Log in.

Quick check

(just a quick review)

Q1. The design wants to record the rising-edge timing of an ultrasonic distance sensor's receive pulse accurately, even when the CPU is delayed by other processing. Which approach is most suitable?

Q2. The design wants multiple devices to share the same signal line, in a bus configuration where the line goes Low if any one device drives it Low. Which output method is most appropriate?

Q3. Among the buses connecting the CPU to a peripheral device, which set of signal lines carries "when and how" to handle the transfer—such as the read/write distinction and data-valid timing?

Check your understandingPractice questions for Chapter 4: Hardware & interfaces

Keep track of your progress

The full study guide is free to read. Sign up free to practice with the question bank, track what you have read, review your mistakes, and highlight passages.