How to program I2C protocol in ARM Microcontroller


I2C (Inter Integrated Circuit) also known as TWI (Two wire Interface) is a bus interface connection that is used in many devices such as Sensors, RTC and EEPROM. Unlike SPI this protocol only uses two wires to establish the connection and hence known as Two wire interface. This protocol will come in handy when the designer needs to conserve the number of pins used to perform the communication. This tutorial will teach you to program I2C protocol in ARM7 Microcontrollers.



This protocol uses 2 bidirectional open drain pins SDA and SCK for data communication. SCL( Serial Clock) is used to synchronize the data transfer between these  two chips and SDA to transfer the data to the devices. Therefore this protocol will allow us to reduce communication pins, package size and power consumption drastically. Each devices connected to the I2C line is known as nodes and the communication lines should be activated by means of a pull up resistor.Each data bit is transferred on the SDA line is synchronized by a high to low pulse clock on the SCL line. And the data line cannot change when the clock line is low.


I2C communications are initiated and terminated by means of a START and STOP Conditions. START condition is generated by a high to low change in SDA line when SCL is high wheras STOP condition is generated by low to high change in SDA line when SCL is low.


In I2C each slave device should possess an unique address which will be used by the master to address the slave and transmit the data to it. Usually the communication begins with start condition followed by the slave address of the slave and then comes the data.


I hope i have enough information to get you started with I2C, but i advise you to go through this article I2C bus specification to get a deeper understanding in its working and addressing schemes.


I2CONSET:  I2C control register is an 8 bit register which holds the holds the bits to control the I2C communication.

i2cconset regsiter

I2STAT: This is an 8 bit read only register which contains the key information and status of the I2C register. The bits in these registers must be checked periodically.

I2DAT: This register holds the data to be transmitted or received. This register can be accessed only when the SI bit is set.

I2ADR: This register  holds the slave mode address and used only when the I2C is set to the slave mode.

I2SCLH & I2SCLL: The values in these two registers will be used to set the data rate of the I2C communication. The bit frequency is given the formula

Bit Frequency = Fclk / (I2SCLH+I2SCLL)


I2C control clear register used to clear the controls of the I2C set using the I2CONSET register.



  1. Load the values in the I2SCLH and I2SCLL register to set the required bit frequency.
  2. Enable the I2EN bit in the I2CONSET register.
  3. Set the Acknowledgement bit and start bit in the I2CONSET register.
  4. Check for the status 0x08 in the I2STAT register which was defined in the datasheet.
  5. Transmit the slave address, followed by the databytes.
  6. Send the stop signal by activating the bit STO in the I2CONSET register.
  7. Disable the I2C by writing 1 to the bit I2EN in the I2CONCLR register,



  1. Slave address register should be loaded with the slave address.
  2. The I2EN bit must be set to enable the I2C function and AA bit must be set to acknowledge general address or call address.
  3. Receive or transmit data based on the direction bit received along with the slave address.

Kindly refer the datasheet for all modes of program, since the topic is vast and cannot be covered within this article. Also datasheet did an exceptional job in explaining the registers and modes of I2C operation. The link to download the datasheet is available below.


This sample code gives you an idea of programming I2C and transmitting bytes of data in master mode and the slave controller retrieves it and displays it in its Port1. This code was built using Keil uVision 4.
#define AA 2
#define SI 3
#define STO 4
#define STA 5
#define I2EN 6

void wait(unsigned int delay)

void i2c_init(void)                         //I2C initilaization
I2SCLH=100;                              //Bit frequency calculated value

int i2c_start()                              //I2C communication start
return 0;

int i2c_write(unsigned char buff)      //Data writing through I2C
return 0;

void i2c_stop(void)                   //Stop the I2C communication

int main(void)
VPBDIV=0x02;                   //Setting FCLK frequency
PINSEL0=1<<4|1<<6;       //Selecting I2C communication pins


  • The Bit rate frequency of the I2C must not exceed 400KHZ so make the calculation to follow this criteria.
  • Make Changes in the above code as stated in the steps for slave mode to obtain the code for slave controller.
  • Pull Up resistors should be used to activate the communication lines.
The following two tabs change content below.
Frank Donald

Frank Donald

Junior Network Engineer at Tata Communications
Frank Donald is an Electronics and Communication Engineer who loves building stuff in his free time. Video games, blogging and programming are the things he loves most
Frank Donald

Latest posts by Frank Donald (see all)

Ask your query

2 Comments on "How to program I2C protocol in ARM Microcontroller"

newest oldest most voted
Notify of

Hello, thanks for your examples. How to do i2c read ?

Hendrick Cheung
Hi, your project “How to program I2C protocol in ARM Microcontroller” sounds that my mini project can use this circuit. Let me briefly explain my mini project. I intend to build a lighting system which needs a controller to turn on/off LED individually. The controller is able to support 10 rows of extendable modules. Each row will be extended by each light module panel in which each panel support 10 LED lights – maximum 4 such module panels in each row. So, the controller will be able to support 400 lights all together in 10 rows. Is your project able… Read more »