
AVR301
2
Theory of Operation
The I
2
C bus is a two-wire synchronous serial interface
consisting of one data (SDA) and one clock (SCL) line. By
using open drain/collector outputs, the I
2
C bus supports
any fabrication process (CMOS, bipolar and more). The I
2
C
bus is a multi-master bus where one or more devices,
capable of taking control of the bus, can be connected.
When there is only one master connected to the bus, the
resulting code is much simpler because handling of bus
contentions and inter master access (a master accessing
another master) is not necessary. Only master devices can
drive both the SCL and SDA lines while a slave device is
only allowed to issue data on the SDA line. This application
note implements a single master I
2
C-interface.
Software Description
The generic I
2
C routines listed below were compiled with
size optimization using IAR
’
s C Compiler Version 1.40.
These routines implement a single master I
2
C implementa-
tion. The AT90S8515 used to perform the master function
is driven by an external 7.3728 MHz crystal. The routine
BitDelay is executed in 15 clock cycles or a 2.03 μs period
and provides the quarter period bit timing necessary to
meet the 3.3V timing specifications found in the above
mentioned application note.
This code uses PORTB of the AT90S8515. On power-up,
PORTB is initialized to all inputs with the internal pull-ups
turned off, the external pull-ups pull the SDA and SCL lines
high and the PORTB output latch bits SCL and SDA are ini-
tialized to zero. Routines WriteSDA and WriteSCL toggle
their respective data direction bit depending on the value of
parameter
“
state
”
. When state is a
‘
1
’
the port pin is config-
ured as input (external pull-ups pull high). When state is a
‘
0
’
the port pin is configured as an output and the latch
drives the pin low. Table 1 lists the generic I
2
C routines and
the amount of code space used by each routine. WriteSDA
and WriteSCL are very simple routines that could be incor-
porated into their respective calling routines to further
reduce the code size.
Table 1 lists the number of clock cycles used while imple-
menting the function. Compiler options were set to
generate minimum code.
General Calling Sequence for the I
2
C Routines
Write:
SendStartBit();
/*start* /
SendByte(byte,msbfirst); /*send address MSB first*/
SendByte(byte,lsbfirst); /*send data byte to that*/
/*address LSB first*/
SendStop():
/*stop*/
Read:
SendStartBit();
/*start*/
SendByte(byte,msbfirst); /*send address MSB first*/
byte = GetByte(lastbyte);/*read byte from that*/
/*address last byte = 1
/*for the last byte*/
/*in a serial stream*/
SendStop();
The routines SendStartBit, SendByte, and GetByte all
leave the SCL signal low on exit, allowing the next routine
to write data to SDA (I
2
C allows changes on SDA only
when SCL is low; otherwise the I
2
C device will interpret a
start or stop condition). SendByte returns a flag indicating a
successful write to the I
2
C slave, 0x01 signals that the
slave did not acknowledge the transfer and that something
is wrong on the I
2
C bus or with the slave. WritePage and
ProgramResetPolarity use this flag for data polling. Figure
1 shows I
2
C start and stop bit conditions.
/*stop*/
Table 1.
Size and Execution Time for I
2
C Routines
Routine
Clocks
Bytes
SendStartBit
138
22
SendByte
1050-1054
74
SendStopBit
110
16
BitDelay
15
10
SetSCLHigh
33
38
WriteSCL
12-13
12
WriteSDA
12-13
12
GetByte
1089-1090
66