I2C Introduction
Inter-Integrated Circuit
By Phillips semiconductor
There are so many sensors out there which have I2C as the only option available for interfacing. The I2C-bus is a de facto world standard that is now implemented in over 1000 different ICs manufactured by more than 50 companies. Additionally, the versatile I2C-bus is used in various control architectures such as System Management Bus (SMBus), Power Management Bus (PMBus), Intelligent Platform Management Interface (IPMI), Display Data Channel (DDC) and Advanced Telecom Computing Architecture (ATCA).
This tutorial and codes provided are mainly for dsPIC30F4012 but can be used for dsPIC30F4011 also without any change. It can be useful as a refernce for dsPIC33F series of micro-controller from Microchip. I have not interfaced any sensor to dsPIC30F but made two dsPIC's to communicate using I2C as medium.
dsPIC30F4012 is a 16-bit micro-controller designed and produced by Microchip. These micro-controller are specially designed for DC Motor speed and position control application. This 28-pin PDIP package contains one I2C module besides having 1 SPI(Serial Peripheral Interface), 1 UART and 1 CAN(Controller Area Network) 2.0B Compliant for communication.
The codes are tested on a pre-built Motor Control Board(MCB). This MCB is a development board build around dsPIC30F4012 micro-controller mounted with Maxon Motor. We need not to concern about board and its circuit. The Pins 17(SCL) and 18(SDA) of Micro-controller are of our interest. These two pins are SDA(Serial DAta) which is responsible for transmitting serial data and SCL(Serial CLock) which is generated by Master. The bus are pulled-up using resistors of 2 K-ohm.
This tutorial and codes provided are mainly for dsPIC30F4012 but can be used for dsPIC30F4011 also without any change. It can be useful as a refernce for dsPIC33F series of micro-controller from Microchip. I have not interfaced any sensor to dsPIC30F but made two dsPIC's to communicate using I2C as medium.
dsPIC30F4012 is a 16-bit micro-controller designed and produced by Microchip. These micro-controller are specially designed for DC Motor speed and position control application. This 28-pin PDIP package contains one I2C module besides having 1 SPI(Serial Peripheral Interface), 1 UART and 1 CAN(Controller Area Network) 2.0B Compliant for communication.
The codes are tested on a pre-built Motor Control Board(MCB). This MCB is a development board build around dsPIC30F4012 micro-controller mounted with Maxon Motor. We need not to concern about board and its circuit. The Pins 17(SCL) and 18(SDA) of Micro-controller are of our interest. These two pins are SDA(Serial DAta) which is responsible for transmitting serial data and SCL(Serial CLock) which is generated by Master. The bus are pulled-up using resistors of 2 K-ohm.
The I2C bus was developed in the early 1980's by Philips Semiconductors. Its original purpose was to provide an easy way to connect a CPU to peripheral chips in a TV-set.
I²C is appropriate for peripherals where simplicity and low manufacturing cost are more important than speed. Common applications of the I²C bus are:
- Reading configuration data from SPD EEPROMs on SDRAM, DDR SDRAM, DDR2 SDRAM memory sticks (DIMM) and other stacked PC boards
- Supporting systems management for PCI cards, through an SMBus 2.0 connection.
- Accessing NVRAM chips that keep user settings.
- Accessing low speed DACs and ADCs.
- Changing sound volume in intelligent speakers.
- Turning on and turning off the power supply of system components.
A particular strength of I²C is the capability of a micro-controller to control a network of device chips with just two general purpose I/O pins and software. Many other bus technologies used in similar applications, such as Serial Peripheral Interface Bus, require more pins and signals to connect devices.
These days most of the sensors have I2C interface. Gyros, Accelero-meters temperature sensors and list continues.
![]() |
| Accelerometer |
![]() |
| 3-Axis Gyroscope |
So in order to fetch data out of these sensors they must be interfaced with I2C of the micro-controller. Before interfacing any sensor to dsPIC30F, if you interface two dsPICs, one acting as master and other as slave. Then it will be very easy for us to interface any sensor to dsPIC30F.
Now let us first move to basics of I2C.
Basic Characteristics
- Two-wired bus SDA(Serial DAta) and SCL(Serial CLock)
- Originally to interact with small no. of devices over short distances
- Speed 100 kbps(Standard Mode),400 kbps(Fast Mode),3.4 Mbps(High-speed Mode)
- Data transfer:Serial,8-bit oriented, Bi-directional
- Master/Slave relationship with Multi-master
- Master can operate as Transmitter or Receiver
- Addressing 7-bit or 10-bit addressing
- Maximum device limit capacitance 400 pF
I2C Features available in dsPIC30F4011/4012
- Independent Master and Slave logic
- Multi-Master support. No messages lost in arbitration
- Detects 7-bit and 10-bit device addresses
- Detects general call addresses as defined in the I2C protocol
- Bus Repeater mode. Accept all messages as a slave regardless of the address
- Automatic SCL clock stretching provides delays for the processor to respond to a slave data request
- Supports 100 kHz and 400 kHz bus specifications
The above picture highlights the master-slave and receiver-transmitter relationships found on
the I2C-bus. Note that these relationships are not permanent, but only depend on the
direction of data transfer at that time. The transfer of data would proceed as follows:
1. Suppose micro-controller A wants to send information to micro-controller B:
– micro-controller A (master), addresses micro-controller B (slave)
– micro-controller A (master-transmitter), sends data to micro-controller B
(slave-receiver)
– micro-controller A terminates the transfer.
2. If micro-controller A wants to receive information from micro-controller B:
– micro-controller A (master) addresses micro-controller B (slave)
– micro-controller A (master-receiver) receives data from micro-controller B
(slave-transmitter)
– micro-controller A terminates the transfer.
Even in this case, the master (micro-controller A) generates the timing and terminates the
transfer
We will go in details in both of the above modes. In first mode i.e. master acting as transmitter and slave as receiver is simple and easy. Hardware setup is already shown above.
I2C Bus Protocol
- The data transfer may be initiated only when the bus is not busy
- During the data transfer, the data line must remain stable whenever the SCLx clock line is high. Any changes in the data line, while the SCLx clock line is high, will be interpreted as a Start or Stop condition.
![]() |
| Time Diagram |
Master is the device which sends start bit control serial clock line(either acting as transmitter or receiver) and sends or request data from particular slave then ether resart communication or stop it by sending stop bit. As per the value of I2CBRG registers the master generates clock. Let us have a look at code then we go through it in detail.
#include<p30f4012.h>
_FOSC(CSW_FSCM_OFF & XT); // To use the external crystal
_FWDT(WDT_OFF); // To disable the watchdog timer
void timer1_set(float); // Timer-1 settings
void i2c_set();
float T = 0.002;
void timer1_set(float Ts) // ******* Timer-1 settings
{
IEC0bits.T1IE = 1; // Enable Timer-1 interrupt
IFS0bits.T1IF = 0; // Clear Timer-1 interrupt flag to get next interrupt
PR1 = 7373000*Ts; // No of clk (count) per controller sampling time
TMR1 = 0; // Initialise the Timer count
T1CON = 0x8000; // Starts timer, Internal clock (Fosc/4), prescale 1:1
}
void i2c_set()
{
I2CCON = 0x8000; //Enable I2C module
I2CBRG = 0x00A;
IEC0bits.MI2CIE = 1;
IFS0bits.MI2CIF = 0;
}
void main()
{
timer1_set(T); // Initialise Timer-1 settings & start timer
i2c_set(); //Initialise I2C Module
I2CCONbits.SEN = 1;
while(I2CCONbits.SEN);
I2CTRN = 0x10;
while(I2CSTATbits.TRSTAT);
// Continue until stop the power
for(;;);
}
// Interrupt service routine (ISR) for interrupt from Timer1
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt (void)
{
IFS0bits.T1IF = 0; // Clear timer 1 interrupt flag
while(I2CSTATbits.ACKSTAT);
I2CTRN = 99;
while(I2CSTATbits.TRSTAT);
} // End of ISR of Timer 1
void __attribute__((interrupt, no_auto_psv)) _MI2CInterrupt (void)
{
IFS0bits.MI2CIF = 0;
}
The above code is for MPLAB C30 Compiler which is available at Microchip. Here is the one which i have used to compile code. Skipping oscillator setting and timer interrupt setting we are moving directly to I2C settings and registers.
I2C message comprises of addresses and data which is to be transmitted in a particular sequence.
- Master generates start bit, which is nothing but a falling edge when clock line is high. All devices on bus receives start bit and get ready for address to be transmitted by slave.
- After generating start bit Master writes address along with ReadWrite bit, to bus. Devices matches transmitted address with their address(if GCEN bit of I2CCON is cleared).The with the transmitted address responds with Acknowledge bit. Now there starts communication between responding slave and Master. No other device have control over any bus line.
- Upon receiving acknowledge from slave, Master then transmit data to bus. On reception of each byte of data slave send acknowledge bit to master.
- If master wants to read from slave, the bus must be turned in the other direction for the slave to send data to the master which is achieved by sending restart bit. To do this function without ending the message, the master sends a “Repeated Start”. The Repeated Start is followed with a device address byte containing the same device address as before and with the R/W= 1 to indicate slave transmission and master reception.
- Slave now sends data bytes to Master, Clock is generated by Master but clock stretching is under control of Slave.
- In order to end message stop bit is generated by Master which results in release of clock line and data line by Master.
Control and Status Registers
The I2C module has six user-accessible registers for I2C operation. The registers are accessible in either Byte or Word mode. These registers are described below.![]() |
| Width of registers |
Now lets get into details of the these registers.
Register I2CCON: Control Register
Register I2CCON: Control Register
Upper Byte:
R/W-0 U-0 R/W-0 R/W-1 R/W-0 R/W-0 R/W-0 R/W-0
HC
|
|||||||
I2CEN
|
—
|
I2CSIDL
|
SCLREL
|
IPMIEN(1)
|
A10M
|
DISSLW
|
SMEN
|
bit
15 bit 8
| |||||||
Lower Byte:
R/W-0 R/W-0
|
R/W-0
|
R/W-0 HC
|
R/W-0 HC
|
R/W-0 HC
|
R/W-0 HC
|
R/W-0 HC
|
|
GCEN
|
STREN
|
ACKDT
|
ACKEN
|
RCEN
|
PEN
|
RSEN
|
SEN
|
bit 7 bit 0
|
|||||||
bit 15 I2CEN: I2C Enable bit
1 = Enables
the I2C module and configures the SDA and SCL pins as
serial port pins
0 = Disables I2C module.
All I2C pins are
controlled by port functions
This bit is set for enabling I2C module which is written in code as I2CCONbits.I2CEN = 1;
bit 14 Unimplemented: Read as ‘0’
bit 13 I2CSIDL: Stop in Idle Mode bit
1 = Discontinue module operation when device enters an Idle mode
bit 12 SCLREL: SCL Release Control bit
(when operating as I2C Slave)
1= Release SCL clock
0= Hold SCL clock low (clock stretch)
If STREN = 1
Bit is R/W (i.e., software may write ‘0’ to initiate stretch and write ‘1’ to release clock)
Hardware clear at beginning of slave transmission.
Hardware clear at end of slave reception.
if STREN = 0
Bit is R/S (i.e., software may only write ‘1’ to release clock)
Hardware clear at beginning of slave transmission.
SCREL bit is cleared to release clock. It is coded as
I2CCONbits.SCREL = 0;
1= Release SCL clock
0= Hold SCL clock low (clock stretch)
If STREN = 1
Bit is R/W (i.e., software may write ‘0’ to initiate stretch and write ‘1’ to release clock)
Hardware clear at beginning of slave transmission.
Hardware clear at end of slave reception.
if STREN = 0
Bit is R/S (i.e., software may only write ‘1’ to release clock)
Hardware clear at beginning of slave transmission.
SCREL bit is cleared to release clock. It is coded as
I2CCONbits.SCREL = 0;
bit 11 IPMIEN: Intelligent Platform Management Interface (IPMI) Enable bit(1)
1 = Enable IPMI Support mode. All addresses Acknowledged
0 = IPMI mode not enabled
IPMIEN mode is not enabled.
I2CCONbits.IPMIEN = 0;
bit 10 A10M: 10-Bit Slave Address bit
1 = I2CADD
is a 10-bit slave address
0 = I2CADD
is a 7-bit slave address
Set in 7 bit address modebit 9 DISSLW: Disable Slew Rate Control bit
1 = Slew rate control disabled
0 = Slew rate control enabled
Slew rate enabled in code
bit 8 SMEN: SMBus Input Levels bit
1 = Enable
I/O pin thresholds compliant with SMBus specification
0 = Disable SMBus input thresholds
SMbus Disabled.
bit 7 GCEN: General Call Enable bit (when operating as I2C slave)
1 = Enable interrupt when a
general call address is received in
the I2CRSR (module is enabled for reception)
0 =
General call address disabled
Since we have receiver with proper address and we do not want all devices to listen to Master so disabled General call enable bit.bit 6 STREN: SCL Clock Stretch Enable bit (when operating as I2C slave) Used in conjunction with SCLREL bit.
1 = Enable software
or receive clock stretching
0 = Disable software
or receive clock stretching
This bit is cleared.
bit 5 ACKDT: Acknowledge Data bit (When operating as I2C Master. Applicable
during master receive) Value that will be transmitted when the software initiates an Acknowledge sequence.
1 = Send NACK
during acknowledge
0 = Send ACK during acknowledge
When we put Master in receiver mode then to send acknowledge to slave this bit is used. I will show the use of this bit in next tutorial where Master is receiver and slave is transmitter.bit 4 ACKEN:Acknowledge Sequence Enable bit(When operating as I2C master. Applicable during master receive.)
1= Initiate Acknowledge sequence on SDA and SCL pins, and transmit ACKDT data bit Hardware clear at end of master Acknowledge sequence.
0= Acknowledge sequence not in progress
This bit is also meant for Master in receiver mode.
bit 3 RCEN:Receive Enable bit (when operating as I2C master)
1= Enables Receive mode for I2C. Hardware clear at end eighth bit of master receive data byte.
0= Receive sequence not in progress
When master will act as receiver then this bit will be after sending Read bit.
bit 2 PEN:Stop Condition Enable bit (when operating as I2C master)
1= Initiate Stop condition on SDA and SCL pins. Hardware clear at end of master Stop sequence
0= Stop condition not in progress
To stop communication between Master and slave, Master generates stop bit.
bit 1 RSEN:Repeated Start Condition Enable bit (when operating as I2C master)
1= Initiate Repeated Start condition on SDA and SCL pins. Hardware clear at end of master Repeated Start sequence
0= Repeated Start condition not in progress
When master wants to change mode from transmitter to receiver or vice-versa, then restart bit is generated by Master.
bit 0 SEN:Start Condition Enable bit (when operating as I2C master)
1= Initiate Start condition on SDA and SCL pins. Hardware clear at end of master Repeated Start sequence
This bit is set for generating start bit.
The above code is for master only the code for slave will be posted in next article.







No comments:
Post a Comment