View previous topic :: View next topic |
Author |
Message |
hate
Joined: 29 Apr 2006 Posts: 6
|
eeprom never returns an ack |
Posted: Thu Feb 08, 2007 4:48 pm |
|
|
Hi;
My problem is the 24c512 eeprom chip I'm using, never returns an ack! I can read and even write the chip but cannot get an ack! So the pic16f877 I'm using stays forever in the 'while' loop below!
Code: |
#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)
void write_ext_eeprom(long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
do {
i2c_start();
status=i2c_write(0xa0);
} while(status==1);
}
|
'i2c_write' always returns '1'. But when I use the software I2C routines everything is ok. Am I missing something? Any ideas? Thnx!
Compiler v4.023
Regards... |
|
![](templates/subSilver/images/spacer.gif) |
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Thu Feb 08, 2007 5:57 pm |
|
|
why are you not using the driver given to you?
C:\Program Files\PICC\Drivers\24512.C |
|
![](templates/subSilver/images/spacer.gif) |
hate
Joined: 29 Apr 2006 Posts: 6
|
|
Posted: Fri Feb 09, 2007 2:54 am |
|
|
That's allready the driver I'm using with only a minor change with the while loop:
Code: |
i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
|
became a 'do while' loop:
Code: |
do {
i2c_start();
status=i2c_write(0xa0);
} while(status==1);
|
I also tried it without changing anything and same result: no ACK! Thnx for the suggestion anyway.
Regards... |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Feb 09, 2007 5:25 am |
|
|
Your change is not functionaly the same as the original. For example, if the call to i2c_start returns an error code, you will still continue and hence loop forever.
What happens when you revert to the original? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Fri Feb 09, 2007 6:12 am |
|
|
Actually, I have to disagree. The functionality is the same.
The first time into the loop, ther will be a start, and then a write, and then a test for NACK. It'll then test for ACK, and loop if this is not seen. This is exactly what the original code does.
I have seen problems with certain chips, and the hardware I2C, when sending repeated starts (which this code relies on). I found it to only work properly, if instead of sending a repeated start, I added a stop, and tried again. Try adding an I2C_STOP, and see if it starts working. If so, the original code would also have the same problem, but would work, because it is using software I2C, which appears not to have this fault.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
SLo Guest
|
|
Posted: Fri Feb 09, 2007 6:30 am |
|
|
I observed the same problem and my solution was to just wait 5mS as this is the longest specified write time. Not as efficient, but better than being stuck in the loop!
I will however try Ttelmahs fix as this may prove faster.
My function:
Code: |
i2c_start();
i2c_write(0xA0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(5);
|
|
|
![](templates/subSilver/images/spacer.gif) |
hate
Joined: 29 Apr 2006 Posts: 6
|
|
Posted: Fri Feb 09, 2007 7:18 am |
|
|
Hi;
I had tried SLo's suggestion but it hadn't worked. But Ttelmah's solution works, I added the' i2c_stop();' and everything works in hardware mode. Thnx all for your time!
Regards... |
|
![](templates/subSilver/images/spacer.gif) |
gokuden
Joined: 11 Feb 2007 Posts: 2
|
|
Posted: Sun Feb 11, 2007 10:35 am |
|
|
i have the same problem. Where i have to add i2c_stop();? on library? where? im test it on proteus! i changed the memory for a 25lc256 and now its`n sutck in the infinite while but, if a write a number "5" in the address "5". and i read the same address, it return me a 255, no a 5! i dont know what to do now!
void write_ext_eeprom(long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(5);
i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
} |
|
![](templates/subSilver/images/spacer.gif) |
hate
Joined: 29 Apr 2006 Posts: 6
|
|
Posted: Tue Feb 13, 2007 4:01 pm |
|
|
Here is where I added 'i2c_stop();':
Code: | void write_ext_eeprom(long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
do {
i2c_start();
status=i2c_write(0xa0);
i2c_stop(); //<--- I added the 'i2c_stop();' here!
} while(status==1);
}
|
In case you are using the default ccs driver, you have to add 2 'i2c_stop()' so be careful as my code differs from the original driver. Read all of the topic carefully!
Regards... |
|
![](templates/subSilver/images/spacer.gif) |
SLo Guest
|
|
Posted: Wed Feb 14, 2007 4:23 pm |
|
|
I tried Ttelmahs fix of including the I2C_Stop() and it worked a treat.
Out of interest, I added code to read the timer at the start & end of the write and compared the time taken using the delay_ms(5) and the loop waiting for ack. I appreciate that this may vary for other hardware, but out of interest I noted that the loop for ack code executed about 1.1mS faster than the dumb delay. Clearly a worthwhile saving.
Thanks Ttelmah. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Wed Feb 14, 2007 5:10 pm |
|
|
It might be worth making a 'note' of what chips need this fix. I posted, because I had met exactly this problem, and a friend had spent a lot of time and effort working out what on earth was happening. The same code without stops, worked fine on some chips, while the 'soft' I2C also works fine. I'm not sure if the problem is with particular PIC's, or particular EEPROM's. However at least it is a fix, and as said, it does save significant time over 'dumb' waiting...
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
gokuden
Joined: 11 Feb 2007 Posts: 2
|
|
Posted: Thu Apr 19, 2007 10:58 am |
|
|
hi. a have a problem with the writting process. I can record it only once. When I record it for the second time and I read the memory, it is only the first data |
|
![](templates/subSilver/images/spacer.gif) |
|