You can't read them back immediately.
They go off-line during their write-cycle of about 10 ms.
That is, they don't respond to their I2C bus address.

So your code needs to either wait say 20ms, or
retry until the slave EEPROM responds.
The latter is better because it automatically waits as
long as is needed. No code-re-write if you change
EEPROM type.

I've been trying to do this for over a month. I've read all the
FAQs/ notes, etc and still can't get it to work.

As many have asked for usuable code and no-one has posted, either
there are _Very_ few people who can access I2C eeproms from a 16-84
or they are deliberately holding back because amateurs tend to use
these devices.

Or...People are reluctant to publish their source code on the internet
because they could receive alot of flack from their employer, who the
source code ultimately belongs to, atleast here anyway.

I can't send source code but I can give a few tips,
1)Don't rely on the MC app notes.
2)The eeprom manufacturer's data sheets should provide you with all the
info you need (timing diagrams, etc)
3)Be aware of the eeproms write time. (Usually around 10 ms)
4)Use the tris registers instead of the port registers to make the pins
go high and low
5)The rest of it is just bit banging.
6)Be patient and take it one step (bit) at a time.
7)The best advice is to forget i2c unless absolutely neccessary, use SPI
if you can!

> I've been trying to do this for over a month. I've read all the
> FAQs/ notes, etc and still can't get it to work.
>
> As many have asked for usuable code and no-one has posted, either
> there are _Very_ few people who can access I2C eeproms from a 16-84
> or they are deliberately holding back because amateurs tend to use
> these devices.
>
> I'm still trying.
> Tony.

> Or...People are reluctant to publish their source code on the internet
> because they could receive alot of flack from their employer, who the
> source code ultimately belongs to, atleast here anyway.
>
> I can't send source code but I can give a few tips,
> 1)Don't rely on the MC app notes.
> 4)Use the tris registers instead of the port registers to make the pins
> go high and low
> 7)The best advice is to forget i2c unless absolutely neccessary, use SPI
> if you can!

There's nothing wrong or particularly hard with using I2C; SPI can be a
little faster, but only if you're using a >4MHz CPU or one with built-in
SPI hardware; if you really need the speed in such a case, you could use
two or four EEPROM chips and read/write them in parallel (you'd have to
deal with data in 16 or 32 bit chunks, but that shouldn't be a problem).
Using two I2C EEPROMs would get you speed as good or better than SPI with
the same number of port pins.

Also, note that while I2C in the general case is quite complex the subset
of the protocol needed for one CPU "master" to talk to one or more EEPROM
chips is quite simple. Although I2C generally requires the clock to be
open-collector, and for the master to wait if slaves hold the clock low,
I have never seen an EEPROM chip which required bit-level waiting. I'd
therefore suggest treating the clock as a standard output, saving yourself
a pull-up resistor.

Additionally, the protocol will seem much simpler if you roll the "ack"
pulses into the start of the read-byte routine. I don't have the exact
sequence handy, but if you use the proper definitions for "start", "stop",
"read", and "write", you can forget all about acking (even on multi-byte
reads). This makes the main code MUCH easier to write and understand;
the only caveat is that after you send a byte the data line will be low
until you read a byte or send a stop/restart; if left in this state the
device will draw some extra power through the pullup.

We have all had trouble getting PIC to EEProm I2C code to work the first
time. It may be that others like me are relutant to post hand-tweaked
code. We know any post will generate even more questions. I have code
that works in production products. If you can use code that works for
32.7678KHz or 4 MHz or 8 MHz only let me know which one you could use. I
will have to extract the I2C stuff from the complete program and take
out the company sensitive information.

> ----------
> From: Tony Vilches[SMTP:spam_OUTtony-vilchesTakeThisOuTIDISCOVER.NET]
> Reply To: pic microcontroller discussion list
> Sent: Friday, January 23, 1998 10:33 AM
> To: .....PICLISTKILLspam@spam@MITVMA.MIT.EDU
> Subject: Re: I2C Read and Write a byte from EEPROM
>
> I've been trying to do this for over a month. I've read all the
> FAQs/ notes, etc and still can't get it to work.
>
> As many have asked for usuable code and no-one has posted, either
> there are _Very_ few people who can access I2C eeproms from a 16-84
> or they are deliberately holding back because amateurs tend to use
> these devices.
>
> I'm still trying.
> Tony.
>

> 1)Don't rely on the MC app notes.
> 2)The eeprom manufacturer's data sheets should provide you with all the
> info you need (timing diagrams, etc)
> 3)Be aware of the eeproms write time. (Usually around 10 ms)
> 4)Use the tris registers instead of the port registers to make the pins
> go high and low
> 5)The rest of it is just bit banging.
> 6)Be patient and take it one step (bit) at a time.
> 7)The best advice is to forget i2c unless absolutely neccessary, use SPI
> if you can!

I'd add to that,
8) Remember the read-modify-write thing. Reading another port pin can stuff
up your i2c.
9) Addresses wrap on different boundaries for eeprom read and writes.

> Does number 8 apply when you're changing the TRIS register, as opposed to
the
> actual data register?

Sorry. I was in a hurry at the time, otherwise I would have expanded on it.

Yes. It's a gotcha for when you are pin bashing I2C using the TRIS
register.
You write a 0 into the data latch and then swap the pin between input and
output using the TRIS register. When it's an output, it's outputting a 0.
When it's an input, the external pullup makes the bus a 1, also allowing
other things on the bus to pull it low if needed.
This bit you know.

The catch is when you execute an instruction that does a read-modify-write
on another port bit.
It reads the port as a byte (reading the pins) gets the bit it needs and
then writes the data byte back to the port (latches). If your bus was idle
at the time, the read gets a 1 from the bus and writes it into the data
latch. You wanted the 0 that you originally wrote.
If you don't fix it when you start to use the bus properly, you don't get
any 0's on the bus.
If you have an interrupt that can occur while you are using the i2c bus and
it tests a bit on the port, you'll pull out a lot of hair.

It is taking a bit longer to extract, comment and test the code and
circuit. I should finish it over the weekend (2/1/98). I will post the
Web / FTP site for downloading the PIC 16C84 / 24LCxx assembly code and
demo circuit schematic.