eeprom 24C64 read problem

Status
Not open for further replies.
yeah it is freely downloadable .. i will give you the link within 2 hrs.. have to get it from my friend.
or should i send you my hex file along with the c file??
 
This is what I've done in SDCC it works well.
Code:
#include<8052.h>
#include<stdio.h>


__sbit __at 0x96 scl;
__sbit __at 0x97 sda;

void I2Cinit()
	{
	P1 = 0xc0;	
	}

void aknowledge()	 //acknowledge condition
	{
	sda=0;
	scl=1;
	scl=0;
	sda=1;
	} 
	
void nack()	 	// not acknowledge condition
	{
	sda=1;
	scl=1;
	scl=0;
	scl=1;
	}
	
void start()	 //start condition
	{
	sda=1;
	scl=1;
	sda=0;
	scl=0;
	}
	
void rstart()	 //re-start condition
	{
	scl=0;
	sda=1;
	scl=1;
	sda=0;
	}
	
void stop()	 //stop condition
	{
	scl=0;
	sda=0;
	scl=1;
	sda=1;
	}
	
unsigned char read_byte()	//reading from EEPROM serially
	{
	unsigned int i;
	unsigned char reead=0;
	
	for(i=0;i<8;i++)
		{
		reead=reead<<1;
		scl=0;
		if(sda==1)
			reead++;
		scl=1;
		}
	scl=0;
	sda=1;
	return reead;	 //Returns 8 bit data here
	}
	
void send_byte(unsigned char value)	//send byte serially
	{ 
	unsigned int i;
	unsigned char send;
	send=value;
		
	for(i=0;i<8;i++)
		{
		scl=0;
		sda=send/128;	 //extracting MSB
		send=send<<1;	 //shiftng left
		scl=1;
		}
	scl=0;
	sda=1;
	}
	
void Write(unsigned char ch, int addr)
	{
	start();
	send_byte(0xA0);
	aknowledge();	
	send_byte((unsigned char)(addr>>8));
	aknowledge();
	send_byte((unsigned char)addr);
	aknowledge();	
	send_byte(ch);	//device address
	aknowledge();
	stop();
	}
		
int Read(int addr)
	{
	unsigned char ret;
	start();
	send_byte(0xA0);
	aknowledge();
	send_byte((unsigned char)(addr>>8));  // High addr
	aknowledge();
	send_byte((unsigned char)addr);  // low addr
	aknowledge();
	rstart();
	send_byte(0xA1);	//device read address
	aknowledge();
	ret=read_byte();
	nack();				// stop reading
	stop();
	return ret;
	}
void delayus(int x)
	{
	while(x--);		
	}
void delayms(int x)
	{
	while(x--)
		delayus(97);
	}
	
void main()
	{
	int x,j;
	I2Cinit();
	for(x=0;x<256;x++)
		{
		Write(x,x);
		delayms(5);
		}
	for(x=255;x>0;x--)
		j = Read(x);
		
	}
 
sir, in the Read function, instead of calling nack, can i call aknowledge() ?? and can you recheck the nack function??
void nack() // not acknowledge condition
{
sda=1;
scl=1;
scl=0;
scl=1; //this should be sda=0 ?????
}
 
Last edited:
i made following changes in the main function:
void main()
{
int x,j=0;
char k=48;
delay(3000);
lcd_ini();
lcd_command(0x80);
lcd_dataa("Sending data...");

delay(2400);
lcd_command(0x01);
lcd_ini();
lcd_command(0x80);
for(x=0;x<10;x++)
{
lcd_data(k+x);
Write(k+x,x);
delay(100);
}
lcd_command(0xC0);
lcd_dataa("Saved data...");

delay(2400);
lcd_command(0xC0);
for(x=0;x<16;x++)
{
j = Read(x);
lcd_data(k+j);
delay(100);
}
}

it shows following output
sending data...
0123456789
saved data...
<<<<====>>>>???/

how to correct this??
 
When reading from an eeprom.... YOU must generate a nack to signal you don't want any more data.... The ack is to inform the slave that you wish to continue

lcd_data(k+j); <-- when you saved the data you already added 48 '0' when you write to screen, you add it again.
 
sir this is my analysis:


1.
--> if i write...
unsigned char k=48,j=0;
and then (returning value from Read function is char type)

j = Read(x);

then it shows 10 complete blocks.

now when i write lcd_command(0x38) and lcd_command(0x0E) before for loop, it is showing the same problem of 4 characters repeated... and the characters it is showing are (chinese type) special characters...

--> if i write...
unsigned char k=48,j=0;
and then (returning value from Read function is char type)

j = Read(x);
lcd_data(j+k);

then it shows //////////

--> if i write...
unsigned char k=48,j=0;
and then (returning value from Read function is int type)

j = Read(x);

then it shows 10 complete blocks.

--> if i write...
unsigned char k=48,j=0;
and then (returning value from Read function is int type)

j = Read(x);
lcd_data(j+k);

then it shows //////////

--> if i write...
unsigned char k=48;
int j;
and then (returning value from Read function is char type)

j = Read(x);
lcd_data(j+k);

then it shows //////////

--> if i write...
unsigned char k=48;
int j;
and then (returning value from Read function is char type)

j = Read(x);

then it shows 10 complete blocks

--> if i write...
unsigned char k=48;
int j;
and then (returning value from Read function is int type)

j = Read(x);

then it shows 10 complete blocks

--> if i write...
unsigned char k=48;
int j;
and then (returning value from Read function is int type)

j = Read(x);
lcd_data(j+k);

then it shows //////////

2. can you recheck the nack function??
last line of it?
sda=1;
scl=1;
scl=0;
scl=1; //this should be sda=0 ?????

now how to bring the data 0123456789 on lcd???
 
I tested it on ISIS before I posted it to you..

The nack IS correct..... First check sda and scl = 1... then clock scl .... sda should be left high...

In ISIS you have the protocol analyser... It is correct, I have written 0 - 255 to an eeprom and recieved the same back..... What size eeprom do you have?

In your code you write ASCII 0 to 9.... This is done by adding 48 to each number... This is correct... your code is spot on.

But!!!!! you then retrieve the ascii code 48 thro 5... 8 then add 48 to display......so you are trying to display ascii 96 thro 106

You don't need to add 48 to the read function as the numbers are already in ascii....


I will test it again when I get home.... as the IDE is there..
 
Last edited:
my eeprom is 24C64 (64Kbit eeprom)

please explain how it is 5..8 ?? i rechecked the code and still not found 5 or 6,7,8. it is starting from x=0 only.

ok i deleted the 48 addition, but tell me, the return type from Read function should be char or int, and in j=Read(x), j should be char or int.
 
Sorry.. typo it should have read " 48 thro 58...."

the return type is irrelevant... unsigned char or int . Its possible to overrun a char.. so either unsigned or integer.

I'm testing it now..
 
Last edited:
sir i again wrote the code and this time only for read(), and it is still showing 10 blocks ...
 
OK so we need to look at your LCD routine..... Are you working on actual hardware? Have you the 4.7k pullups on the scl and sda lines?

What pins are your scl and sda on? they are best on the pins I used... you need open collector ideally..

Can I see your whole code? If you agree I'll send you my email address via PM.
 
1. lcd routine:

#include<reg51.h>

sbit rs=P3^2; // Register select pin
sbit rw=P3^3; // Read write pin
sbit en=P3^4; // Enable pin

void delay(unsigned int time) //delay function
{
int i,j;
for(i=0;i<time;i++)
for(j=0;j<100;j++);
}

void lcd_command(unsigned char comm) // function to send command to LCD
{
P2=comm;
en=1;
rs=0;
rw=0;
delay(1);
en=0;
}

void lcd_ini() //Function to inisialize the LCD
{
lcd_command(0x38); //8-bit 2 row LCD
lcd_command(0x0C); //Display on, cursor off
lcd_command(0x80); //force cursor to the beginning of 1st line
}

void lcd_data(unsigned char disp) // function to send only single data on LCD
{
P2=disp;
en=1;
rs=1;
rw=0;
delay(1);
en=0;
}

lcd_dataa(unsigned char *disp) // function to send strings to LCD
{
int x;
for(x=0;disp[x]!=0;x++)
{
lcd_data(disp[x]);
}
return;
}

2. yes i am working on actual hardware.
3. i have only one resistor of 20k between scl and Vcc. no pull ups. is this the problem?? and why do we need pull ups here? it was not mentioned in the datasheet!!!
4.scl pin is p1.1 sda pin is p1.0
5. yeah.. please send me your emial id.. i will send you my code... but only for memory part or complete???
my code is for attendance recording system so it has functions for taking date, taking attendance , hyperterminal coding etc. so should i send my complete code??
 
Can you move the scl and sda to P16 & 7? You need a pullup at least on the sda to 5V.... You do not need a 20k between the controller and the eeprom... Are they at the same voltage?

You don't need to send the code... I have your LCD routines for testing... That's enough for now.... I think your issue is on the hardware side...

(BTW) P1.6 and P1.7 are used for actual hardware I2C on some chips, that is why they are open collector.
 
nooo... we cant... we have already made the hardware and now we can not change it since it will have to be printed, etched, drilled, and soldered again..

but i can manage a pull up from sda to 5v. and thats must be 4.7k. isnt it??

then what about the 20k?? that is also a pullup for scl.. it should also be 4.7k??

yes. both are at 5v.

any other option than hardware change???
 
Ok... Try to replace the 20k with a much smaller resistance first... All the ports are tristate types.. P1.0 and P1.1 aren't open drain so I'm hoping that it should still work..

P1.6 & 7 are designed for this kind of use.
 
sir excuse me but i will tell about the result of this modification on 8th may because i am going out of town. but please read this post on 9th. i will surely write the result of the change ... and one more thing.. in the site you gave, in program 6_4, you have ANDed that address (low and high, during read and write) with 0ff . and now you haven't. so that is necessary or not??
 
It's not really necessary to and the address with 0xff..... it just makes sure that the top half of the word is 0 before the cast.... ( otherwise a - figure could emerge )

you could put it back in....

I'm busy testing several types of eeprom, so i'll let you know.
 
sir i changed the resistors and now it is showing <- arrow 10 times...
i just feel like breaking the circuit now....
 
Can you post me the schematic... so I can see the connections.


(this should have been a new post but...)
I've tested the code on 24lc64 and 24lc256. both work fine....

I think it's definitely hardware.
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…