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.

EEPROM Problem, able to write once and can not write again

Status
Not open for further replies.

ark5230

Advanced Member level 3
Joined
Jun 29, 2009
Messages
862
Helped
163
Reputation
324
Reaction score
140
Trophy points
1,323
Location
India
Activity points
6,187
I am using 24C64 EEPROM and able to write data on that only once.
When I attempt two write again, it fails.
Something serious is missing?
Is it to be erased for reuse, if so How??
Data sheets do not provide information on erasing eeprom.
Any suggestions please !!
I am using AVR Studio and AVRGCC.
 

You mean 24C64 serial EEPROM? It doesn't need data erasure.

May be an I2C protocol problem. Or performing a new write before the previous write has been executed, without ACK polling.
 
Thak you very much.
Now I will feagure out problem with the code.
 

I'm also have a problem about EEPROM.able to write once and can not write again.
i used this MikroC code and various PIC(16F6XX,16F8XX).

EEPROM_Write(0x02,0xAA); this line work.
EEPROM_Write(0x50,0x55); this line does not work. program is stuck.

pls can anyone help me?
 

According to the manual, mikroC EEPROM library is handling successive write operations, apparently it's using ACK polling but I don't have the compiler and can't check the generated code.

"program is stuck" should never happen, may be a side effect of a different problem.
 

The 24C64 doesn't need erase before write, it's done internally, but during the write process it will not ACK next transfers on IIC bus. The AVR needs to wait the time specified in the datasheet before trying next IIC transfer.
And reprorgarmming a cell that was written before takes longer than programming a cell that contains 0xFF (because of the additional time that the internal erase needs).
 
The AVR needs to wait the time specified in the datasheet before trying next IIC transfer.
Or implement ACK polling, which is the faster method.
 
this is my full codes.
===============================

Code dot - [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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
unsigned short i, DD0, DD1, DD2, DD3, DD4;
    char temp=0;
 
    unsigned short mask(unsigned short num) {
    switch (num) {
    case 0 : return 0x3F;
    case 1 : return 0x06;
    case 2 : return 0x5B;
    case 3 : return 0x4F;
    case 4 : return 0x66;
    case 5 : return 0x6D;
    case 6 : return 0x7D;
    case 7 : return 0x07;
    case 8 : return 0x7F;
    case 9 : return 0x6F;
    } //case end
    }
 
    unsigned int counter = 0;
    char second = 0;
    char hour = 12;
    char minute = 0;
void interrupt(){
 
         if(PIR1.TMR1IF){
            counter++;
            TMR1H = 0xD8;
            TMR1L = 0xF0;
            if(counter >= 25) {
                counter = 0;
                second++;
                EEPROM_Write(8,second);
                EEPROM_Write(4,minute);
                EEPROM_Write(2,hour);
                
                if (second >= 61){
                   second = 0;
                   minute++;
                  if (minute >= 60){
                     minute = 0;
                     hour++;
                    if (hour >= 13){
                       hour = 1;
                       second += 22;
                    }
                  }
                }
            }
            PIR1.TMR1IF = 0;
 
            if (temp > 0) temp--;
 
          }
    }
 
    void main() {
      CMCON |= 7;
      TRISB = 0b00000000;
      TRISA = 0b00110000;
      PORTB = 0x00;
      PORTA = 0x00;
 
      hour = EEPROM_Read(2);
      minute = EEPROM_Read(4);
 
      TMR1H = 0xD8;
      TMR1L = 0xF0;
 
       T1CON.T1CKPS1 = 1;
       T1CON.T1CKPS0 = 0;
       PIE1.TMR1IE = 1;
 
       INTCON.PEIE = 1;
       INTCON.GIE = 1;
 
       T1CON.TMR1ON = 1;
 
 
      do
      {
         if (PORTA.F4 == 1 && temp == 0)
         {
            PORTB.F7=0;
            if (PORTA.F4==0)
            {
             hour++;
             if (hour >= 13) hour = 1;
            }
            else
            {
             minute++;
             if (minute >= 60) minute = 0;
            }
 
            temp = 12;//doesn't get another button click until a half of second
         }
 
          DD0 = minute%10;
          DD0 = mask(DD0);
 
          DD1 = (minute/10);
          DD1 = mask(DD1);
 
          DD2 = hour%10;
          DD2 = mask(DD2);
 
          DD3 = (hour/10);
          DD3 = mask(DD3);
 
          if (counter > 13) DD4 = 1;
          else DD4 = 0;//blick the LED onece a second
 
          for (i = 0; i<=20; i++) {
              PORTB = DD0;
              PORTA = 1;
              delay_ms(3);
 
              PORTB = DD1;
              PORTA = 2;
              delay_ms(3);
 
              PORTB = DD2;
              PORTA = 4;
              delay_ms(3);
 
              if(DD3 != 63) {
                PORTB = DD3;
                PORTA = 8;
                delay_ms(3);
               }
                
              PORTB = 0x00;
              PORTA = 4;
              PORTB.F7 = DD4; // turn on/off blicking LED
              delay_ms(3);
 
          }
 
       } while(1);          // endless loop
    }



program is stuck at 'EEPROM_Write(4,minute);' line.
It is seen as program is running, but do not flow.
pls help me.
 
Last edited by a moderator:

this is my full codes.
===============================

Code dot - [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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
unsigned short i, DD0, DD1, DD2, DD3, DD4;
    char temp=0;
 
    unsigned short mask(unsigned short num) {
    switch (num) {
    case 0 : return 0x3F;
    case 1 : return 0x06;
    case 2 : return 0x5B;
    case 3 : return 0x4F;
    case 4 : return 0x66;
    case 5 : return 0x6D;
    case 6 : return 0x7D;
    case 7 : return 0x07;
    case 8 : return 0x7F;
    case 9 : return 0x6F;
    } //case end
    }
 
    unsigned int counter = 0;
    char second = 0;
    char hour = 12;
    char minute = 0;
void interrupt(){
 
         if(PIR1.TMR1IF){
            counter++;
            TMR1H = 0xD8;
            TMR1L = 0xF0;
            if(counter >= 25) {
                counter = 0;
                second++;
                EEPROM_Write(8,second);
                EEPROM_Write(4,minute);
                EEPROM_Write(2,hour);
                
                if (second >= 61){
                   second = 0;
                   minute++;
                  if (minute >= 60){
                     minute = 0;
                     hour++;
                    if (hour >= 13){
                       hour = 1;
                       second += 22;
                    }
                  }
                }
            }
            PIR1.TMR1IF = 0;
 
            if (temp > 0) temp--;
 
          }
    }
 
    void main() {
      CMCON |= 7;
      TRISB = 0b00000000;
      TRISA = 0b00110000;
      PORTB = 0x00;
      PORTA = 0x00;
 
      hour = EEPROM_Read(2);
      minute = EEPROM_Read(4);
 
      TMR1H = 0xD8;
      TMR1L = 0xF0;
 
       T1CON.T1CKPS1 = 1;
       T1CON.T1CKPS0 = 0;
       PIE1.TMR1IE = 1;
 
       INTCON.PEIE = 1;
       INTCON.GIE = 1;
 
       T1CON.TMR1ON = 1;
 
 
      do
      {
         if (PORTA.F4 == 1 && temp == 0)
         {
            PORTB.F7=0;
            if (PORTA.F4==0)
            {
             hour++;
             if (hour >= 13) hour = 1;
            }
            else
            {
             minute++;
             if (minute >= 60) minute = 0;
            }
 
            temp = 12;//doesn't get another button click until a half of second
         }
 
          DD0 = minute%10;
          DD0 = mask(DD0);
 
          DD1 = (minute/10);
          DD1 = mask(DD1);
 
          DD2 = hour%10;
          DD2 = mask(DD2);
 
          DD3 = (hour/10);
          DD3 = mask(DD3);
 
          if (counter > 13) DD4 = 1;
          else DD4 = 0;//blick the LED onece a second
 
          for (i = 0; i<=20; i++) {
              PORTB = DD0;
              PORTA = 1;
              delay_ms(3);
 
              PORTB = DD1;
              PORTA = 2;
              delay_ms(3);
 
              PORTB = DD2;
              PORTA = 4;
              delay_ms(3);
 
              if(DD3 != 63) {
                PORTB = DD3;
                PORTA = 8;
                delay_ms(3);
               }
                
              PORTB = 0x00;
              PORTA = 4;
              PORTB.F7 = DD4; // turn on/off blicking LED
              delay_ms(3);
 
          }
 
       } while(1);          // endless loop
    }



program is stuck at 'EEPROM_Write(4,minute);' line.
It is seen as program is running, but do not flow.
pls help me.

Can you show us the schematics and the EEPROM_Write routine.
 

Code:
u8 I2C_24C_EEPROM_Write_Page (u8 I2c_Address, u16 Mem_Address, char * pBuffer)
{
  u8 err=0;
  err=I2c_Start(EEPROM_I2Cx);
  if (err) return err;
  err=I2c_WriteAddress(EEPROM_I2Cx, I2c_Address);
  if (err) return err;
  I2c_WriteByte(EEPROM_I2Cx, (0xFF00&Mem_Address)>>8);
  I2c_WriteByte(EEPROM_I2Cx, 0xFF&Mem_Address);
  while (* pBuffer) I2c_WriteByte(EEPROM_I2Cx, * pBuffer++);
  I2c_Stop(EEPROM_I2Cx);
	delay_ms(10);
  return I2c_Success;
}

u8 I2C_24C_EEPROM_Write_Page_ByLen (u8 I2c_Address, u16 Mem_Address, char * pBuffer, u16 Len)
{
  u8 err;
	u8 PagesWritten = 0;
	u8 BytesToWrite;
	while (Len)
	{	
		if (Len<MaxPageSizeBytes) 
		{
			BytesToWrite = Len;
			Len = 0;
		}
		else 
		{
			BytesToWrite = MaxPageSizeBytes;
			PagesWritten++;
			Len-= MaxPageSizeBytes;
		}
		
		err=I2c_Start(EEPROM_I2Cx);
		if (err) return err;
		err=I2c_WriteAddress(EEPROM_I2Cx, I2c_Address);
		if (err) return err;
		I2c_WriteByte(EEPROM_I2Cx, (0xFF00&Mem_Address)>>8);
		I2c_WriteByte(EEPROM_I2Cx, 0x00FF&Mem_Address);
		while (BytesToWrite--) I2c_WriteByte(EEPROM_I2Cx, * pBuffer++);
		I2c_Stop(EEPROM_I2Cx);
		delay_ms(I2c_EEPROM_WriteTime_ms);
		
		Mem_Address+= MaxPageSizeBytes;
	}
  return I2c_Success;
}

u8 I2C_24C_EEPROM_Read_Byte (u8 I2c_Address, u16 Mem_Address, char * pBuffer)
{
  u8 err;
  err=I2c_Start(EEPROM_I2Cx);
  if (err) return err;
  err=I2c_WriteAddress(EEPROM_I2Cx, I2c_Address);
  if (err) return err;
  I2c_WriteByte(EEPROM_I2Cx, (0xFF00&Mem_Address)>>8);
  I2c_WriteByte(EEPROM_I2Cx, 0xFF&Mem_Address);
  I2c_ReStart(EEPROM_I2Cx);
  I2c_NACK(EEPROM_I2Cx);
  I2c_WriteAddress(EEPROM_I2Cx, I2c_Address|1);
  * pBuffer = I2c_ReadByte(EEPROM_I2Cx);
  I2c_Stop(EEPROM_I2Cx);
  I2c_ACK(EEPROM_I2Cx);
  return I2c_Success;
}

u8 I2C_24C_EEPROM_Read_Page (u8 I2c_Address, u16 Mem_Address, char * pBuffer, u8 pBufferSize)
{
  u8 err=0;
	I2c_ACK(EEPROM_I2Cx);
  err=I2c_Start(EEPROM_I2Cx);
  if (err) return err;
  err=I2c_WriteAddress(EEPROM_I2Cx, I2c_Address);
  if (err) return err;
  I2c_WriteByte(EEPROM_I2Cx, (0xFF00&Mem_Address)>>8);
  I2c_WriteByte(EEPROM_I2Cx, 0xFF&Mem_Address);
  I2c_ReStart(EEPROM_I2Cx);
  I2c_WriteAddress(EEPROM_I2Cx, I2c_Address|1);
  I2c_ACK(EEPROM_I2Cx);
  while (pBufferSize) 
  {
    * pBuffer++ = I2c_ReadByte(EEPROM_I2Cx);
    pBufferSize--;
    if (!pBufferSize) I2c_NACK(EEPROM_I2Cx);
  }
  I2c_Stop(EEPROM_I2Cx);
  
  return I2c_Success;  
}
 
FvM, Easyrider83 and all.
I was trying at all possible issues but The 24C64 was defective.
I had 3 of them, when I changed this every thing went fine.
I am writing about 8 K byte of data.
In every write process at least 12 bytes are written incorrect.
This is a new situation, every time the byte locations are different.
I am trying to figure out the problem but hope this will not be too difficult to fix.
Thanks to every body for the help.
Any suggestions regarding new situation are welcome.
 

@PLAAHemantha

If you use mikroC EEPROM routimes then you should use a delay of 20 ms minimum after each EEPROM read or write operation.
 

I suspect similar thing related to code, directly or through borrowed roitines from libraries and include filed.
delay is also to be taken seriously as pointed out.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top