LPC2148 Interfacing with EEPROM using I2C

I2C Protocol

Introduction

I2C config

I2C is a two-wire synchronous serial communication protocol. SDA line is used for transferring data and SCK is used for transferring clock information. Every device connected to an I2C bus has a unique address. I2C communication protocol involves communication between a slave and a master. The device which initiates the communication and which provides the clock is referred to as a master device. The devices which receive the clock signal and receive/transmit data according to the clock signal is termed as a slave device. Each device on the bus is accessed using its slave address.

Communication process in an I2C bus or I2C Data Transfer

I2C Frame

i2c data transfer steps

START condition

STEP-1) First the MCU will issue a START condition. The devices connected to the bus will listen to the START condition and will stay ready to begin the communication process.
STEP-2) Then MCU will send the address of the device with which it needs to communicate. Master indicates the action to be performed with the device whether to read or write along with the address.
STEP-3) All devices connected to the bus will receive the address and will compare it with its own address. If the addresses match with each other, the device will send back an ACKNOWLEDGEMENT signal to the master device. If they                   don’t match they will simply wait for the bus to be released with a STOP condition.
STEP-4) Once the MCU sends the address and corresponding device acknowledges, the MCU can start transmitting or receiving data.
STEP-5) When the data transmission or reception is complete, the MCU will stop communicating by sending a STOP condition.

STOP condition

STEP-6) STOP condition indicates that the bus is released and it can be used by any other master (if any) connected to the I2C bus.

After a master generate a start condition I2C bus will solely belong to it. The bus will be freed only if the master generate a STOP condition. Any other master connected to the bus can access the bus after a STOP is identified on the bus.

If the master device which uses the bus needs to communicate with a different slave it should generate a RESTART. Instead if it tries to stop current communication and then start again it may lose access to the bus. RESTART is nothing but a start signal without a stop in the bus.

I2C Module in LPC2148

Features of I2C module
  • Two fast I2C buses (I2C0, I2C1)
  • Standard I2C compliant bus interfaces that may be configured as Master, Slave, or Master/Slave.
  • Arbitration between simultaneously transmitting masters without corruption of serial data on the bus.
  • Programmable clock to allow adjustment of multiple I2C data transfer rates.
    • Standard- 100 kbps
    • Fast- 400 kbps
    • High Speed- 3.4 Mbps
  • Bidirectional data transfer between masters and slaves.
  • Serial clock synchronization allows devices with different bit rates to communicate via one serial bus.
  • Serial clock synchronization can be used as a handshake mechanism to suspend and resume serial transfer.
  • The I2C bus may be used for test and diagnostic purposes.
Applications

Interfaces to external I2C standard parts

  • Serial RAMs
  • LCDs
  • Tone generators 

I2C Bus Configuration

i2c config

Pin Description
PinTypeDescriptionLPC2148 Pins
SDA0/1Input/OutputI2C Serial DataP0.3 and P0.14
SCL0/1Input/OutputI2C Serial ClockP0.2 and P0.11

I2C Registers

Summary of I2C Registers
Generic NameDescriptionAccessReset valueI2Cn Register name & Address
I2CONSETI2C Control Set Register. When a one is written to a bit of this register. the corresponding bit in the I2C control register is set. Writing a zero has no effect on the corresponding bit in the I2C control register. R/W0x00

I2C0CONSET - 0xE001 C000

I2C1CONSET - 0xE005 C000

I2STATI2C Status Register. During I2C operation, this register provides detailed status codes that allow software to determine the next action needed.RO0xF8

I2C0STAT - 0xE001 C0004

I2C1STAT - 0xE005 C004

I2DATI2C Data Register. During master or slave transmit mode. data to be transmitted is written to this register. During master or slave receive mode, data that has been received may be read from this register.R/W0x00

I2C0DAT - 0xE001 C008

I2C1DAT - 0xE005 C008

I2ADRI2C Slave Address Register. Contains the 7 bit slave address for operation of the I2C interface in slave mode. and is not used in master mode. The least significant bit determines whether a slave responds to the general call address.R/W0x00

I2C0ADR - 0xE001 C00C

I2C1ADR - 0xE005 C00C

I2CSCLHSCH Duty Cycle Register High Half Word. Determines the high time of the RC clock.R/W0x04

I2C0SCLH - 0xE001 C010

I2C1SCLH - 0xE005 C010

I2CSCLLSCL Duty Cycle Register Low Half Word. Determines the low time of the 12C clock. I2nSCLL and I2nSCLH together determine the clock frequency generated by an I2C master and certain times used in slave mode.R/W0x04

I2C0SCLL - 0xE001 C014

I2C1SCLL - 0xE005 C014

I2CONCLRI2C Control Clear Register. When a one is written to a bit of this register. the corresponding bit in the I2C control register is cleared. Writing a zero has no effect on the corresponding bit in the PC control register. WONA

I2C0CONCLR - 0xE001 C018

I2C1CONCLR - 0xE005 C018

I2CxCONSET Register

8-bit Register
Bits76543210
Symbol-I2CENSTASTOSIAA--
8 bits Explained
BitSymbolDescription
0-1--Reserved
2AA

Assert Acknowledge 

AA=1; request an acknowledge

3SI

I2C Serial Interrupt

SI=1; indicate state change

4STO

STOP

STO=1; sends stop condition

5STASTART
STA=1; sends START condition
6I2CENI2CEN=1; I2C interface enable
7-Reserved

I2CSCLH/I2CSCL Register

I2C frequency = [Pclk/(I2CSCLH + I2CSCLL)] .........Hz

where,

  • I2CSCLH: Count for Serial clock High time period
  • I2CSCL : Count for Serial clock low time period

EEPROM interfacing with LPC2148

Features of EEPROM IC(AT24C512)
  • The AT24C512 provides 524,288 bits of serial electrically erasable and programmableread only memory (EEPROM) organized as 65,536 words of 8 bits each. 
  • The device’scascadable feature allows up to four devices to share a common two-wire bus. 
  • The device is optimized for use in many industrial and commercial applications where low power and low-voltage operation are essential. 
  • The devices are available in space saving8-pin PDIP, 8-lead EIAJ SOIC, 8-lead JEDEC SOIC, 8-lead TSSOP, 8-lead Leadless Array (LAP), and 8-lead SAP packages. In addition, the entire family is availablein 2.7V (2.7V to 5.5V) and 1.8V (1.8V to 3.6V) versions.
PIN Diagram

eeprom

Interfacing Diagram

EEPROM_I2C_LPC2148

Algorithm for the Interfacing

1) Start

2) Initialize I2C bus interface

PINSEL0=0X10400050; //Configure P0.11-SCL1 & P0.14-SD1
I2CSCLH=150;
I2CSCLL=150;   //SET I2C frequency=[Pclk/(I2CSCLL+I2CSCH)]

3) Transmit the slave address(Page address,Page offset,No. of bytes)

4) Enable I2C bus interface

I2CCONSET=0X40;////I2CEN=1

5) Master (LPC2148) will transmit START signal

I2CCONSET=0X20;//STA=1

6) Transmit slave address(7-bit address,R/W=0; write operation)

7) Wait for acknowledgement

8) Tansmit Page address and page offset at which data is to be written

9) Wait for acknowledment

10) Transmit data using I2CDAT register

11) Wait for acknowledge

12) After successful transmission of data , master wil transmit STOP condition

I2CCONSET=0X10;//STO=1

13) Disable I2C interface

I2CCONCLR=0X40; //I2CENC=1

14) END 

Video Tutorial


Embedded C code

/**************************************************************************/
/* Project Name:- EEPROM Interfacing with LPC2148 using I2C Protocol module      */
/* Device:- LPC2148                          */
/* Compiler:- KeilUvision4                   */
/* Language:- Embedded  C*/
/* Visit www.wikinote.org for more Details   */
/********************************************************************************************/
#include <LPC214x.h>
#include <stdio.h>
#include "serial.h"

#define EEPROM_Addr 0xA0     //device address
#define I2Cwrite 0x00   //LSB bit 0 (write)
#define I2Cread  0x01   //LSB bit 1 (read)

#define I2C_ENABLE  1 << 6     //I2C Enable bit
#define I2C_START 1 << 5     //Start Bit
#define I2C_STOP  1 << 4     //Stop Bit
#define I2C_SI  1 << 3     //I2C interrupt flag
#define I2C_AACK   1 << 2     //assert ACK flag

unsigned char write_array[10] = {11,12,13,14,15,16,17,18,19,20};
unsigned char read_array[10];
unsigned char val[4];


void I2CInit(void)
{
 PINSEL0 |= 0x00000050;       //P0.2 -> SCL0  P0.3 -> SDA0

 I2C0CONCLR  = I2C_ENABLE | I2C_START | I2C_STOP | I2C_SI | I2C_AACK; //clear all the bits in CONTROL register

//set I2C clock to work at 100Khz
I2C0SCLH = 0x4B ;       //set the high time of i2c clock; (15mhz / 100khz / 2)
I2C0SCLL = 0x4B ;       //set the low time of i2c clock;

 I2C0CONSET = I2C_ENABLE ;     //enable the I2C Interface
}          


void I2CStart(void)          //Function to initiate a start condition on the I2C bus
{
unsigned int status;
I2C0CONCLR = (I2C_START | I2C_STOP | I2C_SI | I2C_AACK);  // clear all the bits in CONCLR register
I2C0CONSET = (I2C_ENABLE );            //Enable the I2C interface
I2C0CONSET = (I2C_START);           //set the STA bit
while(!((status=I2C0CONSET)& I2C_SI));      //wait till interrupt flag becomes set
}


void I2CStop(void)
{
unsigned int status;      
I2C0CONCLR = I2C_START | I2C_SI | I2C_AACK;    //clear all bits
I2C0CONSET = I2C_STOP;          //set STOP bit
}


void I2Csend(unsigned char data)
{    
unsigned int status;
I2C0DAT = data;
I2C0CONCLR = I2C_START | I2C_STOP ;      // clear start bit for next operation
I2C0CONCLR = I2C_SI;         // clear interrupt flag
while(!((status=I2C0CONSET)& I2C_SI));        //wait till interrupt flag becomes set
}

unsigned char I2Cget(void)
{
unsigned char data;
unsigned int status;

I2C0CONCLR = I2C_START | I2C_STOP;  
I2C0CONCLR = I2C_SI;         // clear interrupt flag    
I2C0CONSET = I2C_AACK;            // send ack to continue further data transfer
while(!((status=I2C0CONSET)& I2C_SI));     //wait till interrupt flag becomes set
data = I2C0DAT;
return data;
}


int main()
{
unsigned int i,j;
Uart0Init();       //initialize UART with 9600 baudrate
Uart0PutS("\r\nI2C EEPROM\r\n");
I2CInit();        //initialize I2C


 /* Write Sequence */
Uart0PutS("\r\n Writing Data.....\r\n");
I2CStart();       //Assert START
I2Csend(EEPROM_Addr | I2Cwrite);  //Device address with LSB bit 0
I2Csend(0x13);         //Address higher byte
I2Csend(0x49);      //Address lower byte
for(i=0;i<10;i++)
 I2Csend(write_array[i]);   //write the array to EEPROM
I2CStop();
     //Assert STOP
for(i=0;i<10;i++)
{
 sprintf(val,"%d",write_array[i]);    //display read data
Uart0PutS(val);
 Uart0PutS("\r\n");
}
/* Read Sequence */
Uart0PutS("\r\n Reading.....\r\n");
I2CStart();        //Assert START
I2Csend(EEPROM_Addr | I2Cwrite);  //Device address with LSB bit 0 (Dummy Write)
I2Csend(0x13);      //Address higher byte
I2Csend(0x49);       //Address lower byte
I2CStart();       //Assert Restart
I2Csend(EEPROM_Addr | I2Cread);  //Device address with LSB bit 1
for(i=0;i<10;i++)
 read_array[i] = I2Cget();   //Read EEPROM
I2CStop();       //Assert STOP


/*Display Write and Read Data*/

for(i=0;i<10;i++)
{
 sprintf(val,"%d",read_array[i]);    //display read data
Uart0PutS(val);
 Uart0PutS("\r\n");
}
while(1);      //stop here forever
return 0;
}
Download EEPROM Project : Click Here 

References

  • WikiNote Foundation
  • Prof. Sujit Wagh, Sinhgad's SKNCOE, Pune
Last modified: Tuesday, 4 February 2020, 3:59 PM