Electronics Design AU
CommunicationsEmbedded Systems

What Is I2C (Inter-Integrated Circuit)?

Last updated 7 July 2026 · 4 min read

Direct Answer

I2C (Inter-Integrated Circuit) is a two-wire synchronous serial bus — SDA for data and SCL for clock — that allows a controller to address multiple peripheral devices over the same pair of lines using a 7-bit or 10-bit device address, instead of needing a dedicated chip-select per device like SPI.

Detailed Explanation

I2C uses just two signal lines shared by every device on the bus:

  • SDA (Serial Data): carries both directions of data, time-multiplexed.
  • SCL (Serial Clock): generated by whichever device is currently acting as controller (in standard mode, a fixed primary controller).

Every transaction starts with a START condition, followed by a 7-bit (or extended 10-bit) address plus a read/write bit, then one or more data bytes, each acknowledged by the receiver, ending with a STOP condition. Because the address is transmitted on the bus itself, any number of peripherals can share the same two wires; there's no per-device chip-select like SPI requires.

Standard speed grades are 100 kHz (Standard Mode), 400 kHz (Fast Mode), 1 MHz (Fast Mode Plus), and 3.4 MHz (High Speed Mode), though most general-purpose sensors and EEPROMs only support up to Fast Mode.

Practical Examples

A common board might have an I2C temperature sensor, an I2C EEPROM, an I2C-controlled GPIO expander, and an external RTC IC all wired to the same two SDA/SCL pins on the microcontroller, each with a distinct fixed or configurable address. The firmware addresses each one individually over the shared bus rather than needing a separate pair of wires per device.

This is exactly why I2C is popular for sensor-heavy designs: adding another I2C peripheral often costs zero additional GPIO pins, as long as its address doesn't collide with something already on the bus.

Design Considerations

  • Pull-up resistor sizing: typical values are 2.2 kΩ–4.7 kΩ, but the correct value depends on bus capacitance (trace length, number of devices) and target speed. Too weak a pull-up limits rise time at high speed; too strong increases power draw and ringing.
  • Address collisions: check every device's address space before committing to a bus layout, especially with fixed-address sensors from the same vendor family. Where only two devices need to communicate point-to-point, UART is a simpler alternative with no addressing or pull-up requirements, though it cannot serve a shared bus.
  • Bus capacitance limits: the I2C spec caps total bus capacitance (400 pF for standard/fast mode), which limits practical trace length and device count without a bus buffer.
  • Clock stretching support: some peripherals pause SCL to indicate they need more time; confirm your microcontroller's I2C peripheral (and any bit-banged implementation) actually supports this, or transfers can corrupt silently. See how I2C clock stretching works and how to debug a timeout for the mechanism, which devices commonly use it, and how to tell a legitimate long stretch apart from a genuinely stuck bus.
  • Multi-master designs: I2C's "multi-master capable" label refers to a specific wired-AND bus-arbitration mechanism that lets two controllers safely start a transaction at the same moment without corrupting either one. See how I2C multi-master bus arbitration works for the mechanism and when a genuinely multi-controller bus is the right design choice.
  • Outgrowing I2C's speed or per-device interrupt lines: I3C is I2C's MIPI-defined successor, backward-compatible on the same SDA/SCL pins, adding dynamic addressing, In-Band Interrupts, and substantially higher throughput. Worth evaluating for a new sensor-heavy design where I2C's fixed addressing or lack of a built-in interrupt mechanism is becoming a real constraint.
  • Bus recovery from a stuck slave: a device interrupted mid-transaction (hot-unplugged, or browning out) while holding SDA low wedges the entire bus for every device on it, not just the affected one. Build in the I2C bus-clear recovery sequence from NXP's specification rather than relying on a full power cycle to clear it. On STM32 specifically, this same fault can leave the peripheral's own BUSY flag stuck set even after the bus-clear sequence. See STM32 I2C configuration and BUSY-flag lockup recovery for the additional peripheral-level reset this requires.
  • Choosing between I2C, SPI, and UART: for a structured comparison of when each protocol is the better choice, see SPI vs I2C vs UART: which to use.
  • I2C on Raspberry Pi: for enabling I2C via device tree overlay, sizing pull-ups for a CM4 carrier board, and using i2cdetect, see Raspberry Pi GPIO Interfacing.
  • Mixing 3.3 V and 5 V devices on the same bus: because I2C is open-drain and bidirectional, a simple resistor divider or unidirectional buffer cannot shift it. See how do you shift logic levels between 3.3V and 5V? for why I2C specifically needs an open-drain-aware bidirectional buffer (PCA9306/TCA9516-class, or a discrete MOSFET shifter).
  • Commercial peripheral integration: integrating multiple I2C peripherals into a production device involves driver development, bus diagnostics, and error recovery. Zeus Design's embedded firmware team handles this kind of hardware-software integration for commercial products.

Common Mistakes

  • Omitting pull-up resistors entirely because the bus "seems to work" on the bench with parasitic capacitance, then failing intermittently in production.
  • Two peripherals sharing a fixed address with no multiplexer or alternate-address strategy planned for.
  • Ignoring NACK responses from the bus and assuming a write succeeded. See what a real NACK-on-every-address failure looks like in practice for how to diagnose it systematically.
  • Running at 400 kHz with pull-up resistors and trace lengths only validated at 100 kHz.

Frequently Asked Questions

Why does I2C need pull-up resistors?
I2C uses open-drain outputs on both SDA and SCL, meaning devices can only pull the line low, never drive it high. External pull-up resistors are required to return the lines to a high (idle) state, and this is also what allows multiple devices to share the bus safely.
Can two I2C devices share the same address?
Not on the same bus segment. If two peripherals have a fixed, identical address, you need an I2C multiplexer/switch, a level-translating bus splitter, or to choose a peripheral variant with an alternate address (many sensors expose an address-select pin for exactly this reason).

References

Related Questions

Related Forum Discussions