The ATmega328 datasheet gives
some quite detailed information on
the protocol — we’re not going to
get into that level of detail here since
the microcontroller takes care of
much of the behind-the-scenes
complexity for us. A quick note: The
datasheet refers to I2C as TWI, or
Two Wire Interface. This was to avoid “complications”
with the trademark that Phillips (now NXP) registered on
the I2C protocol; however, TWI is completely I2C
compatible.
Get Connected
Let’s start with the physical connections. In addition
to a common ground, I2C only needs two connections
between the modules wanting to communicate: Clock
(called SCL — Serial CLock) and Data (called SDA — Serial
DAta). I2C differs from the serial UART communication we
looked at a couple of months ago in that the UART
operated at a specific speed (baud rate). I2C is more
flexible in that it doesn’t need to agree to a speed
between the modules up front, but operates at the speed
that the clock signal dictates.
One bit of data is transferred each time the clock
signal pulses — the clock signal is a bit like a metronome,
setting the pace for the module’s communication. The
advantage of this type of communication is that the
modules don’t need accurate crystals or oscillators — a
microcontroller can communicate with all sorts of
(relatively simple) modules, without worrying about
whether they’re going to stay synchronized.
The data line operates much as we’d expect — as a
series of voltages: high levels (for a “1” bit) and low levels
(for a “0” bit). String the bits together in time with the
clock pulses, and you’re soon transferring full bytes.
Remember Your Pull-Ups
The signals for I2C are referred to as open-drain. In
other words, their default state is high and they need to be
pulled low. Let’s digress to illustrate this: If you were to
connect an LED with the cathode (negative terminal) to
your microcontroller and the anode to your power rail,
you would be operating on an open-drain setup. For the
LED to be off, you’d have to ensure the pin on your
microcontroller was high (usually by using a pull-up
resistor). To turn the LED on, you’d pull the pin low (i.e., to
GND), allowing current to flow.
I2C operates on a similar principle. The lines are held
high by pull-up resistors, and then pulled low by the
modules wanting to communicate. When the modules
stop pulling the lines low, they “bounce” back up to a
high state. So, remember, I2C must always be
accompanied by pull-up resistors on the SDA and SCL
lines. The datasheets will usually give you an indication of
the value of the resistors, but a value from 2K to 10K
usually does the trick.
Building Up the Protocol
I mentioned earlier that I2C has a slightly more
complicated protocol as a trade-off for the simplicity of
the physical connection. While you don’t need to
understand how the protocol works at a physical level as
signals transition between high and low (timing diagrams
like those in Figure 1 can get a bit overwhelming), you do
need to know the protocol for having a conversation.
Figure 2 summarizes the key elements of an exchange,
detailed next.
The Start Condition
Every communication needs to begin with a start
“condition” which occurs when the SDA line is pulled low
before the SCL has started pulsing. This warns the
connected modules that something is coming — a bit like
clearing your throat before you address a group of people.
By Andrew Retallack Post comments on this article and find any associated files and/or downloads
at www.nutsvolts.com/index.php?/magazine/article/september2015_Retallack. www.crash-bang.com
Figure 1: Typical I2C timing diagram.
Figure 2: Key
elements in an
I2C exchange.
September 2015 53