View previous topic :: View next topic |
Author |
Message |
Guest
|
EXTERNAL EEPROM (24LC01) |
Posted: Thu Jun 16, 2005 8:51 pm |
|
|
I am learning PIC micro, I have a 24LC01 interface to PIC18F458 and I try to write a data to the eeprom and read it back and print it to
hyperterminal and the result is always 255, no matter what the data value
I use. What did I do wrong.
I need help....
Here is my code:
Code: | //******************************************************
//
// PURPOSE OF THIS FILE IS FOR LEARNING I2C IN PIC MICRO, NOT FOR COMMERCIAL
//
//
// To write data to or read data from an external EEPROM
// device,
// Example:
// I want to write the data of 0x55 to address 0x30 of EEPROM device, and then I
// want to read it back to see if it match what I was written to.
//
// To do above, the following sequence are require
//
// EEPROM Write
//
// 1. Send a START sequence ( i2c_start() )
// 2. Send the I2C address of the SLAVE with R/W bit low ( i2c_write(0xA0) )
// Note: A is 1010 for EEPROM Slave device address, 0 is the write R/W bit
// 3. Send the Internal Address you want to write to ( i2c_write(0x30) )
// 4. Send the Data byte (i2c_write(0x55) )
// 5. Send the Stop sequence ( i2c_stop() )
//
//
// EEPROM Read
//
// 1. Send Start sequence ( i2c_start() )
// 2. Send I2C address of the SLAVE with R/W bit low ( i2c_write(0xA0) )
// 3. Send the Internal Address of the EEPROM you want to read from
// example ( i2c_write(0x30) )
// 4. Send Start sequence again ( i2c_start() )
// 5. Send the I2C address of the SLAVE with R/W bit high ( i2c_write(0xA1) )
// 6. Read the byte ( data = i2c_read() )
// 7. Send the Stop sequence ( i2c_stop() )
//
//*******************************************************************************
#include <18F458.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(Master,fast,sda=PIN_C4, scl=PIN_C3, FORCE_HW)
void main()
{
byte data;
while(1)
{
// Write Data
i2c_start();
i2c_write(0xa0);
i2c_write(0x30);
i2c_write(0x55);
i2c_stop();
// Read Data
i2c_Start();
i2c_Write(0xA0);
i2c_Write(0x30);
i2c_Start();
i2c_Write(0xA1);
data = i2c_Read();
i2c_stop();
printf(" Data %u\n\r",data);
}
}
|
|
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Fri Jun 17, 2005 12:46 am |
|
|
Code: | void main()
{
byte data;
while(1)
{
// Write Data
i2c_start();
i2c_write(0xa0);
i2c_write(0x30);
i2c_write(0x55);
i2c_stop();
// Read Data
i2c_Start();
i2c_Write(0xA0);
i2c_Write(0x30);
i2c_Start();
i2c_Write(0xA1);
data = i2c_Read();
i2c_stop();
printf(" Data %u\n\r",data);
}
}
|
read the datasheet.
the write cycle time (parameter Twc) is at least 5ms. so, after any write you have to introduce a delay before you can read from the device. otherwise you are going to get invalid data.
see sections 4.1 and 5.0 of
http://ww1.microchip.com/downloads/en/DeviceDoc/21711D.pdf
for more detail and a library oriented approach, see
http://www.ccsinfo.com/forum/viewtopic.php?t=19526
and scroll down to where my 24Cxx routines are.
jds-pic |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 17, 2005 1:09 am |
|
|
But that will blow him away because it's too complicated for him.
If he had the full compiler, he would have the 2401.C file in
c:\Program Files\Picc\Drivers, but apparently he doesn't have
that, so he probably has the demo compiler.
Here's an old version of a CCS driver which should work for the 24LC01.
It's also very simple.
http://www.blitzlogic.com/2402_c.htm |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Fri Jun 17, 2005 1:13 am |
|
|
the hand holding continues.
cheers,
jds-pic |
|
|
Guest
|
|
Posted: Fri Jun 17, 2005 9:43 am |
|
|
I am learning so, I want to do it manually, I do not want to use the driver.
I have added the delay_ms(5); after each i2c_write() and it still does not work. I still get 255 on hyperterminal.
Any more suggestion?
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 17, 2005 10:32 am |
|
|
But asking us to debug your program for you, line by line, is not
really "doing it manually".
If we show you an example driver such as that Blitzlogic page,
you should study it. Compare your program to it.
If you look very closely at the read routine on that page and compare
it to your code, you will see there is a small, but important difference.
You should also study the CCS manual or Help file, and read about
how to use the i2c functions. |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Fri Jun 17, 2005 10:56 am |
|
|
Anonymous wrote: |
I still get 255 on hyperterminal.
Any more suggestion?
|
did you notice any differences between your i2c code and the code in the TWO example i2c drivers which were linked for you?
for example, when reading from the 24Cxx series you must no-ACK the last i2c_read...
is that how your code is written?
do you have the correct pull-ups on your i2c bus? does the SCL pin have a valid looking (~50% duty cycle) clock waveform on it when you perform i2c transactions? is the frequency of the clock in the ballpark of 400KHz? is the SDA pin actually toggling when you read and write data? does the specific 24LC01 that you are using support 400KHz i2c operation?
jds-pic |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 17, 2005 10:57 am |
|
|
But now he doesn't have to learn how to search code for details. |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Fri Jun 17, 2005 12:12 pm |
|
|
PCM programmer wrote: | But now he doesn't have to learn how to search code for details. |
the whole of the iceberg is not in sight yet:
Code: |
I have added the delay_ms(5); after each i2c_write()
|
jds-pic |
|
|
|