Inter-Integrated Circuit (I2C) is a bidirectional communication protocol commonly used to connect microcontrollers (MCUs) to various integrated circuits (ICs) like IMUs, temperature sensors, multiplexers, and more. It's popular for its simple hardware interface, multi-slave communication capability, and low power consumption.
Hardware:
SDA = Serial Data = Streams binary data onto the bus
SCL = Serial Clock = Synchronizes binary data. SDA is sampled on the rising edge of SCL
Take an example waveform:
We notice that I2C is an 8-bit communication protocol, meaning that for every 8 bits we receive an ACK. We can also take note of the following characteristics:
START BIT = Pulling SDA low while SCL is high
END BIT = Pulling SCL high while SDA is low
ACK/NACK BIT = This is the 9th bit. ACK means the message was received properly, bit will be 0. NACK means the message was not received, bit will be 1
Standard I2C Communication Steps:
Addressing [0:8]:
The master starts by sending a 7-bit address of the slave device it wants to communicate with
The 8th bit indicates the operation: 0 = Write, 1 = Read
Acknowledge [9]:
After the address byte, the slave device responds with an ACK bit if it recognizes the address.
Data Transmission [10:]:
Depending on the operation (Read or Write), data is either sent master → slave or slave → master.
The receiver sends an ACK bit for every byte of data to confirm successful reception
Stop Condition:
The master ends the communication by generating a STOP condition.
Open-Drain:
The defining characteristic of I2C buses is that both SCL and SDA are open-drain pins. Put simply, this means the STM32 can only pull the line LOW. It needs a pull-up resistor to go back HIGH.
Notice that there is only 1 NMOS transistor that controls Vout. A Pull-up/Pull-down GPIO has two transistors. When Vin is HIGH, Vout = GND. However, when Vin is LOW, we notice that Vout is left floating. That's when the pull-up resistor pulls the line HIGH.
Multi-Slave Busses
I2C busses can hold up to 127 slaves on a single bus. Unlike SPI, I2C does not have a chip select line to control communication. Instead I2C relies on IC addressing (each IC on the bus has a different address). Typically each slave has alternative addresses that can be configured in the situation two slaves have the same address.
Arbitration:
Arbitration is used to resolve conflicts that arise from 2 or more devices transmitting on the bus. The bus has a wired-AND system, where only one bus can
Clock Stretching:
Resources:
https://www.circuitbasics.com/basics-of-the-i2c-communication-protocol/
https://en.wikipedia.org/wiki/I%C2%B2C
https://www.allaboutcircuits.com/technical-articles/the-i2c-bus-hardware-implementation-details/