I²C — Inter-Integrated Circuit Bus
I²C connects many sensors, EEPROMs, RTCs and power ICs using just two wires. Learn open-drain signalling and pull-ups, start/stop conditions, 7-bit addressing, ACK/NACK, register read/write sequences with repeated start, clock stretching, speed modes, pull-up resistor sizing from bus capacitance, multi-master arbitration and bus-recovery techniques.
I²C (two-wire interface, TWI) uses SDA (data) and SCL (clock). Both lines are open-drain: devices can only pull them low, and pull-up resistors bring them high. This allows many devices, and even multiple masters, to share the bus without short circuits.
Each device has an address; the master starts a transaction, sends the address and a read/write bit, and the addressed device acknowledges. Typical sensor access is 'write the register number, then read its value' — a pattern you will use constantly.
An analogy
I²C is a meeting where anyone may lower a flag (pull the line low) but nobody may force it up — springs (pull-ups) raise it. The chairperson (master) calls a name (address); only that person answers 'present' (ACK).
Open-drain and pull-ups
No device ever drives I²C lines high; they only release them and pull-ups raise the voltage. This wired-AND behaviour makes a low from any device win, enabling ACKs, clock stretching and multi-master arbitration. Too-large pull-ups give slow rising edges; too-small ones exceed the drivers' sink current.
Anatomy of a transaction
Every transfer follows the same pattern:
- START: SDA falls while SCL is high
- Address byte: 7-bit address + R/W bit, followed by ACK from the slave
- Data bytes: 8 bits MSB first, each followed by ACK (receiver pulls SDA low)
- Master-read ends with NACK on the last byte
- STOP: SDA rises while SCL is high; or REPEATED START to change direction
Speed modes and clock stretching
Standard mode 100 kHz, Fast 400 kHz, Fast-mode Plus 1 MHz, High-speed 3.4 MHz. A slow slave may hold SCL low (clock stretching) until it is ready — the master must wait, and some MCU implementations handle this poorly. Data rate is modest: a 2-byte register read at 400 kHz takes ~100 µs.
Robustness in real products
Address conflicts (two identical sensors) are solved with address pins, I²C multiplexers (TCA9548A) or separate buses. Long cables and many devices raise capacitance above the 400 pF limit — use bus buffers/extenders (P82B715). Implement timeouts on every transaction, the 9-clock recovery procedure, and SMBus features (PEC CRC, alert line) for power-management devices. For multi-master systems, arbitration happens bit by bit: the master that sends a 1 but reads a 0 loses and backs off.
Formulas
- Minimum pull-up:
R_p,min = (V_DD − V_OL,max) / I_OL (3.3 V, 0.4 V, 3 mA → 967 Ω) - Maximum pull-up:
R_p,max = t_r / (0.8473 × C_b) - Rise time limits:
Standard 100 kHz: 1000 ns; Fast 400 kHz: 300 ns; Fast-mode Plus 1 MHz: 120 ns - Address byte:
byte = (addr7 << 1) | R/W̅ (0x48 → write 0x90, read 0x91) - Transaction time:
t ≈ (9 bits × bytes + start/stop) / f_SCL
Worked example: Address byte
Given: 7-bit address 0x48
Find: Bytes for write and read.
- 0x48 << 1 = 0x90
- Read: 0x90 | 1
Answer: Write 0x90, read 0x91
Worked example: Pull-up range
Given: 3.3 V, 400 kHz, C_b = 200 pF
Find: R_p limits.
- R_min = (3.3 − 0.4)/3 mA = 967 Ω
- R_max = 300 ns / (0.8473 × 200 pF) = 1770 Ω
Answer: Use ≈ 1.2–1.5 kΩ
Worked example: Temperature conversion
Given: TMP102 returns 0x19 0x00
Find: Temperature.
- 0x1900 >> 4 = 0x190 = 400
- 400 × 0.0625 °C
Answer: 25.0 °C
Reading a temperature sensor register (TMP102-style) with HAL
#define TMP102_ADDR (0x48u << 1) /* HAL expects the 8-bit (shifted) address */
#define REG_TEMP 0x00u
int16_t tmp102_read_centi(void)
{
uint8_t buf[2];
/* START, 0x90 (W), reg 0x00, REPEATED START, 0x91 (R), 2 bytes, NACK, STOP */
if (HAL_I2C_Mem_Read(&hi2c1, TMP102_ADDR, REG_TEMP, I2C_MEMADD_SIZE_8BIT,
buf, 2, 10) != HAL_OK) {
return INT16_MIN; /* caller handles the error */
}
int16_t raw = (int16_t)((buf[0] << 8) | buf[1]) >> 4; /* 12-bit, signed */
return (int16_t)(raw * 625 / 100); /* 0.0625 C/LSB -> centi-degrees */
}
/* Example: bytes 0x19 0x00 -> raw 0x190 = 400 -> 2500 = 25.00 C */The repeated start keeps bus ownership between the register write and the read. Integer maths (×625/100) avoids floating point. Always check the return status — a missing ACK usually means wrong address or wiring.
Bus recovery when a slave holds SDA low
void i2c_bus_recover(void)
{
gpio_config_open_drain(SCL); gpio_config_open_drain(SDA);
for (int i = 0; i < 9 && !gpio_read(SDA); i++) { /* clock out the stuck byte */
gpio_write(SCL, 0); delay_us(5);
gpio_write(SCL, 1); delay_us(5);
}
gpio_write(SDA, 0); delay_us(5); /* generate a STOP: */
gpio_write(SCL, 1); delay_us(5); /* SDA low -> high while */
gpio_write(SDA, 1); delay_us(5); /* SCL is high */
i2c_peripheral_reinit();
}If the MCU resets mid-read, a slave may still be driving a 0 bit and SDA stays low forever. Toggling SCL up to 9 times lets it finish its byte; then a STOP resets the bus state machine.
Common mistakes
- Wrong: No pull-ups (or relying on weak internal 40 kΩ pull-ups at 400 kHz). — Right: Fit external resistors sized for bus capacitance.
- Wrong: Confusing 7-bit and 8-bit address notation. — Right: 0x48 (7-bit) = 0x90/0x91 (8-bit with R/W).
- Wrong: No timeout — firmware hangs on a stuck bus. — Right: Timeouts + bus-recovery routine.
- Wrong: Long cables to off-board sensors. — Right: Use buffers/differential extenders or a different bus.
Applications
- Sensors: Temperature, humidity, IMUs, pressure, light sensors.
- Memory: EEPROMs for calibration and configuration.
- Power management: PMICs, fuel gauges, battery chargers (SMBus/PMBus).
- Board control: IO expanders, RTCs, display controllers, DDC in HDMI.
Key takeaways
- Two open-drain wires + pull-ups, many devices.
- START, address+R/W, ACKs, data, STOP/repeated start.
- Size pull-ups from bus capacitance and speed.
- Always add timeouts and bus recovery.
Going further
- I3C: MIPI successor: push-pull, 12.5 MHz, in-band interrupts, dynamic addressing.
- SMBus/PMBus: Timeouts, PEC and standard commands for power systems.
- 10-bit addressing: Extended address space for large systems.