Jump to content

Recommended Posts

As part of my voyage of discovery I decided it would be nice to add I2C to my latest project! I've started out by experimenting with the example code from the forum - which all works as I guess it should. But I'm hoping someone far more conversant with I2C can help me with what should be a simple problem - but I just don't get it, and the EEPROM data sheets don't shed any light.

 

I wish to read/write to a 24C04 EEPROM using a 16F876 as master; the I2C routines in the example program read/write to the bottom 16 bytes OK, but so far I've not discovered how to access the rest of the EEPROM.

 

I'm obviously missing something that must be staring me in the face... please help!!

 

Thanks,

Mike W

Share this post


Link to post
Share on other sites

Mike,

 

Are you working in multibyte write or page write mode ?

 

Memory is in 8 byte pages. For multibyte you can write 4 bytes at a time which can cross a page boundary. You tell it the start address and write 4 consecutive bytes from there. If you cross a page boundary remember the write time doubles to 20ms as you have to write over 2 pages.

 

For page write you write 8 consecutive byte in a complete page. When you set the start address the lower 3 bits will be ignored and start internally = 000. If you write less than 8 bytes I assume it doesn't matter it keep the previous data. Don't hold me to that bit.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites
Mike,

 

Are you working in multibyte write or page write mode ?

 

Memory is in 8 byte pages. For multibyte you can write 4 bytes at a time which can cross a page boundary. You tell it the start address and write 4 consecutive bytes from there. If you cross a page boundary remember the write time doubles to 20ms as you have to write over 2 pages.

 

For page write you write 8 consecutive byte in a complete page. When you set the start address the lower 3 bits will be ignored and start internally = 000. If you write less than 8 bytes I assume it doesn't matter it keep the previous data. Don't hold me to that bit.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

Thanks Reynard. To be honest, I don't know!! I've simply taken the example code and tried to use it to understand how I2C works. For information, the read and write routines are as below:-

 

--------------------------------------------------------------------------------code----------------------------------------

////////////////////////////////////////////////////////////////////////////

// I2C Device constants

////////////////////////////////////////////////////////////////////////////

 

// define External I2C slave (Hardware) addresses

#define xee_slave 0xA0 // Base address of the EEPROM

 

////////////////////////////////////////////////////////////////////////////

// Read from the External EEPROM

////////////////////////////////////////////////////////////////////////////

// s is a pointer to the destination buffer to data read from the EEPROM

// HW_address is the hardware address of the i2c device

// ic2_addr is the target internal address within the External EEPROM

// count is the number of bytes to be read starting at i2c_addr

 

void read_XEE(char *s, char HW_address, unsigned short i2c_addr, unsigned short count)

{

short i;

 

i2c_start();

i2c_write(HW_address); // send XEE i2c address

i2c_write(i2c_addr >> 8); // send XEE internal HIGH address

i2c_write((char) i2c_addr & 0x00ff); // send XEE internal LOW address

i2c_restart(); // send i2c_restart

 

// sending XEE read command via i2c_write

i2c_write(HW_address | 0x01); // send device address + RD to I2C device

 

// XEE read loop

for (i=0;i<count-1;i++)

*s++ = i2c_read(0);

*s++ = i2c_read(1);

*s = 0;

i2c_stop();

}

 

////////////////////////////////////////////////////////////////////////////

// Write to the External EEPROM

////////////////////////////////////////////////////////////////////////////

// s is a pointer to the string to be written to the EEPROM

// HW_address is the hardware address of the i2c device

// ic2_addr is the target internal address within the External EEPROM

// count is the number of bytes to be written starting at i2c_addr

 

void write_XEE(char *s, char HW_address, unsigned short i2c_addr, unsigned short count)

{

short i;

 

i2c_start();

i2c_write(HW_address); // send XEE i2c address

i2c_write(i2c_addr >> 8); // send XEE internal HIGH address

i2c_write((char) i2c_addr & 0x00ff); // send XEE internal LOW address

 

// XEE write loop

for (i=0;i<count;i++)

i2c_write(*s++);

i2c_stop();

}

-----------------------------------------------------------------------------------------------------------------------------------

 

I have observed that increasing the value of 'count' beyond 16 causes the data to overwrite from address 0000, as the EEPROM data sheet says, but what it doesn't say to me is how the 'pointer' is increased beyond the 16byte boundary; the HIGH address and LOW address in the example seem to be inscrutable!

 

So, please, what is the significance of multibyte or page mode?

 

Thanks,

Mike W

Share this post


Link to post
Share on other sites

Mike

 

What address are you writing to? Your code snippet does not show the main() routine where this is done.

 

You send both a H/W address and an EEPROM internal address to the routine.

 

It could be the internal EEPROM address is near the end of the EEPROM page?

Share this post


Link to post
Share on other sites

Hi Mike,

 

You need to check the mode pin of your EEPROM (pin 7). Multibyte = 1, Page = 0.

 

You seem to be sending too many bytes. You only need device ID, memory address, then the data.

 

There are only 512 bytes in the chip arranged as 2 x 256 byte blocks. The block is selected using A8 which is contained in the device ID byte (Bit 1). The 8 remaining address bits (A7-A0) are in the next byte.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

Thanks for your assistance, Reynard. One assumption I have made is that all EEPROM's are the same, but different! The ones I have been using don't seem to have a page mode function, but a write protect on pin 7. I'd guess that the example code is intended for the multibyte mode; I didn't include all the code as it's already in the examples on the Sourceboost site.

I've found another example that is much simpler, and obviously uses single byte read/writes with the I2C routines included, and which I can understand!!

 

I'll pursue this for the moment and come back to the other one when I feel I have the time.

 

Again many thanks for your help.

 

Mike W

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...