You are on page 1of 6

information.

The clock, called the


FEATURE master, must be supplied by a micro-
controller. This clock frequency does
not have to be constant. The master
ARTICLE also initiates communication with
serial devices called slaves. Often,
Dariusz Caban multiple slaves can use common data
and clock lines, with each slave hav-
ing its own select line or address.
One of the most popular synchro-

Software Implementation of nous interfaces is the inter-integrated


circuit (I2C), which was developed by
Philips nearly 20 years ago. I2C is a
low-bandwidth, short-distance, two-

the I2C Protocol wire interface that was originally


designed to enable communication
between devices inside a TV. Now,
I2C interface is implemented in over
1000 different devices. [1] Some
microcontrollers have a hardware I2C
controller built-in (e.g., the P8xC528

e
from Philips and the PIC16C6x from
Microchip). An all-software imple-
xternal devices mentation of I2C protocol is also pos-
that are used to sible. Thanks to this method, any
expand a microcon- microcontroller can communicate
Thanks to the possibil- troller’s internal with I2C devices. In this article, I’d
resources are generally available with like to present such an implementa-
ity of all-software a parallel interface but a serial inter- tion for the popular 8031 microcon-
implementation of the face is becoming more popular. There troller.
is a wide range of such devices,
I2C protocol, micro- including EEPROMs, display con- THE BUS
trollers, real-time clocks, A/D and The I2C interface is modest in its
controllers can com- D/A converters, and I/O expanders. hardware resource requirements,
municate with I2C Serial thermal sensors, directly con- because only a single pair of signal
nectable to a microcontroller, are lines is needed: serial data (SDA) and
devices. With this arti- offered as well. Serially accessed serial clock (SCL) (see Figure 1). Both
devices require less wiring and space lines are bidirectional and must be
cle, Dariusz presents on printed circuit boards than parallel connected to a positive supply voltage
us with an example ones. Thus, printed circuit boards and
connectors can be simpler and small-
via pull-up resistors. The SDA and
SCL pins of each device also must
implementation of the er. Reduced wiring also increases reli- have an open drain or open collector
ability of a system. In some cases, in order to perform the wired AND
Standard mode of the such microcontrollers without an function. Data can be transferred at a
external address and data bus, the rate of up to 100 kbps in Standard
I2C protocol for the application of serial devices enables mode, up to 400 kbps in Fast mode,
popular 8031 micro- interaction between the microcon- and up to 3.4 Mbps in High-Speed
troller and the outside world. mode. Each slave on the bus is identi-
controller. Most serial devices are equipped fied by a unique address.
with a synchronous interface for In Standard mode, 7-bit addressing
which they require separate signal is used. In other modes, slaves can
lines for transferring data and clock have 7- or 10-bit addresses. The num-

www.circuitcellar.com/online CIRCUIT CELLAR® ONLINE March 2002 1


acknowledgment from the
Figure 1—Here you can see how the I2C
addressed slave (because it is
devices connect to the microcontroller.
not connected or performs
some internal operation), the
master can abort the transfer.
Next, if the slave is being
written to, it must acknowl-
edge each byte received. Lack
of acknowledgment indicates
that it cannot accept data.
While reading from the slave,
the master is also obliged to
acknowledge each byte,
except the last byte.
The master can communi-
cate with the slave according
to several scenarios called
transfer formats. For exam-
ple, there are three possible
formats when 7-bit address-
ing is used. Their descrip-
tions can be found in “The
I2C-Bus Specification—
Version 2.1,” by Philips. [1]

THE PROCESS
ber of devices that can be connected condition. A 0-to-1 transition signals The I2C protocol does not have to
to the same bus is limited by the the end of a transfer and is termed as be implemented in hardware.
maximum bus capacitance of 400 pF. a stop condition. The data is trans- Software implementation is also pos-
The I2C bus can be controlled by ferred in bytes, with the most signifi- sible, because the protocol is forgiving
more than one master. If two or more cant bit sent first. Note that the byte with regard to timing accuracy. And,
masters simultaneously initiate data transfer requires nine clock pulses. any of the microcontroller’s general-
transfer, collision is detected and an The transfer of a byte’s bits takes purpose I/O lines can be used as I2C
arbitration procedure is performed. eight pulses, and the ninth is used for lines. This approach is useful when a
The arbitration doesn’t cause data cor- acknowledgment. Between start and system design includes only a single
ruption, however, most system stop conditions, an unrestricted num- master.
designs include only one master. ber of bytes can be transferred. As stated earlier, such designs are
Only the master generates the After a start condition, the byte most frequent. I have implemented
clock, but transmission speed can be containing the slave address (or part the I2C protocol for the 8031 micro-
adjusted to the internal operating rate of the address, when 10-bit addressing controller, using only Standard mode.
of the addressed slave. This adjust- is used) and a data direction bit is The source code was written in C-51.
ment is made by clock stretching, in always sent first (see Figure 3). A start The use of a high-level programming
which the slave keeps the SCL pulled condition can be repeated without language shortened development time
low until it is ready to continue. first generating a stop condition. This considerably. It also simplifies
is used to change transfer direction or changes and adaptation of the code to
THE PROTOCOL to address another slave. If there is no microcontrollers with different archi-
The I2C protocol is tectures.
level-sensitive. The data Listing 1 presents
must be stable when SCL Change of functions perform-
data allowed
is high. Except for two ing basic operations
situations, the state of the SDA .......
of the I2C protocol.
MSB LSB
.......
SDA line can only change SCL The functions given
1 2 ....... 8 9
when SCL is low. The ....... require 135 bytes of
exceptions have special START Data line Clock pulse for STOP code memory and
condition stable; acknowledgement condition
meanings (see Figure 2). A data valid only a few bytes of
1-to-0 transition signals internal data mem-
the beginning of a transfer Figure 2—This diagram shows the issuing of the start and stop conditions and how the byte trans- ory, if a compact
fer on the I2C bus is performed.
and is termed as a start memory model is

2 March 2002 CIRCUIT CELLAR® ONLINE www.circuitcellar.com/online


set. In order to guarantee appropriate
timing characteristics of signals, NOP Listing 1—By using these functions, data transfer via an I2C bus can be performed, assuming only a sin-
gle master exists.
instructions are used. An 8031 micro-
controller executes a NOP instruction
in one machine cycle. [2] One cycle #define uchar unsigned char
takes 12/fosc s, where fosc is the oscilla-
#define SDA P1.0 /* microcontroller's I/O lines */
tor frequency. The number of NOP #define SCL P1.1 /* assigned to I2C lines */
instructions in the given functions
was selected based on an oscillator /****************************************************
frequency of 12 MHz. Issuing of START condition.
****************************************************/
Now, let’s use the set of functions
given in Listing 1 to implement oper- void start(void)
ations on the Atmel AT24C02 device {
you saw in Figure 1. This device sup- SDA = SCL = 1;
SDA = 0;
ports 256 bytes of EEPROM. The _opc(0); /* it places NOP instruction */
slave address of the AT24C02 consists _opc(0); /* into executable code */
of a 4-bit type identifier (1010), fol- _opc(0);
lowed by a 3-bit sequence, which cor- _opc(0);
_opc(0);
responds to logic levels on the A2, SCL = 0;
A1, and A0 inputs. This way, up to }
eight EEPROMs can be addressed on
the same I2C bus. The AT24C02 also /****************************************************
Issuing of STOP condition.
has a write protect (WP) pin that pro- ****************************************************/
vides hardware data protection.
The following operations are void stop(void)
allowed: byte write, page write, {
SDA = 0;
acknowledge polling, current address SCL = 1;
read, random read, and sequential _opc(0);
read. Listings 2 and 3 present example _opc(0);
functions performing byte write and _opc(0);
_opc(0);
sequential read operations, respective- _opc(0);
ly. It was assumed that a single EEP- SDA = 1;
ROM exists in the system. }
When the microcontroller termi-
/****************************************************
nates the write sequence with a stop Clock pulse generation. The function returns data
condition, the EEPROM enters an or acknowledgment bit.
internally timed write cycle that, for ****************************************************/
the AT24C02, can last up to 10 ms.
bit clock(void)
During the write cycle, the EEPROM {
is busy and ignores all communica- bit level; /* state of SDA line */
tions on the I2C bus. The ready/busy
status of the device is determined by SCL = 1;
_opc(0);
using an acknowledge polling opera- while(!SCL); /* if a pulse was stretched */
tion. This operation involves issuing _opc(0);
of a start condition followed by the _opc(0);
slave address byte. If the EEPROM _opc(0);
level = SDA;
does not acknowledge, the cycle is _opc(0);
still in progress. If it does, the cycle _opc(0);
has completed. Listing 4 presents the SCL = 0;
function performing the acknowledge- return(level);
}
ment of the polling operation and its
possible use. /****************************************************
The sequential read operation is a Writing a byte to a slave, with most significant
convenient way to get multi-byte val- bit first. The function returns acknowledgment bit.
****************************************************/
ues stored in the EEPROM. In the
function presented in Listing 3, this bit write(uchar byte) Continued
operation is initiated by a write {
sequence to load the EEPROM’s inter-

www.circuitcellar.com/online CIRCUIT CELLAR® ONLINE March 2002 3


7-bit Addressing
code was produced. I darek1@mail.iitis.gliwice.pl.

A6 A0 R/*W Dariusz Caban completed his studies


at Silesian Technical University in REFERNCES
Slave address
Gliwice, Poland, where he received [1] Philips Semiconductors, “The
10-bit Addressing his MS. Since then, he has been work- I2C-Bus Specification—
1 1 1 1 0 A9 A8 R/*W ing at the Institute of Theoretical and Version 2.1,” January 2000,
Applied Computer Science, Polish http://www.semiconductors.ph
First seven bits of slave address
R/*W—data direction bit
Academy of Sciences (IITiS PAN) and ilips.com/acrobat/various/i2c_
0—Write cooperates with manufacturers of bus_specification_3.pdf.
1—Read
measurement and control equipment. [2] Intel Co., “Embedded
Figure 3—The byte containing all or part of the slave He holds a Ph.D. and specializes in Controller Handbook,” 1987.
address and the data direction bit are sent first after a
start condition.
programming of microcontrollers,
mainly in high-level languages. You
may reach him at
nal address counter with the initial
value. Then the master issues a start
condition again, sends a slave address
Listing 1— continued
with the data direction bit high, and
begins reading. After the master
receives a byte and acknowledges it, uchar mask = 0x80;
the EEPROM increments the address while(mask)
counter and sends a successive byte. {
The EEPROM continues sending until if (byte & mask)
the master does not acknowledge and SDA = 1;
else
generates a stop condition. Listing 5 SDA = 0;
shows an example of using the EEP- clock();
ROM_sequential_read() function. mask >>= 1; /* next bit to send */
}
SDA = 1; /* releasing of the line */
CONCLUSIONS return(clock()); /* a slave should acknowledge */
Compared to other competing syn- }
chronous serial interfaces, Microwire
from National Semiconductor and SPI /****************************************************
Reading byte from a slave, with most significant
from Motorola, I2C has the least hard- bit first. The parameter indicates, whether to
ware requirements. Only two I/O pins acknowledge (1) or not (0).
of the microcontroller are needed to ****************************************************/
communicate with multiple slaves,
uchar read(bit acknowledgment)
because each slave is identified by its {
unique address, not by a separate uchar mask = 0x80,
select line. Also, because the I2C pro- byte = 0x00;
tocol is level-sensitive, its noise
while(mask)
immunity is likely to be higher than {
in edge-sensitive competitors. And, if (clock())
unlike Microwire and SPI, I2C slaves byte |= mask;
provide feedback to the master, which mask >>= 1; /* next bit to receive */
}
indicates whether or not transmission if (acknowledgment)
was successful. Until recently, the I2C {
protocol was significantly slower, but SDA = 0;
in 1999 a high-speed mode was intro- clock();
SDA = 1;
duced, which offered rates up to 3.4 }
Mbps. else
In this article, I have presented an {
example all-software implementation SDA = 1;
clock();
of the Standard mode of the I2C proto- }
col. The source code was written in a return(byte);
high-level language, and you can easi- }
ly see that it is not complicated.
Although the compiler used was
rather old [2], small-size executable

4 March 2002 CIRCUIT CELLAR® ONLINE www.circuitcellar.com/online


SOFTWARE Listing 2—This function writes bytes to the EEPROM cell located at a given
The source code is available for address. The function returns the status of operation.
download in the html format of
the article. #define EEPROM 0xAE /* slave address, data direction
bit = 0 */
SOURCES
bit EEPROM_byte_write(uchar address, uchar byte)
C-51 {
Archimedes bit status;
+38121618243
Fax: +38121619308 status = 0; /* failure by default */
start();
www.archimedes.co.yu if (!write(EEPROM)) /* write operation */
if (!write(address)) /* byte address */
AT24C02 Two-wire serial EEP-
if (!write(byte))
ROM, AT89Cx051 80C31 micro- status = 1; /* success */
controller stop();
Atmel Corp. return(status);
}
(408) 441-0311
www.atmel.com
PIC16C6x 8-bit CMOS
Microcontroller
Microchip Technology Inc. Listing 3—The bytes are placed in memory, starting from the block address.
(978) 692-3848
Fax: (978) 692-3821 #define NO_ACK 0
#define ACK 1
www.microchip.com
bit EEPROM_sequential_read(uchar *block, uchar address,
P80C528, P83C528 8-bit
uchar size)
Microcontrollers {
Philips Semiconductors bit status;
(800) 326-6586
status = 0; /* failure by default */
(212) 536-0500
start();
Fax: (212) 536-0559 if (!write(EEPROM)) /* write operation */
www.semiconductors.philips.com if (!write(address)) /* initial address */
{
start();
if (!write(EEPROM | 0x01)) /* read operation */
{
while(size--)
*block++ = read(size ? ACK : NO_ACK);
status = 1; /* success */
}
}
stop();
return(status);
}

Circuit Cellar, the Magazine for Computer


Applications. Reprinted by permission.
For subscription information,
call (860) 875-2199, or www.circuitcellar.com.
Entire contents copyright ©2001 Circuit Cellar
Inc. All rights reserved.

www.circuitcellar.com/online CIRCUIT CELLAR® ONLINE March 2002 5


Listing 4—The first function determines the ready/busy status of the EEPROM. If you assume that after
the write sequence a program execution may be suspended until the write cycle is complete, the EEP-
ROM_busy() function can be used.

bit EEPROM_acknowledge_polling(void)
{
bit status;

start();
status = write(EEPROM);
stop();
return(status); /* if 1, the write cycle is in progress */
}

void EEPROM_busy(void)
{
while(EEPROM_acknowledge_polling())
delay(1,164); /* about 1 msec */
}

Listing 5—This example shows how to restore float variables within the contents of the EEPROM.

#define T1_SETP_ADDR 0 /* starting locations of set point */


#define T2_SETP_ADDR 4 /* values of temperatures */

/****************************************************
Global variables.
****************************************************/

float t1_setp, /* temperatures’ set points */


t2_setp;

/****************************************************
Initialization of the system.
****************************************************/

void initialization(void)
{
:
EEPROM_sequential_read(&t1_setp,T1_SETP_ADDR,4);
EEPROM_sequential_read(&t2_setp,T2_SETP_ADDR,4);
:
}

6 March 2002 CIRCUIT CELLAR® ONLINE www.circuitcellar.com/online

You might also like