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 CCS Technical Support

Strange results when writing to EEPROM

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Gelio



Joined: 25 Aug 2014
Posts: 12

View user's profile Send private message

Strange results when writing to EEPROM
PostPosted: Tue Aug 23, 2016 8:05 am     Reply with quote

Hi all,
Trying to write to internal EEPROM of PIC18F4550.
Pickit2 correctly verifies and programs the chip.
After normal run I'm trying to save some bytes into 256-byte internal eeprom. And as a result i see garbage or incomplete data.
For example, I am writing
11 22 33 44 55 66 77 88
and as a result have:
11 22 33 44 3F FF 77 88
or
00 00 00 00 55 66 FF 88
or similar.
code looks like

Code:

#include <18F4550.h>

#FUSES NOPROTECT
#FUSES DEBUG
#FUSES ICSP1
#FUSES NOLPT1OSC
#FUSES NOPBADEN
#FUSES WDT32768
#FUSES NOPUT
#FUSES BORV27
#FUSES PLL3
#FUSES CPUDIV1
#FUSES IESO
#FUSES NOFCMEN
#FUSES XTPLL
#FUSES HSPLL

#use delay(clock=20000000)

void main()
{

  int16 i=0;
      for(i=0;i < 0x80; i++)
      {
         int8 b;
         b=*(int8*)i;
         write_eeprom(i,b);   
         delay(100);
      }
  while(1);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 8:20 am     Reply with quote

First thing is your clock will not be running at 20MHz.

Assuming you have a 20MHz crystal, then your fuses need to be:
Code:

#include <18F4550.h>

#FUSES NOPROTECT
#FUSES DEBUG
#FUSES ICSP1
#FUSES NOLPT1OSC
#FUSES NOPBADEN
#FUSES WDT32768
#FUSES NOPUT
#FUSES BORV27
#FUSES PLL5 //To give 4MHz to the USB PLL
#FUSES CPUDIV1
#FUSES IESO
#FUSES NOFCMEN
//#FUSES XTPLL
//#FUSES HSPLL
#fuses HS //To feed the CPU off the crystal, not the PLL

#use delay(clock=20000000)


Then the code you post will feed the data from the RAM at addresses 0 to 0x80 to the EEPROM. Since these addresses will contain things like the code scratch registers, the results will not be what you expect.

Code:

void main(void)
{
    int8 data[16] = {11,22,33,44,55,66,77,88,11,22,33,44,55,66,77,88};
    int16 i;
    int8 b;

    for(i=0; i < 16; i++) //since I've only set up a 16 entry array
    {
         b=*(int8 *) (i+data); //so we fetch data from the array
         //could use b=data[i];
         write_eeprom(i,b);   
         delay_cycles(100);
    }
    while(1);
}
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 7:50 pm     Reply with quote

I'm surprised it compiles with this...

delay(100);

unless I'm wrong it should be
delay_us(xx);
delay_ms(xx);
or
delay_cycles(xx);

another possible problem is that the WDT fuse isn't specifically set/reset. I'm unsure what the CCS 'default' is for that PIC, should be off....but.....

as well the 'debug' fuse is enabled , and 'debug' does change the setup so the PIC won't run as 'normal'....

Jay
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Tue Aug 23, 2016 11:21 pm     Reply with quote

I had same EEPROM problem until made:
Code:
#FUSES BORV45                   //Brownout reset at 4.5V

&
if using MPLAB, the programming should be in "Release" and not "Debug"
(As Jay mentioned)
Regarding
Code:
#use delay(clock=20000000)

The CCS wizard give me just:
Code:
#use delay(internal=20MHz)
#use delay(crystal=20MHz)
#use delay(oscillator=20MHz)


Best wishes
Joe
Gelio



Joined: 25 Aug 2014
Posts: 12

View user's profile Send private message

PostPosted: Wed Aug 24, 2016 12:31 am     Reply with quote

Thank you friends,
i tried the Ttelmah code fixed.
Compiled and burned.
it works first time.
Then extended array to 256 bytes and had zeros instead of normal data.
Now trying to reduce size to find max block.
Tried 16 byte array again:


Code:

void main(void)
{
    int8 data[16] =  {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0xAD};
    int8 data2[16] = {0xA1,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0xAD};
    int8 data3[16] = {0xA2,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0xAD};
    int16 i,j;
    int8 b;
     
     delay_cycles(200);
     delay_cycles(200);
     delay_cycles(200);
     delay_cycles(200);
     delay_cycles(200);
     
    for(i=0; i < 16; i++) //since I've only set up a 16 entry array
    {
         b=*(int8 *) (i+data); //so we fetch data from the array
         write_eeprom(i,b);   
         for(j=0; j < 10; j++);
    }
    while(1);

Result:
Code:
74   08   18   40   14   66   77   88   99   AA   BB   CC   DD   EE   FF   AD


Found some relation results from delay.
When i adding the delay cycles by simple cycle.
(for i=0;i<8192;i++) instead of delay_ms()
i have result:
Code:
A1   22   33   FF   FF   FF   FF   FF   FF   FF   FF   FF   FF   FF   FF   FF


Adding delay (for i=0;i<1000;i++)

Code:
A1   22   33   44   55   66   77   88   99   FF   FF   FF   FF   FF   FF   FF


The same code, but using array data, not data1

Code:
74   08   18   40   14   66   77   88   99   AA   BB   CC   DD   EE   FF   AD
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Aug 24, 2016 5:01 am     Reply with quote

2 comments....

1) using delay_cycles(xx) is ,well, kinda bad...I believe that it's solely based on the cpu clock you've chosen so that a program at 4MHz has a cycle of 1us, clock at 20 Mhz and it'll be 5 x faster. Now using delay_ms(1); will ALWAYS be a 1 ms delay regardless of the CPU speed.

2) writing to data eeprom can take 'up to 4ms' according to the datasheet electrical specs. I don't know how the CCS 'write_eeprom(x,y) is coded but if it doesn't wait 4ms or check a 'done flag', then the data may not be properly stored.

others who use the 4550 and KNOW how it all works may be able to explain if I'm write or wrong.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Wed Aug 24, 2016 7:57 am     Reply with quote

The write does wait.

Problem is that as you and I both spotted, the original code won't work, so what he is posting is not what he is using.
I used delay_cycles, just to give a 'point in time' where he could stop and look at the values with a watch, since assumed (as there is no output or testing shown), that he was testing in the debugger.

He then says that my code as posted worked, but then stopped when he changed it, and kept not working when he went back. Tells us I think that 1) he did not go exactly back, and 2) that something else is actually being done/happening.

There is also the question of compiler version.

He needs to post a small compilable program that actually shows what he is doing.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 24, 2016 9:19 am     Reply with quote

Since he has a problem related to a delay at the start of the program,
the first thing I would do is change the #fuses from NOPUT to PUT.
This will give a 65.6 ms initial delay before the PIC starts running code.

He also needs to post his current test program, and show the #fuses, etc.
Gelio



Joined: 25 Aug 2014
Posts: 12

View user's profile Send private message

PostPosted: Wed Aug 24, 2016 1:40 pm     Reply with quote

I tried to change the PIC unit to PIC18F2455 and set 4Mhz crystal.
Then implement similar code. All working ok.
So maybe my 4550 is somehow broken or has been burned a little.
Original crystal is 20Mhz. PICKIT2 writes code and eeprom ok, erases ok and verifies ok. Only when running execution in normal mode there is problem.
Will clear project and make again and post test here.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Wed Aug 24, 2016 3:07 pm     Reply with quote

PCM programmer wrote:
Since he has a problem related to a delay at the start of the program,
the first thing I would do is change the #fuses from NOPUT to PUT.
This will give a 65.6 ms initial delay before the PIC starts running code.

He also needs to post his current test program, and show the #fuses, etc.


One possibility is that he may be starting the first write before the power rail has actually got high enough to support EEPROM writes....
Gelio



Joined: 25 Aug 2014
Posts: 12

View user's profile Send private message

PostPosted: Wed Aug 24, 2016 6:16 pm     Reply with quote

At 2455 seems all ok...

Please, help to choose Baud rate for UART:
CONFIG1 Fuse is 0x8E22
Crystal is 20 000 000
How to calc correct Baud rate for #use232 string?
Thank you.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 12:35 am     Reply with quote

Er. You don't calculate anything. You specify the baud rate you want. The #USE does the calculations for you.
What baud rate you want to use is down to what the device you are attaching to wants to use, and what the actual data rates want/need to be?.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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