View previous topic :: View next topic |
Author |
Message |
nidhimittalhada
Joined: 06 Sep 2010 Posts: 21
|
PIC18F4550 External eeprom i2c interfacing problem |
Posted: Fri Sep 10, 2010 9:51 am |
|
|
Hi all
I am a newbie just learning to communicate to ext eeprom.
my spec is
PIC18F4550 ...EEPROM is 24C04 is 4K EEPROM ...I2C interfacing .....
Code: |
#include<18F4550.h>
#use delay(clock=48000000)
#use i2c(master,sda=PIN_B0,scl=PIN_B1,FAST=100000)
void main()
{
int8 data;
output_high(PIN_B0);
output_low(PIN_B1);
i2c_start();
i2c_write(0xA2); //write device address 1010 + a2 a1 +P0 + W
i2c_write(0x01); //DATA word address
i2c_write(0x5A); ///write data on current location in address counter
i2c_stop();
delay_ms(100);
i2c_start();
i2c_write(0xA2); //write device address 1010 + a2 a1 +P0 + W
i2c_write(0x01); //DATA word address
//i2c_stop();
delay_ms(100);
i2c_start();
i2c_write(0xA3); //write device address 1010 + a2 a1 +P0 + W
data=i2c_read();
i2c_stop();
delay_ms(100);
} |
But no data is being read ..
pl help .. what can be the problem. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Sep 10, 2010 11:37 am |
|
|
If you're a newbie, don't use your own driver. Look in the CCS drivers
directory (it is installed with the compiler) and find the driver for your
eeprom. They have one for the 24LC02:
Quote: | c:\program files\picc\drivers\2402.c |
If you want to write your own driver, then read the eeprom data sheet
very carefully. The driver has to follow the data sheet exactly.
Make sure the connections are done correctly. This includes 4.7K pullups
on the SDA and SCL lines, and other connections. Example:
http://melabs.com/resources/pbpmanual/images/Image6.gif |
|
|
nidhimittalhada
Joined: 06 Sep 2010 Posts: 21
|
acknowledgment chking |
Posted: Sun Sep 12, 2010 10:05 am |
|
|
while(ack=i2c_write(0xA2));
Hi i have added the acknowledgment check as shown. Its not coming out of while loop. I have read the data sheet completely and followed it step by step. What can be the reason that acknowledgment not coming 0.
In circuit diagram came with my kit shows that address pins of EEPROM A2,A1,A0 all are hard wired to ground. As the EEPROM is 4K, it takes 9bits to address, so A0 is no connect.
Therefore taking device address 1st 4bits 1010 + 0(A2)0(A1)+1(MSB of 9bit address)+0(write) which makes it 0xA2.
Please help what can be probable reason for ack not coming 0. |
|
|
nidhimittalhada
Joined: 06 Sep 2010 Posts: 21
|
INTERNAL EEPROM |
Posted: Sun Sep 12, 2010 10:25 am |
|
|
Hi I have tested this program for internal eeprom and its working fine.
Code: |
void main()
{
int8 data;
init_lcd();
write_eeprom(1,'A');
data=read_eeprom(1);
lcd_data(data);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 12, 2010 2:24 pm |
|
|
Quote: |
I have tested this program for internal eeprom and its working fine. |
In most PICs, internal eeprom has a different command protocol than
external eeprom. It's not the same interface. The CCS functions are
high-level functions. They are read_eeprom() and write_eeprom().
The internal operations are hidden from you. For a 2404 driver, you
must write the internal operations code. (Unless you use a driver
that is already in existence).
Quote: |
i2c_write(0xA2); //write device address 1010 + a2 a1 +P0 +
i2c_write(0xA3); //write device address 1010 + a2 a1 +P0 +
|
You don't have to do this. You are explicitly hard-coding the block
address with 0xA2 and 0xA3. Look at the CCS 2404.c driver. It
automatically handles the formatting of the address (0 to 511) with
some shift and AND-OR operations. That's the correct way to do it.
Here's the CCS driver location:
Quote: |
c:\program files\picc\drivers\2404.c
|
Quote: |
output_high(PIN_B0);
output_low(PIN_B1);
|
CCS handles initializing the TRIS for the i2c library code. You should not
do it, and in fact, you're doing it wrong. Let CCS do it.
Quote: | i2c_start();
i2c_write(0xA2); //write device address 1010 + a2 a1 +P0 + W
i2c_write(0x01); //DATA word address
//i2c_stop();
delay_ms(100);
i2c_start();
i2c_write(0xA3); //write device address 1010 + a2 a1 +P0 + W
data=i2c_read();
i2c_stop(); |
Look closely at the CCS 2404.c, and the eeprom data sheet.
You will see some critical differences between your code and CCS.
Look at this figure in the eeprom data sheet:
Quote: | FIGURE 8-2: RANDOM READ |
Look carefully at the ACK or NO ACK bits. Look at the i2c_read()
function description in the CCS manual. How do you do an ACK or No Ack
in CCS ? All these details are very important. If you want to write your
own driver, you must understand everything down to the finest detail.
The Microchip 24LC04B data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/21708K.pdf |
|
|
nidhimittalhada
Joined: 06 Sep 2010 Posts: 21
|
i2c eeprom behaves unpredictably |
Posted: Tue Sep 14, 2010 3:02 am |
|
|
Hi
Thanks a lot for ur comments they were really helpful.
Quote: |
In most PICs, internal eeprom has a different command protocol than
external eeprom. It's not the same interface. The CCS functions are
high-level functions. They are read_eeprom() and write_eeprom().
The internal operations are hidden from you. For a 2404 driver, you
must write the internal operations code. (Unless you use a driver
that is already in existence).
|
Thanks for that .!!
Quote: |
"Look carefully at the ACK or NO ACK bits. Look at the i2c_read()
function description in the CCS manual. How do you do an ACK or No Ack
in CCS ? All these details are very important. If you want to write your
own driver, you must understand everything down to the finest detail."
|
For now ..we used the driver 2404.c as u suggested ....
Now RESULTS after using 2404.c and ex_extee.c(uses USART for user interface)
We copied reqd portion of ex_extee.c into our main program.
NOW
what we have got is
1)we write some character at an address into EEPROM and read it back ....
when it checks for readiness of eeprom in write_ext_eeprom ....
in while loop ...while(!ext_eeprom_ready().);
.it finds it ready ..we checked it ...
..
..
but when we read it back ...it in all cases reads back 0xFF...
that was output of running it .
2)Then we checked ack o/p of i2c_write(0xA0) function used after
Quote: |
while(!ext_eeprom_ready());
/*It means eeprom is ready here */
i2c_start();
ack=i2c_write(0xA0)..
..
..
..
i2c_stop();
if(ack!=0)
lcd_data('N');
|
to see if its writing successfully or not ...BUT ack is coming non zero ...(means write not successful )
WHY DOES eeprom GIVE UNREADINESS now ...but it has shown readiness once when it came out of while loop. hope i m clear !!
3)IF i read back 0xFF ....from that address ..
In that case it means that when i call read_ext_eeprom function ..then again It checks for readiness in while loop ..it comes out of loop ...as if it is ready ...
but reads this corrupt data ..which is 0xFF everytime.
4)NOW when i run it many times ...i found that ... in case of read_ext_eeprom ...it doesnt come out of while(!ext_eeprom_ready()); loop sometimes ...sometimes it comes out ....
similarly
for write_ext_eeprom () function also ....it doesnt come out of while(!ext_eeprom_ready()); loop sometimes ...sometimes it comes out ....
I just dont know which area i should target for problem because it behaves unpredictably ...sometime ready ...sometime not ready ....
kindly tell me ..which area shd i think can be a targetted as problmetic ..if i see results unpredictable....
can it be a clock problem? ...but clock is working 48Mhz well with RS232 ...
Nidhi |
|
|
nidhimittalhada
Joined: 06 Sep 2010 Posts: 21
|
|
Posted: Tue Sep 14, 2010 11:04 pm |
|
|
Quote: | Look closely at the CCS 2404.c, and the eeprom data sheet.
You will see some critical differences between your code and CCS.
Look at this figure in the eeprom data sheet:
Quote:
FIGURE 8-2: RANDOM READ
Look carefully at the ACK or NO ACK bits. Look at the i2c_read()
function description in the CCS manual. How do you do an ACK or No Ack
in CCS ? All these details are very important. If you want to write your
own driver, you must understand everything down to the finest detail.
|
Thanks a lot !!!
Our program has worked successfully. Yes we had to correct it to add NACK bit in i2c_read and the problem I mentioned in last mail regarding unpredictable ready state of eeprom.
I just found out that for pin B0 and Pin B1 there are two dip switches on my development board which were in wrong position for i2c to work.
We just corrected them and same program worked perfectly well.
We have written i2c eeprom driver successfully. Thanks a lot to you PCM Programmer. |
|
|
|