how interface the external eeprom by using i2c

Status
Not open for further replies.

jaya krishna

Member level 1
Joined
May 10, 2012
Messages
41
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
India,coimbatore
Activity points
1,770
how to interface eeprom with pic controller 16/18f...by using i2c....i read the pdf file for i2c ... i dont know how to initial the i2c....how master send the correct address to slave...how to find that address..

i understand i2c what means ,start condition=sda is high to low with scl is high and
next is control byte it shows 1010 A0 A1 A2....it for read/write operation? then we wait for ACK from slave then we start the condition until the data is completely transfered and finally stop the i2c.


seriously i dont know how to assign the address of i2c(master) to slave....;like external eeprom..
ex:

i2c_start();
i2c_write(0xd0); // not understand//
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(0xd0);


pls any one help me...............

thank u
jai
 

Hi

0xd0 here the first 7 bits (From MSB) is the address of the slave in your case external eeprom and the 8th bit tell the slave whether it is going to write(0) or read(1) from the slave device.

in your code "address" is nothing but a internal address of the slave (external eeprom). After the program completed the "data" will present in "address" of external eeprom
 

hi arun,
ya thanks for reply, my doubt is how to find the 0xd0...in this 0x0d is used in real time clock i post the code below and also one more code that its used in extenal eeprom they used 0xA0....
PHP:
#ifndef EEPROM_SDA

#define EEPROM_SDA  PIN_B1
#define EEPROM_SCL  PIN_B0

#endif

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE   8192

void init_ext_eeprom()
{
   output_FLOAT(EEPROM_SCL);
   output_FLOAT(EEPROM_SDA);
}

void write_ext_eeprom(long int address, BYTE data)
{
   short int status;
   i2c_start();
   i2c_write(0xa0);  // how find this address//
   i2c_write((address>>8)&0x1f);// not understand//
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   i2c_start();
   status=i2c_write(0xa0);
   while(status==1)
   {
      i2c_start();
      status=i2c_write(0xa0);
   }
   i2c_stop();
}

BYTE read_ext_eeprom(long int address) {
   BYTE data;
   i2c_start();
   i2c_write(0xa0);    // how find this address //
   i2c_write((address>>8)&0x1f);
   i2c_write(address);
   i2c_start();
   i2c_write(0xa1);
   data=i2c_read(0);
   i2c_stop();
   return(data);
}
PHP:
#define DS1307_SDA  PIN_C4
#define DS1307_SCL  PIN_C3
#use i2c(master, sda=DS1307_SDA, scl=DS1307_SCL)




//==========================
// initial DS1307
//==========================
void init_DS1307()
{
   output_float(DS1307_SCL);
   output_float(DS1307_SDA);
}
//==========================
// write data one byte to
// DS1307
//==========================
void write_DS1307(byte address, BYTE data)
{
   short int status;
   i2c_start();
   i2c_write(0xd0);   // same this also how find this address // the above one is eeprom....
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   i2c_start();
   status=i2c_write(0xd0);
   while(status==1)
   {
      i2c_start();
      status=i2c_write(0xd0);
   }
}
//==========================
// read data one byte from DS1307
//==========================
BYTE read_DS1307(byte address)
{
   BYTE data;
   i2c_start();
   i2c_write(0xd0);
   i2c_write(address);
   i2c_start();
   i2c_write(0xd1);
   data=i2c_read(0);
   i2c_stop();
   return(data);
}
 

That 0xd0(Address of real time clock) or 0xa0(Address of external eeprom) is available in hardware datasheet.

I think RTC has only one address 0xd0.

But external eeprom have three pin A0,A1, and A2. using this pin you can change the address of the eeprom.

So that you can connect up to 8 external eeprom to the I2C bus at a time.

for example,

A2 = 0, A1 = 0, A0 = 0 ( the address of the device is 0xA0)
A2 = 0, A1 = 0, A0 = 1 ( the address of the device is 0xA2)
A2 = 0, A1 = 1, A0 = 0 ( the address of the device is 0xA4)
A2 = 0, A1 = 1, A0 = 1 ( the address of the device is 0xA6)
A2 = 1, A1 = 0, A0 = 0 ( the address of the device is 0xA8)
A2 = 1, A1 = 0, A0 = 1 ( the address of the device is 0xAa)
A2 = 1, A1 = 1, A0 = 0 ( the address of the device is 0xAc)
A2 = 1, A1 = 1, A0 = 1 ( the address of the device is 0xAe)

remember the 0th bit is R/W command bit.
 
hi arun,thanks for reply still i have doubt in i2c... can u clarify for me.... in below program first it start the i2c and write the address of external eeprom till this i m clear....
1.next two line address high byte and address low byte can u explain these two address (suppose address location is 0x00 assume)...why they use right shift>>8...

2. and ack part also pls it confusing me...
PHP:
void eeprom_write(int16 address, int data)
{
   i2c_start();               // Claim I2C BUS
   i2c_write(0x0a);      // Tell all I2C devices you are talking to EEPROM in WRITE MODE
   i2c_write(address>>8);     // Address High Byte (0x00 - 0x)
   i2c_write(address);        // Address Low Byte (0x00 - 0xAA)
   i2c_write(data);           // Data to write
   i2c_stop();                // Release BUS
   delay_ms(5);               // Let EEPROM Write Data (5ms from data sheet)
}

int eeprom_read(int16 address)
{
   i2c_start();               // Claim I2C BUS
   i2c_write(EEPROM_WR);      // Tell all I2C devices you are talking to EEPROM in WRITE MODE 
                              // (you are first writing to the EEPROM to set the address.  Later you will read)
                              
   i2c_write(address>>8);     // Address High Byte (0x00 - 0x
   i2c_write(address);        // Address Low Byte (0x00 - 0xAA)

   i2c_start();               // RESTART I2C BUS (necissary for microchip protocol)
   i2c_write(EEPROM_RD);      // Tell all I2C you are talking to EEPROM in READ MODE.
   read = i2c_read();         // Read in the data
   i2c_read(0);               // Read last byte with no ACK
   i2c_stop();                // release the bus
   return(read);
}
:-|
 

Hi,
I think the eeprom address 0xa0 not 0x0a.

and the variable address is declare as int16, so it is sixteen bit lenth.

I think the memory size of the eeprom is 8KB or 4 KB.

so the address size will be 16 bit (2 byte) lenght. so you have send the internal address in two part first high byte and then
the low byte.

if you want to write a data in location 0x0000(not 0x00) first send high byte 0x00 then low byte 0x00.

to give clear example

if you want to write a data in 0x0123 first send high byte 0x01 then low byte 0x23.
 

hi ARUN thanks..... can u have excute example for extenal eeprom by using i2c with proteus shematic .....it very help for me.....i try my program in proteus in not excute ,,,pls if u have post it,,,,,,...:|
 

This is a sample code for 8051 with external eeprom.

Because this controller does not have internal i2c peripheral. it written in software.
 

Attachments

  • sampleI2C.rar
    46.1 KB · Views: 130

hi arun,thanks for sample code....and my code run correctly first i write the data in eeprom and read the data in eeprom then i want to display the read data invirtual terminal...i attach the code and schematic pls tell where i mistake.....
PHP:
#include <18f4520.h>
#fuses HS,NOLVP,NOWDT,NOPROTECT
#use delay(clock=20000000)
#use i2c(MASTER, FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)    // use hardware i2c controller
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

void rand_write(int16 address, int data);

int rand_read(int16 address);
int8 EEPROM_WR = 0xA0;        // I2C Address. 1010 0000.  last bit = 0 => write command
                              // First Nibble is fixed as 1010 (internal address);
                              // Second Nibble is ABCD, 
                                 // A     =  Block Set
                                 // B, C  =  Hardware Addresses (Configured when you Wire the CHIP) 
                                 // D     =  (0 = write, 1 = read)
int8 EEPROM_RD = 0xA1;        // Same as EEPROM_WR except last bit = 1 for READ command

int read = 0;
int data = 128;
int16 loc;
int temp = 0;

void main()
{
   output_d(1);               // Output a 1 for reference to start
   delay_ms(1000);            // *Not necissary pause, just for debugging
   
   loc = 0x00;                // Random Location in memory
   temp = 15;                 // Byte to write
 //  printf("%d",temp);
   rand_write(loc, temp);     // Random Write: rand_write(address, data)

   output_d(255);
   delay_ms(1000);            // *Not necissary pause, just for visual purposes

   temp = 0;                  // Reset temp
   temp = rand_read(loc);     // Random Read: rand_read(address);
 //  printf("%d",read);
   output_d(temp);            // Output temp
 
   while(true)
   {
   }
}
void rand_write(int16 address, int data)
{
   i2c_start();               // Claim I2C BUS
   i2c_write(EEPROM_WR);      // Tell all I2C devices you are talking to EEPROM in WRITE MODE
   i2c_write(address>>8);     // Address High Byte (0x00 - 0x)
   i2c_write(address);        // Address Low Byte (0x00 - 0xAA)
   i2c_write(data);           // Data to write
   i2c_stop();                // Release BUS
   delay_ms(5)  ;               // Let EEPROM Write Data (5ms from data sheet)
}

int rand_read(int16 address)
{
   i2c_start();               // Claim I2C BUS
   i2c_write(EEPROM_WR);      // Tell all I2C devices you are talking to EEPROM in WRITE MODE 
                              // (you are first writing to the EEPROM to set the address.  Later you will read)
                              
   i2c_write(address>>8);     // Address High Byte (0x00 - 0x
   i2c_write(address);        // Address Low Byte (0x00 - 0xAA)

   i2c_start();               // RESTART I2C BUS (necissary for microchip protocol)
   i2c_write(EEPROM_RD);      // Tell all I2C you are talking to EEPROM in READ MODE.
   read = i2c_read();         // Read in the data
   i2c_read(0);               // Read last byte with no ACK
   i2c_stop();                // release the bus
   printf("%d",read);
   return(read);
}
**broken link removed**
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…