Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[51] EEPROM related problem.....

Status
Not open for further replies.

Sudhp

Member level 4
Member level 4
Joined
Oct 11, 2013
Messages
69
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
India
Visit site
Activity points
528
M working on a project having micro controller 89s52.
In this i have to store names up to 20.
m using 24c16 EEPROM for this....

HTML:
void Save_name()					
{
start();
send_byte(0xA0);
aknowledge();
switch(nam)
   {
        case 0: send_byte(0x00);break;
	case 1: send_byte(0x10);break;
	.
        .
        .
        case 15: send_byte(0xf0);break;
        case 16: send_byte(0x100);break;
        case 17: send_byte(0x110);break;
        case 18: send_byte(0x120);break;
        case 19: send_byte(0x130);break;
        case 20: send_byte(0x140);break;
   }
aknowledge();
for(i=1;i<16;i++)
{
send_byte(name[i]);aknowledge();
}
stop();
delay_ms(20);
}

void Read_name()
{
start();
send_byte(0xA0);
aknowledge();
switch(nam)
   {
        case 0: send_byte(0x00);break;
	case 1: send_byte(0x10);break;
	case 2: send_byte(0x20);break;
	.
        .
        .
        case 15: send_byte(0xf0);break;
        case 16: send_byte(0x100);break;
        case 17: send_byte(0x110);break;
        case 18: send_byte(0x120);break;
        case 19: send_byte(0x130);break;
        case 20: send_byte(0x140);break;
   }
aknowledge();
start();
send_byte(0xA1);
aknowledge();
for(i=1;i<16;i++)
{
name[i]=read_byte();aknowledge();
}
stop();
delay_ms(10);
}


The prblm is that the data of case 16 get overlap to ist position..
and 17th position with 2....and so on.

plz help me......
 

many EEPROMs wrap around to the start when you exceed the memory size
you have to put a test in your code so if you try to write past the end of the memory the write is ignored and you get an error message
 

We have tested it in segments....still do same thing
Whenever we write data at page address 100.....it's get overlapped with page address 00.....
 

Hi,


send_byte(0x140)

i don´t know this function.
but for me it seems it wants to send one byte. but value 0x140 are two bytes: 0x01; 0x40

Klaus
 

it's data word address for eeprom...
24c16 has 128 pages of 16 bytes each...
from page 00 to 7f0.
although frm the datasheet...
1-AT24C16A, 16K SERIAL EEPROM: Internally organized with 128 pages of 16 bytes
each, the 16K requires an 11-bit data word address for random word addressing.
2- A write operation requires an 8-bit data word address following the
device address word and acknowledgment.

Here it is mentioned in datasheet,it's require 8 bit data word address thn what data word address
should be for 17th address.

it's as per my knowledge. May be I have wrong assumptions...
If I am,Plz make me clear these thngs...
 

Hi,

Code:
it's data [B]word[/B] address for eeprom...

Yes, thats the point.

If you want to transmit a (16 bit) word addres with the (8 bit) send_byte function you have to split it in two function calls.

Instead of send_byte(0x140) you have to write:
Send_byte(0x01)
Send_byte(0×40)

***********
Refer to:

Figure. 6.1.3

Btw... google is your friend...

Klaus
 
  • Like
Reactions: Sudhp

    Sudhp

    Points: 2
    Helpful Answer Positive Rating
Post your send byte code, you are giving 11 bits for each address or 16 bits?
Me too think its only for 8 bits thats what your problem.
 

Hi,

Sorry i was wrong, at least a bit.

Correct is that you can not use send_byte(0x140) because "0x140" are 12 bits at least, and the send_byte() function is only for 8 bit.
But the eeprom has 11 address bits.

The solution is that the three upper address bits are mapped in the device_address.
eep.png
Usually the device_address is 0xA0 / 0xA1.

To access the upper memory area you have to do:
* divide the address into two bytes. 0x140 --> 0x01, 0x40
* shift the upper address one bit left: 0x01 --> 0x02 (this is because the most right bit in device address is for R/W bit.
* OR the upper address byte to the device_address: 0x02 OR 0xA0 --> 0xA2; take care of the RW bit.

Now perform your eeprom access as folows:
Code:
start();
send_byte(0x[B]xx[/B]);   *** use the OR-ed device address as seen below
aknowledge();
switch(nam)
   {
        case 0: send_byte(0x00);break;  *** here use "0xA0" as device address
	case 1: send_byte(0x10);break;
	.
        .
        .
        case 15: send_byte(0xf0);break;
        case 16: send_byte(0x00);break;   *** here use "0xA2" as device address
        case 17: send_byte(0x10);break;   *** mind the missing leading "1"
        case 18: send_byte(0x20);break;
        case 19: send_byte(0x30);break;
        case 20: send_byte(0x40);break;
   }
aknowledge();
for(i=1;i<16;i++)

... ialso find this addressing confusing.

Good luck

Klaus
 
  • Like
Reactions: Sudhp

    Sudhp

    Points: 2
    Helpful Answer Positive Rating
Then the exact code is

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void Save_name()                    
{
start();
send_byte(0xA0 | ( (nam & 0xF0) >> 3 ) );  // for read : send_byte(0xA1 | ( (nam & 0xF0) >> 3 ) )
aknowledge();
switch(nam)
   {
        case 0: send_byte(0x00);break;
    case 1: send_byte(0x10);break;
    .
        .
        .
        case 15: send_byte(0xf0);break;
        case 16: send_byte(0x00);break;
        case 17: send_byte(0x10);break;
        case 18: send_byte(0x20);break;
        case 19: send_byte(0x30);break;
        case 20: send_byte(0x40);break;
   }
aknowledge();
for(i=1;i<16;i++)
{
send_byte(name[i]);aknowledge();
}
stop();
delay_ms(20);
}

 
  • Like
Reactions: Sudhp

    Sudhp

    Points: 2
    Helpful Answer Positive Rating
Hi,

send_byte(0xA0 | ( (nam & 0xF0) >> 3 ) )
i don´t think so.

the complete memory address is (binary) "PPP AAAA AAAA" ( = 11 bits, 0...2047), where PPP are the upper three memory address bits.

The device_address is 0xA0 = "1010 000R" ... but manipulated it should be: "1010 PPPR" , where PPP are the upper three memory address bits. R is the RW bit

****
then nam is the memory address pointer 16 bits wide, valid: 0...2047
send_byte(0xA0 | ( (nam & 0x0700) >> 7 ) ) ; I´m not familiar with C ... i don´t know how to write that the reuslt is 8 bits wide. And take car of RW bit.
followed by:
send_byte((nam & 0x00FF) ) ; here also i don´t know how to write that the reuslt is 8 bits wide

********

Good luck

Klaus
 
  • Like
Reactions: Sudhp

    Sudhp

    Points: 2
    Helpful Answer Positive Rating
KlausST the nam variable here is not address of the memory I think its identifier of starting location.

In the #1 for nam = 16 he wants to send 0x100 but not just 0x0F
if he sends that way then all the name will be written on consecutive locations, so he can have the first letter of the names only.
Also the code look to be a bit bulky..


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Save_name()                    
{
  start();
 
  send_byte(0xA0 | ( (nam & 0x70) >> 3 ) );  // for read : send_byte(0xA1 | ( (nam & 0x70) >> 3 ) )
  aknowledge();
 
  send_byte((nam 0x0F) << 4);
  aknowledge();
 
  for(i=1;i<16;i++)
  {
    send_byte(name[i]);
    aknowledge();
  }
  stop();
  delay_ms(20);
}



This is all he wants

- - - Updated - - -

And also KlausST, you are right about the "& 0x70"
 

Venkadesh_M,
ya sir.......it is a variable to find the memory location to store data.....name
as...
for(i=1;i<16;i++)
{
name=read_byte();aknowledge();
}
 

Venkadesh_M,
ya sir.......it is a variable to find the memory location to store data.....name
as...
for(i=1;i<16;i++)
{
name=read_byte();aknowledge();
}


Try the code and let me know..
 
  • Like
Reactions: Sudhp

    Sudhp

    Points: 2
    Helpful Answer Positive Rating
Hi,

yes, now i see that nam is the counter for the variable.

in the end i hope we all are on the right way...and soon all will be as it should...


Klaus
 

Thank KlausST and Venkadehsh sir...
Actually I am trying this at my hardware....
Due to some reason i m away frm my home....that's why i can't try this right now...
I will reply u as soon as possible...
Thanks again for helping me so much.....
 

I am really sorry for late response....
Sometime circumstances are against u.....anyways

"Also the code look to be a bit bulky.."
may be sir ,my programming skills r too weak.

I have changed program as......
PHP:
void Save_name_(int lo)					
{
nam=lo;
start();
send_byte(0xA0 | ( (nam & 0x70) >> 3 ) );
aknowledge();
switch(nam)
   {
        case 0: send_byte(0x00);break;
        case 1: send_byte(0x10);break;
        .
        .
        case 15: send_byte(0xf0);break;
        case 16: send_byte(0x00);break;
        case 17: send_byte(0x10);break;
        case 18: send_byte(0x20);break;
		case 19: send_byte(0x30);break;
        case 20: send_byte(0x40);break;
   }
aknowledge();
for(i=1;i<16;i++)
{
send_byte(name[i]);aknowledge();
}
stop();
delay_ms(20);
}

void Read_name()
{
start();
send_byte(0xA0);
aknowledge();
switch(nam)
   {
        case 0: send_byte(0x00);break;
        case 1: send_byte(0x10);break;
        .
        .
        case 15: send_byte(0xf0);break;
        case 16: send_byte(0x00);break;
        case 17: send_byte(0x10);break;
        case 18: send_byte(0x20);break;
	case 19: send_byte(0x30);break;
        case 20: send_byte(0x40);break;
   }
aknowledge();
start();
send_byte(0xA1 | ( (nam & 0x70) >> 3 ) );
aknowledge();
for(i=1;i<16;i++)
{
name[i]=read_byte();aknowledge();
}
stop();
delay_ms(10);
}
But it's still doing same thing....data get overlapped

- - - Updated - - -

Post your send byte code, you are giving 11 bits for each address or 16 bits?
Me too think its only for 8 bits thats what your problem.

My 'Send byte code' and 'read byte code' r as....
PHP:
unsigned char read_byte()
{
 unsigned char reead;	
 unsigned int i;
 	sda=1;
	reead=0;
	for(i=0;i<8;i++)
	{
	reead=reead<<1;
	scl=1;
	_nop_();
	_nop_();
		if(sda==1)
		reead++;
		scl=0;
		}
		sda=0;
		return reead;}

void send_byte(unsigned char value)
{ 	
unsigned int i;
unsigned char send;
send=value;
for(i=0;i<8;i++)
{
sda=send/128;
send=send<<1;
scl=1;
_nop_();
_nop_();
scl=0;}
ack=sda;
sda=0;
}
 

Now your problem is reading data..

- - - Updated - - -

I am posting code for both reading and writing so just replace them ..

- - - Updated - - -


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void Save_name()                    
{
  start();
 
  send_byte(0xA0 | ( (nam & 0x70) >> 3 ) );  // for read : send_byte(0xA1 | ( (nam & 0x70) >> 3 ) )
  aknowledge();
 
  send_byte((nam 0x0F) << 4);
  aknowledge();
 
  for(i=1;i<16;i++)
  {
    send_byte(name[i]);
    aknowledge();
  }
  stop();
  delay_ms(20);
}
 
void Read_name()
{
start();
send_byte(0xA0 | ( (nam & 0x70) >> 3 ) );
aknowledge();
 
send_byte((nam 0x0F) << 4);
aknowledge();
 
start();
send_byte(0xA1 | ( (nam & 0x70) >> 3 ) );
aknowledge();
 
for(i=1;i<16;i++)
{
name[i]=read_byte();aknowledge();
}
stop();
delay_ms(10);
}



Replace Two functions completely..
 

Thank u so much sir...... :)
It's working now and data is not overlapping......
thank u....
and KlausST sir...u too....

- - - Updated - - -

Now your problem is reading data..

- - - Updated - - -

I am posting code for both reading and writing so just replace them ..

- - - Updated - - -


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void Save_name()                    
{
  start();
 
  send_byte(0xA0 | ( (nam & 0x70) >> 3 ) );  // for read : send_byte(0xA1 | ( (nam & 0x70) >> 3 ) )
  aknowledge();
 
  send_byte((nam 0x0F) << 4);
  aknowledge();
 
  for(i=1;i<16;i++)
  {
    send_byte(name[i]);
    aknowledge();
  }
  stop();
  delay_ms(20);
}
 
void Read_name()
{
start();
send_byte(0xA0 | ( (nam & 0x70) >> 3 ) );
aknowledge();
 
send_byte((nam 0x0F) << 4);
aknowledge();
 
start();
send_byte(0xA1 | ( (nam & 0x70) >> 3 ) );
aknowledge();
 
for(i=1;i<16;i++)
{
name[i]=read_byte();aknowledge();
}
stop();
delay_ms(10);
}



Replace Two functions completely..

It is working now.....but can u please explain me these line.....

send_byte(0xA0 | ( (nam & 0x70) >> 3 ) );
aknowledge();

send_byte((nam 0x0F) << 4);
aknowledge();
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top