CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

EEPROM read failure on 16F677 ?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
TopLoser
Guest







EEPROM read failure on 16F677 ?
PostPosted: Mon Apr 27, 2009 5:22 am     Reply with quote

Problem is very simple - I can write data to the internal EEPROM with write_eeprom and confirm it has been written correctly using the programmer. No problem with writes.

However, if I try and read the data back then the read_eeprom function only ever returns the last byte of data written.
Code:

write_eeprom(0,0x10);
write_eeprom(1,0x20);
write_eeprom(2,0x30);
write_eeprom(3,0x40);

printf("0 %X\n\r", read_eeprom(0));
printf("1 %X\n\r", read_eeprom(1));
printf("2 %X\n\r", read_eeprom(2));
printf("3 %X\n\r", read_eeprom(3));

The 4 debugging statements all print a data value of 0x40. If I change the order of the write_eeprom lines...
Code:

write_eeprom(3,0x40);
write_eeprom(2,0x30);
write_eeprom(1,0x20);
write_eeprom(0,0x10);

printf("0 %X\n\r", read_eeprom(0));
printf("1 %X\n\r", read_eeprom(1));
printf("2 %X\n\r", read_eeprom(2));
printf("3 %X\n\r", read_eeprom(3));

The 4 debugging statements all print a data value of 0x10.

What am I doing that's stupid?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 27, 2009 11:00 am     Reply with quote

Post a test program with those statements in main() and a while(1);
at the end. Post the #include statement for the PIC, and the #fuses,
and the #use delay() statement. It should compile with no errors.
Verify that it shows the problem and post it.

Also post your compiler version.
TopLoser
Guest







PostPosted: Mon Apr 27, 2009 12:16 pm     Reply with quote

Just tried this simple (and complete) program and it fails as described.

Compiler version is PCM 4.085


Code:
#include <16F677.H>

#fuses INTRC_IO , NOWDT , NOBROWNOUT, NOMCLR
#use delay(clock=4000000)
#use rs232(XMIT=PIN_B6, baud=57600)

int main()
{
   printf("Hello\n\r");

   for (;;) {

      delay_ms(1000);

      write_eeprom(0,0x10);
      write_eeprom(1,0x20);
      write_eeprom(2,0x30);
      write_eeprom(3,0x40);
      
      printf("0 %X\n\r", read_eeprom(0));
      printf("1 %X\n\r", read_eeprom(1));
      printf("2 %X\n\r", read_eeprom(2));
      printf("3 %X\n\r", read_eeprom(3));
   }

   return (0);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 27, 2009 1:20 pm     Reply with quote

I don't have a 16F677, but I do have a 16F690 which is in the same
family. I modified your program to use the hardware UART on the
16F690. I also modified it to just do one pass, and also I zeroed the
eeprom before I wrote data to it, to verify that the code was really
working. I got the result shown below, and it's correct. I compared the
eeprom writing code between the two .LST files and it's the same.
Quote:
Hello
0 00
1 00
2 00
3 00
0 10
1 20
2 30
3 40


Code:
#include <16F690.H>
#fuses INTRC_IO , NOWDT , NOBROWNOUT, NOMCLR
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_B7, rcv=PIN_B5, ERRORS)

void main()
{
 printf("Hello\n\r");

 write_eeprom(0,0);
 write_eeprom(1,0);
 write_eeprom(2,0);
 write_eeprom(3,0);
       
 printf("0 %X\n\r", read_eeprom(0));
 printf("1 %X\n\r", read_eeprom(1));
 printf("2 %X\n\r", read_eeprom(2));
 printf("3 %X\n\r", read_eeprom(3));

 write_eeprom(0,0x10);
 write_eeprom(1,0x20);
 write_eeprom(2,0x30);
 write_eeprom(3,0x40);
       
 printf("0 %X\n\r", read_eeprom(0));
 printf("1 %X\n\r", read_eeprom(1));
 printf("2 %X\n\r", read_eeprom(2));
 printf("3 %X\n\r", read_eeprom(3));

 while(1);
}
TopLoser
Guest







PostPosted: Mon Apr 27, 2009 5:10 pm     Reply with quote

We seem to have a problem here. I took your working (on a 16F690) code and compiled it and then programmed it into my 16F677. It's still broken for me.

Code:

#include <16F677.H>

#fuses INTRC_IO , NOWDT , NOBROWNOUT, NOMCLR
#use delay(clock=4000000)
#use rs232(XMIT=PIN_B6, baud=57600)

void main()
{
 printf("Hello\n\r");

 write_eeprom(0,0);
 write_eeprom(1,0);
 write_eeprom(2,0);
 write_eeprom(3,0);
       
 printf("0 %X\n\r", read_eeprom(0));
 printf("1 %X\n\r", read_eeprom(1));
 printf("2 %X\n\r", read_eeprom(2));
 printf("3 %X\n\r", read_eeprom(3));

 write_eeprom(0,0x10);
 write_eeprom(1,0x20);
 write_eeprom(2,0x30);
 write_eeprom(3,0x40);
       
 printf("0 %X\n\r", read_eeprom(0));
 printf("1 %X\n\r", read_eeprom(1));
 printf("2 %X\n\r", read_eeprom(2));
 printf("3 %X\n\r", read_eeprom(3));

 while(1);
}


Hyperterm output for the above code is

Quote:
Hello
0 00
1 00
2 00
3 00
0 40
1 40
2 40
3 40


My PicKit2 programmer reads the correct data from the EEPROM.

Something is broken, do you agree? I can repeat this on multiple samples of the hardware and get the same result.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 27, 2009 6:03 pm     Reply with quote

Just as a test, change your read operations to load the eeprom data into
a temporary variable. Then give that variable to printf. And also do it
in a loop, just to save typing. Example:
Code:

int8 c, i;

for(i = 0; i < 4; i++)
   {
    c = read_eeprom(i);
    printf("%X %X\n\r", i, c);
   }
Ttelmah
Guest







PostPosted: Tue Apr 28, 2009 2:13 am     Reply with quote

As a comment though, how long have you been experimenting with the write_eeprom function?. Have you tried at any time without the delay?.
The EEPROM, has a limited 'write' life. If you call a loop, that writes to the EEPROM, it can 'kill' the EEPROM, in under 10 minutes. With the one second delay in your example, this goes up to about a day, but if during your experimentation, you have run without the delay, then I'm afraid the answer may simply be that your EEPROM has been destroyed....

Best Wishes
TopLoser
Guest







PostPosted: Tue Apr 28, 2009 3:20 am     Reply with quote

I've never run the looping example for more than a couple of iterations, and I'm very sure the EEPROM is ok because I can always read back the written data with my programmer. It's just the read_eeprom function that seems to always returns an invalid result.
TopLoser
Guest







PostPosted: Tue Apr 28, 2009 3:35 am     Reply with quote

Last night I posted the Hyperterminal output from the board with the last test program in - the read_eeprom was returning the wrong value every time. This morning I turned the hardware on and this time Hyperterminal showed that read_eeeprom was returning the correct values. I hadn't changed anything overnight - it was the same hardware and I hadn't reprogrammed it. All I had done was leave it off overnight and then turn it on again.

To be honest this problem has been manifesting itself in this way for quite a few weeks. I thought I'd managed to isolate it with the simple test program but it looks like it's still there, but intermittent.

At this point I have no idea what the cause might be. Maybe there are some configuration bits not been set by the compiler reliably to set up for reads? The only thing I do know is that writes have ALWAYS worked and reads ALWAYS work when using the programmer.

Many thanks for people input so far.
Ttelmah
Guest







PostPosted: Tue Apr 28, 2009 4:18 am     Reply with quote

One possibility would be that the EEPROM write protection fuse (CPD) had got set. The programmer clears this, and resets it, allowing it to change the values, but then the code inside the chip, wouldn't be able to change the values....
Make sure you have NOCPD in the fuses.

Best Wishes
Guest








PostPosted: Tue Apr 28, 2009 7:01 am     Reply with quote

Thanks for the suggestion - I put the fuse in the list and it made no difference to the configuration word value.

This is starting to annoy me now, I might have to bypass the CCS functions and go directly to the hardware.
TopLoser
Guest







PostPosted: Thu Apr 30, 2009 3:25 am     Reply with quote

Right, back to this ongoing issue.

Below is a little program that uses write_eeprom to successfully write 4 data bytes to successive locations in the 16F677 eeprom. Writing never ever fails.
The same program then uses read_eeprom to read back those 4 locations and display them. I then read the same 4 locations using the hardware registers directly.

read_eeprom has a nasty habit of returning the value of the last byte that write_eeprom was passed as a parameter, regardless of the location! Sometimes it works though, it depsnds which way the wind is blowing. Going directly via the registers always returns the correct value from the requested location.

This occurs on multiple samples of the hardware.

Code:

#include <16F677.H>

#fuses INTRC_IO , NOWDT , NOBROWNOUT, NOMCLR, NOCPD
#use delay(clock=4000000)
#use rs232(XMIT=PIN_B6, baud=57600)

#BYTE EEADR = 0x10d
#byte EEDAT = 0x10c
#BYTE EECON1 = 0x18c

#BIT EEPGD = 0x18c.7
#BIT RD = 0x18c.0

void main()
{
    int8 c, i;

    write_eeprom(0,0x10);
    write_eeprom(1,0x20);
    write_eeprom(2,0x30);
    write_eeprom(3,0x40);

    printf("0 %X\n\r", read_eeprom(0));
    printf("1 %X\n\r", read_eeprom(1));
    printf("2 %X\n\r", read_eeprom(2));
    printf("3 %X\n\r", read_eeprom(3));

   // use suspect read_eeprom
    for(i=0; i<4; i++) {
      c = read_eeprom(i);
       printf("read_eeprom %X %X\n\r", i, c);
    }
 
   // now go to direct to the hardware
   for (i=0; i<4; i++) {
      EEADR=i;
      EEPGD=0;
      RD=1;
      c=EEDAT;
       printf("direct %X %X\n\r", i, c);
   }

    while(1);
}



Here is the debugging output from Hyperterminal

Code:

read_eeprom 00 40
read_eeprom 01 40
read_eeprom 02 40
read_eeprom 03 40
direct 00 10
direct 01 20
direct 02 30
direct 03 40
Ttelmah
Guest







PostPosted: Thu Apr 30, 2009 5:02 am     Reply with quote

Do two things.
Read the EEPROM into a variable, then print it.
Tell us what your compiler version is.

There was a documented problem with _printf_, some versions ago, where using certain functions directly inside the printf, led to corrupted values.

This is not a read_eeprom problem, but a fault in printf.

I'd suspect that this is what you are seeing.

Best Wishes
TopLoser
Guest







PostPosted: Thu Apr 30, 2009 6:21 am     Reply with quote

As stated earlier in this thread the compiler is version 4.085, only a few weeks old. I'd try it with 4.092 but that has an issue I don't even want to raise on this board.

In the code sample I gave I am actually reading the eeprom into a variable before printing it - somebody else suggested that a few days ago.

One of the reasons I'm having to try and sort this out is that the original application using read_eeprom was failing to read configuration data correctly from the eeprom - that code didn't have any printf at all.

However, I'm willing to try anything at the moment so how about dispensing with printf altogether....


Code:

#include <16F677.H>

#fuses INTRC_IO , NOWDT , NOBROWNOUT, NOMCLR, NOCPD
#use delay(clock=4000000)
#use rs232(XMIT=PIN_B6, baud=57600)

#BYTE EEADR = 0x10d
#byte EEDAT = 0x10c
#BYTE EECON1 = 0x18c

#BIT EEPGD = 0x18c.7
#BIT RD = 0x18c.0

void main()
{
    int8 c, i;

    write_eeprom(0,'A');
    write_eeprom(1,'B');
    write_eeprom(2,'C');
    write_eeprom(3,'D');

   // use suspect read_eeprom
    for(i=0; i<4; i++) {
      c = read_eeprom(i);
       putc('0'+i);
      putc(c);
      putc('\n');
      putc('\r');
    }
 
   // now go to direct to the hardware
   for (i=0; i<4; i++) {
      EEADR=i;
      EEPGD=0;
      RD=1;
      c=EEDAT;
       putc('0'+i);
      putc(c);
      putc('\n');
      putc('\r');
   }

    while(1);
}


Debugging output

Quote:

0D
1D
2D
3D
0A
1B
2C
3D


Annoying isn't it!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 30, 2009 12:17 pm     Reply with quote

Tell us about your hardware. Did you build the board yourself, or did
you buy it ? If you bought it, post the manufacturer and model number.
If you built it, describe the circuits and the board in detail. Is it a printed
circuit board ? If so, does it have a ground plane, or gridded ground
tracks ? What voltage regulator is used ? What's the Vdd voltage ?
Do you have a 0.1 uF (100 nF) ceramic capacitor very close to the PIC's
Vdd pin ? Etc.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group