You are on page 1of 8

•Projects

Microcontroller
BootCamp (7)
The I²C bus
By Burkhard Kainka If you are running short of I/O lines on an Arduino Uno board, a remedy is
(Germany)
available. The I²C bus needs only two port pins and can address up to 127
external ICs. There are countless devices available with I²C interfaces, including
simple port expanders, EEPROMs and a wide variety of sensors. In the final
instalment of our Bascom course series, we show you how the I²C bus works. As
usual, the main focus is on interesting demo applications.

The Inter-IC bus or I²C bus (barring code, also The I²C bus can work with 5 V microcontrollers
sloppily written as I2C) is a two-wire data bus and ICs as well as 3.3 V devices. You can even
consisting of a data line and a clock line, origi- connect both types to the same bus. The two
nally developed by Philips (not: Phillips) for con- pull-up resistors, which typically have a value of
sumer electronics applications. Most television 2.2 kΩ, hold the bus lines at 3.3 V or 5 V (logic
sets or video recorders have a central processor High level) when the lines are not pulled low by
that controls a large number of modules. With a any of the pull-down transistors in the devices
data bus consisting of just two lines, connecting connected to the bus. Any 5 V devices on the
all these modules to the processor is easy. The bus also see 3.3 V as a High level because it is
processor is the bus master, as with the SPI bus, significantly higher than 2.5 V (half of the supply
and the peripheral devices are the slaves. A par- voltage), and of course 0 V is logic Low in any
ticular feature of the I²C bus is that every slave system. This means that you can easily connect
device has a 7-bit address. That allows a large the Arduino Uno board to a 3.3 V slave device.
number of ICs to be connected to the bus with- That’s handy because many recent ICs are only
out interfering with each other. Along with RAMs, designed to operate at 3.3 V.
EEPROMs, port expanders, real-time clocks, A/D The ATmega328 on the Uno board has an inte-
and D/A converters, there are a large number grated hardware I²C interface connected to pins
of special-purpose I²C devices such as display PC4 and PC5. However, Bascom also has spe-
drivers, PLL ICs and many others. An excellent cial commands that can be used to implement
reference book on I2C is available from Elektor, a software I²C interface using any desired port
see Further Reading [a]. pins, and of course you can also write your own
functions to set the lines High or Low using indi-
Data transfer and addressing vidual code lines. Here we only use the Bascom
The I²C bus consists of a serial data line (SDA) software I²C interface, but with the same port
and a clock line (SCL). One bit per clock pulse pins as used by the hardware I²C interface inte-
(as in a shift register) is transferred on the data grated in the microcontroller.
line. Usually the address bits are sent first, fol- These port pins are also used on the Elektor
lowed by the data bits. Each line has a pull-up Extension shield [1] for the Arduino Uno. There
resistor, and each line can be pulled low by any they are routed to the EEC/Gnublin connector K2,
device on the bus. Figure 1 shows the basic which can be used to connect Gnublin modules
bus architecture. The master generates the clock with an I²C interface over a flat cable, such as a
signal. The data can come from the master or module with eight relays [2]. The bus lines also
from the slave. have 330 Ω series resistors, which can be omit-

34 | November 2014 | www.elektor-magazine.com


Microcontroller Bootcamp

ted if desired. However, they provide protection by the addressed slave. Then the master sends
against false signals resulting from reflections on the data byte, which is also acknowledged. The
long bus lines, and they can help avoid problems connection can be ended now by generating the
that may occur on buses with devices operating stop condition, or another byte can be sent to
at different supply voltages. For example, the the same slave.
input currents of 3.3 V peripheral devices could
exceed the maximum rated value if one of the I²C bus address with data direction
bus lines is accidentally set to a 5 V high level A6 A5 A4 A3 A2 A1 A0 R/W
for a prolonged period. The series resistors limit
the input current to a safe level. If the master want to read data from a slave, the
The I²C bus protocol defines several specific address must be sent with the data direction bit
states that allow every device on the bus to detect set to 1. The master then generates eight clock
the start and end of a transfer: pulses and receives eight data bits. If reception is
confirmed by an acknowledgement on the ninth
• Quiescent state: SDA and SCL are high and clock pulse, it can receive another data byte. At
therefore inactive. The Bascom instruction the end the master terminate the transfer with
I2cinit puts both lines in the quiescent a stop condition when no acknowledgement is
state but without internal pull-up resistors, received.
since they are located externally. Every I²C device has a fixed address. Part of the
• Start condition SDA is pulled low by the address is specific to the device type, and the rest
master while SCL remains high (Bascom can be configured by the user with the address
instruction: I2cstart). lines A0, A1, etc. fed out from the device. These
• Stop condition: SDA changes from low address lines are tied high or low in the circuit
to high while SCL remains high (Bascom to set the address bits. If the device has three
instruction: I2cstop). address lines fed out, such as the PCF8574 port
• Data transfer: The current sender places expander, up to eight different addresses can be
eight data bits on the data line SDA, which set. This means that up to eight devices of the Figure 1.
are shifted out by clock pulses on the clock same type can be connected to one bus. This I²C bus connections
line SCL generated by the master. The trans- port expander provides eight digital outputs, and between master and slave
fer starts with the most significant bit (Bas- the signal levels on the outputs are determined devices.
com instruction: I2cwbyte Data).
• Acknowledge (Ack): The currently addressed
receiver acknowledges reception of a byte +3V3/+5V
by holding the SDA line low until the master ATmega328
2k2

2k2

has generated a new clock pulse on the SCL Master, VDD = 5V

line. This acknowledgement also means that PC4 SDA


330R
another byte is expected to be received. If
the device wishes to end the transfer, it must PC5 SCL
330R
indicate this by omitting the acknowledge-
ment (Nack).
The transfer is terminated by the stop con-
dition (Bascom instruction: i2crbyte Data,
Ack or i2crbyte Data, Nack). Slave, VDD = 3V3/5V

SDA
Addresses are transferred and acknowledged in
the same way as data. In the simplest case of a
SCL
data transfer from the master to a slave, such
as an output port, the following procedure is
used. The master generates the start condition
and then transfers the address of the port IC
in bits 1 to 7 and the desired direction of the
140293 - 11
data transfer in bit 0 – in this case, 0 for writ-
ing to the device. The address is acknowledged

www.elektor-magazine.com | November 2014 | 35


•Projects

Many ICs allows the user to set the last three


Listing 1.
address bits. The PCF8583 real-time clock IC has
Polling for active I²C addresses.
the same base address as a RAM because it also
'------------------------------------ contains a RAM. If you want to use a RAM and
'UNO_I2C1.BAS Test for valid Adresses
a real-time clock on the same bus, you have to
'------------------------------------
give them different addresses.
$regfile = "m328pdef.dat"
Incidentally, there are two different notations
$crystal = 16000000
for the address, which sometimes cause confu-
$baud = 9600
sion and laborious troubleshooting. Some data
sheets only give the 7-bit address without the
Dim Addr As Byte
read/write bit. In that notation the base address
...
Config Scl = Portc.5 of the PCF8574 would be 20hex (decimal 32) By
Config Sda = Portc.4 contrast, in Bascom this IC has a write address
I2cinit of 64 (40hex = &H40) and a read address of 65
(&H41).
For Addr = 2 To 254 Step 2
I2cstart To learn the addresses of the devices connected
I2cwbyte Addr to the bus, you can use the small Bascom pro-
If Err = 0 Then gram shown in Listing 1 (downloadable from
Print Addr [3]). It polls every possible bus address to see
Locate 2 , 1 whether a device responds. After a device address
Lcd Addr is output, the Bascom system variable ERR (which
Waitms 1000 does not have to be declared with Dim because
End If Bascom has already done this for you) is set to
I2cstop 1 if no acknowledgement is received or to 0 if
Next Addr an Ack signal is received. The latter case means
End that the address is valid. All even addresses from
2 to 254 are tested, since the odd addresses are
the corresponding read addresses of the same
by the eight bits in the data byte sent to the IC. devices. For the circuit shown in Figure 2, the
The base address of the port expander is 40hex program reports the addresses 64, 144, 160 and
(decimal 64). The base addresses of some typical 162 just as expected.
first-generation Philips I²C devices are: There’s another special feature of the I²C bus
protocol: every device on the bus can halt the
• PCF8591 A/D converter: 90hex (decimal 144) master for a while if it needs a bit more time. To
• RAMs and EEPROMs: A0hex (decimal 160) do so it pulls the clock line Low, which forces the
• PCF8583 real-time clock: A0hex (decimal master to wait until the line is released again.
160) Bascom follows this convention faithfully. How-

VCC

Master
2k2

2k2

SDA

SCL

SCL SDA SCL SDA SCL SDA SCL SDA


A0 A0 A0 A0
A1 PCF8574 A1 PCF8591 A1 24C512 A1 PCF8583
A2 Adr. 64 A2 Adr. 144 A2 Adr. 160 A2 Adr. 162
Figure 2.
140293 - 12
A master and four slaves.

36 | November 2014 | www.elektor-magazine.com


Microcontroller Bootcamp

ever, this means that a program that uses the


I²C bus will hang if no pull-up resistors are con-
nected. From other projects you may be used to +5V/+3V3

the idea that you can sometimes test software


without connecting the associated hardware. As 16 15 14 13 12 11 10 9
a result, you might find yourself staring at an 2k2

SCL

P7
P6
P5
P4
VCC
SDA

Int
oscilloscope while checking out your software to Device
2k2 PCF8574 under
see whether there are any signals at all on the
Test

GND
SCL and SDA lines, while the cable to the Gnub-

A0
A1
A2
P0
P1
P2
P3
1 2 3 4 5 6 7 8
lin board is not yet connected. What you have
overlooked is that the I²C bus pull-up resistors +5V

330R
330R
are on the Gnublin board. Since no pull-ups are
present on the host board, everything remains
in suspended animation and there are no signals
28 27 26 25 24 23 22 21 20 19 18 17 16 15
on the I²C bus.

GND

AVCC
C5
C4
C3
C2
C1
C0

B5
B4
B3
B2
B1
AREF
The PCF8574 port expander ATmega328p

The PCF8574 is a port expander IC with eight

GND
VCC
RES
D0
D1
D2
D3
D4

D5
D6
D7
B0
X1
X2
bidirectional port pins. It does not have a data 1 2 3 4 5 6 7 8 9 10 11 12 13 14

direction control function. Instead, the port pins


have internal pull-up resistors that cause a high 16MHz
level to be present in the quiescent state. This
means that after booting you will initially read 100n

the port status 255 (binary 11111111). You will 22p 22p
140293 - 13
only see low values (logic 0) if the port pins are
actively pulled to ground by an external device.
It is possible to use some of the port pins as may be necessary, which means you will need Figure 3.
outputs and the others as inputs. This requires different test software. Using the PCF8574 port
first configuring all of the input pins in the high expander.
state, the same as the output pins. PCA9555 16-bit I/O port
Figure 3 shows the bus connections and a poten- Sometimes eight more lines are not enough. The
tial application of the port expander as a digital Gnublin port expander module [2] provides 16
tester. The port expander can be powered from I/O lines using an NXP PCA9555 IC. The board
3.3 V or 5 V according to the operating voltage can be plugged directly into the EEC connector
of the item under test. Any desired digital circuit on the Elektor Extension shield. There is also a
with four inputs can be driven using the output Gnublin relay board that uses the same IC.
port pins P0 to P3. For example, you could apply NXP is the successor to Philips, and the PCA9555
an incrementing digital value to these four pins to is the rightful successor to the PCF8574. That’s
obtain all possible combinations of signal levels why the two devices have the same bus address:
on the circuit inputs. Cables and connectors can 64 (&H40). This sort of address recycling makes
also be tested the same way. Every open circuit sense because the address space is limited. In
and short circuit can be detected. any case, why would you need a PCF8574 when
Listing 2 shows an example of how to use a you have a PCA9555? Along with twice as many
mixed set of inputs and outputs. Here pins P0 I/O pins, the new IC has additional functions
to P3 output a continuously incrementing digital such as data direction control and inversion of
value. Pins P4 to P7 are used as inputs and must the input data.
therefore be set high in the write operation (Or Figure 4 shows how the IC can be connected to
&B11110000) The IC is addressed twice: first in the Elektor Extension shield using the EEC con-
the write direction (address 64) and then in the nector. The I²C bus lines and supply voltage lines
read direction (address 65). Incrementing the are connected using a flat cable. The two pull-up
value on the four outputs is the simplest possi- resistors on the Gnublin board are connected to
ble type of test stimulus. Depending on the item the bus lines by a pair of jumpers. These jump-
under test, a completely different test sequence ers must be fitted if only one board is connected.

www.elektor-magazine.com | November 2014 | 37


•Projects

Listing 2. Accessing the PCF8574 ports.


'------------------------------------ Print " ";
'UNO_I2C2.BAS input/output PCF8574 Locate 2 , 1
'------------------------------------ Lcd N
$regfile = "m328pdef.dat" Lcd " "
$crystal = 16000000
$baud = 9600 I2cstart
I2cwbyte 65 'read
Dim N As Byte I2crbyte D , Nack
Dim D As Byte I2cstop
... Shift D , Right , 4
Do Print D
For N = 0 To 15 Locate 2 , 5
I2cstart Lcd D
I2cwbyte 64 'write Lcd " "
D = N Or &B11110000 Waitms 100
I2cwbyte D Next N
I2cstop Loop
Print N;

If you use several boards, perhaps connected That yields a bus address of 64. A total of eight
using the Gnublin distributor board [2], make boards can be connected, with addresses from
sure that the pull-up resistors are only enabled 64 to 72. With 16 I/O pins per board, that gives
on one board. It is possible to use several port you a grand total of 128 I/O lines.
expander boards because each board has jump- Listing 3 shows an application for the PCA9555,
ers for configuring address lines A0 to A2. In the which can also be used for testing other circuits.
default state, all three lines are tied to ground. As in the previous example, the port pins are

Listing 3. Using the PCA9555 port expander.


'------------------------------------ I2cwbyte N
'UNO_LCD1.BAS input/output PCA9555 I2cstop
'------------------------------------ Print N;
$regfile = "m328pdef.dat" Print " ";
$crystal = 16000000 Locate 2 , 1
$baud = 9600 Lcd N
Lcd " "
Dim N As Byte
Dim D As Byte I2cstart
... I2cwbyte 64 'write
I2cstart I2cwbyte 1
I2cwbyte 64 'Gnublin port expander I2cstart
I2cwbyte 6 I2cwbyte 65 'read
I2cwbyte 0 'Port 0 output I2crbyte D , Nack
I2cwbyte 255 'Port 1 input I2cstop
I2cstop Print D
Locate 2 , 5
Do Lcd D
For N = 0 To 255 Lcd " "
I2cstart Waitms 100
I2cwbyte 64 'write Next N
I2cwbyte 2 Loop

38 | November 2014 | www.elektor-magazine.com


Microcontroller Bootcamp

divided up with half of them used for outputs


+3V3
and the other half used for inputs. Since things
are a bit more complicated here, a command
byte has to be sent after each address [4]. The
command selects a register address in the IC.

2k2

2k2
After that you can send or receive one or two 24
VDD
bytes of data. For example, if you want to con- 2 1 I/O0.0
4
5
figure port 0 (with eight pins) and port 1 (with I/O0.1
SDA 23 6
SDA I/O0.2
the other eight pins), you first send the com- 22 7
SCL I/O0.3

PORT 0
SCL
mand ‘6’ after the address and then write two I/O0.4
8
9
data bytes, which are placed in registers 6 and 7. I/O0.5
1 10
INT I/O0.6
Zero bits in these bytes mean that you want to 3V3 GND 11
I/O0.7
14 13
configure the corresponding pins as outputs. One EEC PCA9555D
13
bits stand for inputs. In our example, all pins of I/O1.0
14
I/O1.1
port 0 are configured as outputs and all pins of 15
I/O1.2
port 1 are configured as inputs. Incidentally, pins I/O1.3
16

PORT 1
21 17
configured as inputs have integrated high-imped- 2
A0 I/O1.4
18
A1 I/O1.5
ance pull-up resistors (approximately 100 kΩ), 3 19
A2 I/O1.6
so open inputs are read as logic 1. You can use I/O1.7
20
VSS
the following command byte values: 12

Figure 4.
0 Input Port 0 140293 - 14
The PCA9555 on the Gnublin
1 Input Port 1 board.
2 Output Port 0
3 Output Port 1 for each command. In order to read a port, the
4 Polarity Inversion Port 0 IC must also be addressed again with the read
5 Polarity Inversion Port 1 bit set (address 65). If you examine the code
6 Configuration Port 0 closely, you may wonder why there is no I2cstop
7 Configuration Port 1 instruction. That’s because the code implements a
‘repeated start’ without a previous stop condition,
The commands 2 (Output Port 0) and 1 (Input since the two accesses always belong together:
Port 1) are used iteratively in the data loop of the writing the command to select the register to be
sample program. The IC must be addressed anew read and reading the register contents.

Other interesting I²C components


Anyone who reads Elektor regularly is always running into interesting ICs with an I²C interface.
They often form the inspiration for new projects. Some particularly significant types are:

• I²C EEPROMs up to 64 KB (for example, the 24C512). These can be used to build data loggers
and lots of other things.
• The CY27EE16 is a crystal clock generator that can be programmed over the I²C bus. It is
used in the Elektor Software Defined Radio project. Software control with a microcontroller
opens the door to new possibilities.
• The SI4735 is a complete AM/FM receiver and has already been used in several Elektor
projects along with Bascom. Any desired frequency can be set using just a few I²C commands.
• High-resolution A/D and D/A converters often have I²C ports. One example is the ADS1115
16-bit A/D converter recently described in Elektor.
If you want to delve deeper into this subject, you can even build your own I²C bus IC. A Bascom
library for programming I²C slave devices is available for this purpose. That is a bit more
difficult than programming a bus master because the slave device must be able to handle the
bus speed set by the master. The Mastering the I2C Bus book has all the details.

www.elektor-magazine.com | November 2014 | 39


•Projects

Analog I/O with the PCF8591


The PCF8591 contains an 8-bit A/D converter with
four inputs along with an 8-bit D/A converter in
+5V the same package. You probably won’t need the
A/D converter by itself because the Arduino Uno
16 15 14 13 12 11 10 9
already has enough analog inputs and higher
2k2
resolution for A/D conversion. However, a real

OSC

SCL
VCC

SDA
AGND
Ref
A0

Ext
A/D converter can come in handy. Unlike a PWM
PCF8591
2k2 output, it delivers a true DC voltage. You can use
DUT

GND
this to build a simple diode tester that measures
Ai0
Ai1
Ai2
Ai3
A0
A1
A2
1 2 3 4 5 6 7 8 the forward voltage at a defined current level (see
+5V Figure 5). The circuit operates at 5 V so that it
330R
330R

can also be used to measure the relatively high


forward voltage of LEDs.
The IC has a control register that must be writ-

1k
28 27 26 25 24 23 22 21 20 19 18 17 16 15
ten right after the bus address is sent. A control
GND

AVCC
C5
C4
C3
C2
C1
C0

B5
B4
B3
B2
B1
AREF

byte value of 64 enables the D/A converter and


ATmega328p selects input channel 0. The following byte is put
into the D/A register and results in an output
GND
VCC
RES
D0
D1
D2
D3
D4

D5
D6
D7
B0
X1
X2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 voltage in the range of 0 to 5 V, corresponding


to a data range of 0 to 255. With this 8-bit res-
16MHz
olution, the output voltage increment is approx-
imately 20 mV. The demo program in Listing 4
100n generates a rising voltage ramp and measures
22p 22p the voltage across the 1 kΩ sense resistor at the
140293 - 15
same time. The PCF8591 has to be addressed
again in the read direction (address 145) to read
the measured voltage. The read byte value rep-

Figure 5.
Listing 4. A diode tester using the PCF8591.
A diode tester using the
PCF8591. '------------------------------------- I2cstart
'UNO_I2C4.BAS AD/DA PCF8591 I2cwbyte 145 'read
'------------------------------------- I2crbyte D , Nack 'Ain0
$regfile = "m328pdef.dat" I2cstop
$crystal = 16000000 Print D
$baud = 9600 Locate 2 , 5
Lcd D
Dim N As Byte Lcd " "
Dim D As Byte Waitms 100
Dim U As Word N = N + 1
... If D >= 50 Then Exit Do
N = 0 Loop
Do Cls
I2cstart Locate 1 , 1
I2cwbyte 144 'write Lcd " 1 mA"
I2cwbyte 64 'DA enable U = N - D
I2cwbyte N U = U * 20
Print N; Locate 2 , 2
Print " "; Lcd U
Locate 2 , 1 Lcd " mV"
Lcd N End
Lcd " "

40 | November 2014 | www.elektor-magazine.com


Microcontroller Bootcamp

resents the voltage on input Ai0. A reading of 50 elektor-labs.com and http://forum.elektor.com


indicates a voltage of 1 V, which corresponds to (Microcontrollers section). Relatively small proj-
a diode current of 1 mA. At this point the ramp ects or applications still in the development stage
is stopped. Now the forward voltage of the diode are especially welcome.
can be calculated from the difference between (140293-I)
the output voltage and the input voltage. It is
displayed in millivolts. With a sample blue-green
Web Links
LED, the following results were displayed at the
end of the measurement cycle: [1] www.elektor-magazine.com/140009
[2] www.elektor.com/tools/gnublin
1 mA [3] www.elektor-magazine.com/140293
2920 mV
[4] www.nxp.com/documents/data_sheet/
PCA9555.pdf
Future prospects
This is the last installment of our Microcontroller
BootCamp series, but there will be other articles
Further Reading
on Bascom applications for the Arduino Uno and
the Elektor Extension shield from time to time. [a] Mastering the I2C Bus, Vincent Himpe,
We hope we have aroused your enthusiasm for Elektor International Media Publishers,
developing your own programs. If so, we encour- ISBN 978-0-905705-98-9.
age you to share the results of your efforts with Also available as an E-book.
other members of the Elektor community at www.
Advertisement

Create Complex Electronic Systems


in Minutes Using Flowcode 6
Design Simulate Download

Flowcode is one of the World’s most advanced


graphical programming languages for micro-
controllers (PIC, AVR, ARM and dsPIC/PIC24).
New in Version 6:
The great advantage of Flowcode is that it allows • Component Library Expansion;
those with little experience to create complex elec- • Improved Simulation;
tronic systems in minutes. Flowcode’s graphical • New Test Features;
development interface allows users to construct a • 3D Design Environment;
complete electronic system on-screen, develop a • Third Party Instrument Support;
program based on standard flow charts, simulate • Dashboard HMI Components;
the system and then produce hex code for PIC • And More!
AVR, ARM and dsPIC/PIC24 microcontrollers.

Further Information and Ordering at www.elektor.com/flowcode

www.elektor-magazine.com | November 2014 | 41

You might also like