View previous topic :: View next topic |
Author |
Message |
Van
Joined: 02 Oct 2003 Posts: 5
|
can not get data from i2c_read() |
Posted: Thu Oct 02, 2003 3:10 pm |
|
|
Hi,
After I wrote to EEPROM, I would like to read it back, but I can not. What I got back is just 0xFF, here is the code:
void init_ext_eeprom()
{
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
BOOLEAN ext_eeprom_ready()
{
int ack;
i2c_start(); //if the write command is acknowledged
ack = i2c_write(0xa0); //then the device is ready
i2c_stop();
return !ack;
}
void write_ext_eeprom(long int address, BYTE data)
{
while(! ext_eeprom_ready() );
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(10);
}
int read_ext_eeprom(long int address)
{
int data, data1;
i2c_start();
i2c_write(0xa0);
i2c_write(hi(address) );
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data = i2c_read(0);
data1 = i2c_read();
i2c_stop();
return data;
}
void main()
{
int i, j;
init_ext_eeprom();
for(i = 0; i < 3; i++)
{
write_ext_eeprom(i, 10+i);
}
for(i = 0; i < 3; i++)
{
j = ext_read_eeprom(i); // I can not get back the data at address 0
}
}
After I wrote from address 0 to address 3, then I would like to read it back from address 0 to address 3. But I could not, Could you please help me to solve this?
Thank you for your time and your help
Van |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 02, 2003 3:28 pm |
|
|
int read_ext_eeprom(long int address)
{
int data, data1;
i2c_start();
i2c_write(0xa0);
i2c_write(hi(address) );
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data = i2c_read(0);
data1 = i2c_read();
i2c_stop();
return data;
}
------------------------------------------------------------------
Your code above is incorrect. You should only use the "0" parameter
with i2c_read() only on the last read. It should be like this:
data = i2c_read();
data1 = i2c_read(0);
Also, are you aware that you're only returning the first byte
of the two that you're reading ? |
|
|
Van
Joined: 02 Oct 2003 Posts: 5
|
|
Posted: Thu Oct 02, 2003 3:44 pm |
|
|
int read_ext_eeprom(long int address)
{
int data, data1;
i2c_start();
i2c_write(0xa0);
i2c_write(hi(address) );
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data = i2c_read();
i2c_stop();
return data;
}
------------------------------------------------------------------
PCM programmer!
I still could not get back to data from the EEPROM? As I am debugging those, the line
data = i2c_read()
return the value 0xFF
Could you please tell me why I can not read back a value that I wrote to?
Thank for your help
Van |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 02, 2003 4:06 pm |
|
|
For the last i2c read, you must use a "0" parameter. Example:
data = i2c_read(0); |
|
|
Van
Joined: 02 Oct 2003 Posts: 5
|
|
Posted: Thu Oct 02, 2003 4:41 pm |
|
|
That is it, the problem has sovled
Thank you, PCM programmmer, for your time and knowledge
Van |
|
|
Chill
Joined: 01 Jun 2010 Posts: 10
|
|
Posted: Thu Jun 03, 2010 8:54 am |
|
|
Hi all,
I have the I2C issue something like the above post.
The PIC18f65j10 works as a master to read the eeprom data back,
The code as below,
Code: |
i2c_start();
i2c_write(0xa0);
i2c_write(hi_address) );
i2c_write(low_address);
i2c_start();
i2c_write(0xa1);
data = i2c_read();
i2c_stop();
|
It gets the CORRECT data back, but the waveform shows that there is a invalid STOP bit after the data byte, although the master has issued the ACK bit followed by the data. The SDA line keep low always...
But when PIC sequencial read more than 2 bytes, no error found i.e. the data is correct and valid stop bit.
Code: |
i2c_start();
i2c_write(0xa0);
i2c_write(hi_address) );
i2c_write(low_address);
i2c_start();
i2c_write(0xa1);
data1 = i2c_read();
data2 = i2c_read();
data3 = i2c_read();
i2c_stop();
|
I really have no idea about it.
For the 1st case, when i rewrite the code like below,
data = i2c_read(0);
Adding 0 parameter, it does fix the issue.
Is it really the fix and why?
Thanks in advance. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 03, 2010 10:09 am |
|
|
It's not a fix, it's part of the i2c specification. Look on page 10, at
the last paragraph on the right side of the page. It says this:
Quote: |
7.2 Acknowledge
If a master-receiver is involved in a transfer, it must signal
the end of data to the slave-transmitter by not generating
an acknowledge on the last byte that was clocked out of
the slave.
|
This is what is called a "Not Acknowledge" or a NACK. In CCS, this is
done by using a zero parameter in the last call to i2c_read() in an i2c
transaction. To follow the specification you should do this:
Code: |
data1 = i2c_read();
data2 = i2c_read();
data3 = i2c_read(0); // Do a NACK on the last byte read
i2c_stop();
|
Here's the link for the i2c spec:
http://www.nxp.com/documents/other/39340011.pdf |
|
|
Chill
Joined: 01 Jun 2010 Posts: 10
|
|
Posted: Thu Jun 03, 2010 8:42 pm |
|
|
Got it. Thanks, PCM programmer. |
|
|
|