|
|
View previous topic :: View next topic |
Author |
Message |
Dean
Joined: 08 Jun 2017 Posts: 15
|
Write to EEPROM |
Posted: Fri Jul 14, 2017 3:14 pm |
|
|
Hi everyone
I have a problem when writing a variable to the PIC EEPROM. It writes the variable OK and reads it as well, but when the power is turned off and on again the value in EEPROM is reset again to FF.
I am using PIC18F4520
and the code for writing is
Code: |
void SaveTime()
{
write_eeprom(0x08,STime);
delay_ms(500);
lcd_gotoxy(1,2);
lcd_putc(" Time Saved ");
} |
The code for reading the variable is
Code: |
void ReadTime()
{
STime = read_eeprom(0x08 );
delay_ms(1000);
}
|
Anyone can help ? _________________ Find a way Or Make one . |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Fri Jul 14, 2017 4:30 pm |
|
|
Please post your complete program, one with fuses, header, and the simple read/write that you posted. It needs to be complete so we can cut/paste/compile/test.
Code 'snippets' don't tell the whole story.....
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat Jul 15, 2017 1:12 am |
|
|
In particular:
What compiler version?.
How is STime declared?.
Show the fuses. |
|
|
Dean
Joined: 08 Jun 2017 Posts: 15
|
|
Posted: Sat Jul 15, 2017 2:41 am |
|
|
Hi
The variable STime is declared as float
The fuses declaration in *.h file is:
Code: |
#include <18F4520.h>
#device ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#define PBL PIN_B7
#define PBC PIN_B6
#define PBR PIN_B5
#use delay(crystal=10000000)
|
Also, in the code I am including:
Code: |
#include <flex_lcd.c>
#include <internal_eeprom.c>
|
The program is too long, however this part is the only part which uses EEPROM.
I am getting the same problem when running on the proteus simulator or actually on the circuit, so may be we can exclude hardware reason.
Regarding the version, the manual says PIC C MCU Compiler June 2013, Nothing more as version number
Thanks _________________ Find a way Or Make one . |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Sat Jul 15, 2017 5:02 am |
|
|
OK, this is a simple software problem based in hardware...
Now that we know you have declared STime as a float, you should read the 'data definitions' section of the manual as well as the EEPROM memory section of the PIC datasheet.
A float variable ( floating point number) is represented in 4 bytes...
data stored in the EEPROM section of the PIC is ONE byte
I'm pretty sure the read/write eeprom functions ONLY use single bytes though without a small,complete prgram from you to test, it's hard to confirm. I don't have that PIC, so I can't test real hardware and there's NO way Proteus works correctly....
While PICs are small and powerful, you need to read the 400-600 pages of 'boring' information in the datasheet to understand the 'inside' operations of the PIC. Same goes for the compiler. It is very,very powerful BUT some operations are only possible with some PICs and/or compiler versions.
Jay |
|
|
Dean
Joined: 08 Jun 2017 Posts: 15
|
|
Posted: Sat Jul 15, 2017 6:24 am |
|
|
Thanks Jay
I will read that (boring) part of the manual for sure, but if the type of variable is the problem then the PIC will not save it in all cases. In this particular case the variable is saved and read again an again with the correct value as long as the PIC is powered. Once the PIC is turned OFF and ON again the value is reset to FF. If the variable is not written, or written improperly then this will appear when reading the variable without having to switch the power OFF then ON .
I've made a small test program with integer variable instead of float, and still get the same result. Here is the test program code.
Code: |
void TestDataSave() // test only not used in code
{
int value1 = 93 ;
int Rvalue1 = 0 ;
int Rvalue2 = 0 ;
Rvalue2 = Read_eeprom(0x0);
write_eeprom(0xFF ,value1) ;
delay_ms(5000) ;
Rvalue1 = Read_eeprom(0xFF);
lcd_gotoxy(1,2);
printf(lcd_putc, "%u\r\n" , Rvalue2) ; //value read before save in EEPROM
lcd_gotoxy(6,2);
printf(lcd_putc, "%u\r\n" , Rvalue1) ; //value read After save in EEPROM
} | same result nevertheless I am using integer. _________________ Find a way Or Make one . |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Sat Jul 15, 2017 6:46 am |
|
|
hmm HOW are you programming the PIC. Perhaps the IDE has some silly 'option' that tells the PIC to erase the EEPROM section of memory when power is applied ? MAybe there's a 'fuse' that needs to be set/cleared??
Heck, I'm tryng to think WHAT can cause the EEPROM to be erased as there's usually a lot of 'protection' to keep it secure.
All(most ?) EEPROM devices will be erased to 0xFF. I'd test ,read/display every byte of the EEPROM memory, to confirm it is the entire section and not just one byte.
I currently am testing an external EEPROM( 2432 series) and after a zillion power on/off cycles data is always retained so you do have an odd situation.
Jay |
|
|
Dean
Joined: 08 Jun 2017 Posts: 15
|
|
Posted: Sat Jul 15, 2017 7:56 am |
|
|
I am programming the PIC through PicKit2 writing the Hex code directly to the PIC, however I am using Proteus as well for simulation.
I will test it on an other PIC as 16F877 the most common PIC.
and I believe the story of the option of telling the PIC to erase EEPROM when power is applied, this thing needs checking.
I will try an other chip from different manufacturer as well.
Thanx Jay
Dean _________________ Find a way Or Make one . |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Sat Jul 15, 2017 8:11 am |
|
|
I read then re-read the EEPROM DATA section of the datasheet and there isn't an ' erase all bytes' command that I can see which leads me to believe that your PICkit2 software may be culprit.
I use the PICkit3 and checked, it does have an 'erase EEPROM' option but that's a one shot deal, ONLY during the programming of the PIC...NOT everytime the PIC powers up.
Dang curious though.
I'd still cut/compile/run a read all data eeprom and display program,just to confirm/deny it's one byte or ALL the bytes being reset.
Now if the 877 works fine...arrgh... that kinda eliminates the programmer doing it....pointing to the org PIC, though the datasheet doesn't have an 'erase all on powerup' command.....arrgh....
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat Jul 15, 2017 9:01 am |
|
|
Dean wrote: | Thanks Jay
I will read that (boring) part of the manual for sure, but if the type of variable is the problem then the PIC will not save it in all cases. In this particular case the variable is saved and read again an again with the correct value as long as the PIC is powered. Once the PIC is turned OFF and ON again the value is reset to FF. If the variable is not written, or written improperly then this will appear when reading the variable without having to switch the power OFF then ON.
I've made a small test program with integer variable instead of float, and still get the same result. Here is the test program code.
void TestDataSave() // test only not used in code
{
int value1 = 93 ;
int Rvalue1 = 0 ;
int Rvalue2 = 0 ;
Rvalue2 = Read_eeprom(0x0);
write_eeprom(0xFF ,value1) ;
delay_ms(5000) ;
Rvalue1 = Read_eeprom(0xFF);
lcd_gotoxy(1,2);
printf(lcd_putc, "%u\r\n" , Rvalue2) ; //value read before save in EEPROM
lcd_gotoxy(6,2);
printf(lcd_putc, "%u\r\n" , Rvalue1) ; //value read After save in EEPROM
}
same result nevertheless I am using integer |
It's not being saved and read when the chip is powered. It still contains the value that was put into it. You are being misled by thinking that the data can be saved like this.
When you compile a program, the .lst file has the compiler version at the top.
This is vital. It sounds as if your compiler may be quite old, so might well have a problem.
However, _look at the files you are including_. 'Internal_eeprom.c', contains routines to write and read a float value to eeprom, but you are using the byte write/read, that does not need this file....
write_float_eeprom, and read_float_eeprom.
So a basic test program:
Code: |
#include <18F4520.h>
#device ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#define PBL PIN_B7
#define PBC PIN_B6
#define PBR PIN_B5
#use delay(crystal=10000000)
#use rs232(UART1, baud=9600, errors)
#include <internal_eeprom.c>
void main(void)
{
float Test_val=1234.56;
write_float_eeprom(0, Test_val);
//Now clear the value
Test_val=0.0;
printf("Cleared value %7.2f \r", Test_val);
//Now read the value
Test_val=read_float_eeprom(0);
printf("Read value %7.2f \r", Test_val);
while (TRUE)
; //stop here
}
|
Just tested this on a 4520, using compiler 4.141, which dates to about 2013, and it runs fine. |
|
|
Dean
Joined: 08 Jun 2017 Posts: 15
|
|
Posted: Sat Jul 15, 2017 12:39 pm |
|
|
Hi Ttelmah
First I don't know where the version of the compiler is written on the software menus, there is no About option on the menu where the version is normally shown.
I did use the same program you sent and still have the same problem, the value is saved and read OK while the power is ON, but when switched OFF and on again the value is back to zero.
I had to include the flex driver for LCD
#include <flex_lcd.c>
and the initialize for LCD in the main() code as well.
lcd_init(); // Initialize LCD .
if that makes a difference.
The first code to write and read again the variable value looks like this
Code: | void main(void)
{
lcd_init(); // Initialize LCD .
float Test_val ;
Test_val =1234.56;
write_float_eeprom(0, Test_val); // save
Test_val=0.0; //Now clear the value
lcd_gotoxy(1,1);
printf(lcd_putc, "%2.2f", Test_val); // print float number
Test_val=read_float_eeprom(0); //Now read the value
lcd_gotoxy(8,1);
printf(lcd_putc, "%2.2f", Test_val); // print float number
while (TRUE)
; //stop here
} |
The second code to read only after power is OFF then NO excludes the write statement since I want to see if the saved value is still there, the code is:
Code: | void main(void)
{
lcd_init(); // Initialize LCD .
float Test_val ;
Test_val=read_float_eeprom(0); //Now read the value
lcd_gotoxy(8,1);
printf(lcd_putc, "%2.2f", Test_val); // print float number
while (TRUE)
; //stop here
} |
The variable read value is 0.00 after power toggled OFF/ON.
Well, I am almost sure its the compiler problem, the same problem also is
repeated with PIC16F877 and also on the simulator. Earlier I have used EEPROM memory with different compiler (MikroC Pro) and it worked alright, however the problem with Mikro C Pro is that the maximum Hex file size I can generate with it is 13 K only, and this is not enough for this application thats why I switched to CCS compiler.
Where is The Version Number is this thing CCS Compiler ? Can anyone tell me.
Thanx _________________ Find a way Or Make one . |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sat Jul 15, 2017 4:22 pm |
|
|
The version # is at the top of the LST file _________________ Google and Forum Search are some of your best tools!!!! |
|
|
Dean
Joined: 08 Jun 2017 Posts: 15
|
|
Posted: Sat Jul 15, 2017 5:11 pm |
|
|
Thanx dyeatman
Ttelmah, the version is - CCS PCH C Compiler, Version 5.008.
Apparently it's a new version !
Any new ideas ?
Currently, I am trying to understand the library internal_eeprom.c, but looks like this is unlikely to happen soon .
Is there any other way to save a variable (float) on a PIC controller through power OFF time, and get it back when power is ON, aside from using Write to EEPROM method ? I am trying to go around the problem rather solving it.
Any ideas ? _________________ Find a way Or Make one . |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Jul 16, 2017 12:04 am |
|
|
No, not new....
About 65 versions old.
5.008, was a _beta_ version of V5. The first fully working version was around 5.012. So, not a good start. At that time, 4.141, was the working compiler.
However I've just tested with 5.009, which is the nearest one to that which I have kept, and it merrily works exactly as 4.141.
Now, things that could be wrong:
How often do you write the EEPROM, how long have you been testing?.
It's possible that you have used up it's lives with your earlier tests. The EEPROM has a limited life. On your chip, you can write to it just 100000 times. Now this sounds huge, but if (for instance) you used it like RAM and saved a value every second, this would be used up in just over a day. You can actually use up the entire life in just 400 seconds if you write continuously.
Yes, people do save values to the EEPROM, but they use tricks to reduce the number of times the data is written. So (for instance), have an interrupt when the unit is switched 'off', and only write the data using an external capacitor to maintain the power, in the few hundred mSec before the unit actually goes off. Or only do an actual 'write', when data actually has changed, and only at long intervals. It is the act of writing that uses a 'life'.
The other likely problems are unfortunately rather 'ruled out' by the board having worked before (some supply problems can cause an EEPROM write to fail for example).
Losing when switched off, is actually a classic sign of an EEPROM failure.
Try an experiment:
Code: |
//write something to the EEPROM with your programmer
//add this line to your code, and program it into the chip.
#rom getenv("EEPROM_ADDRESS")={ 0,1,2,3}
|
Then switch everything off, disconnect the programmer etc., and then switch back on, and read the chip with the programmer, and look what is in the first four bytes of the EEPROM (details will depend on what programmer code you are using). If these are '0xFF', then I'm afraid you have worn out the chip's EEPROM...
The EEPROM needs to be thought of more like a filing cabinet in the basement, rather than as your working desktop. You put things away at the end of the day, or when you have finished a job, not all the time. If you want a memory that can be re-written indefinitely, then either design a system to keep the PIC powered (it doesn't take much if the chip is put to sleep and the oscillator stopped - a tiny battery can keep it running for years), or add an external memory (an external battery backed CMOS RAM, or an FRAM chip). |
|
|
Dean
Joined: 08 Jun 2017 Posts: 15
|
|
Posted: Sun Jul 16, 2017 1:51 am |
|
|
Well , Its not the chip , I used the very same chip , which is new , with a different compiler (MikroC Pro ) and it works fine !
But as I said in a previous message , MikroC Pro Compiler is limited to 13 K of Hex Code .
For CCS version , being a Beta version can cause strange things I guess .
Is 4.141 version available as free download on the internet ( being an old version ) ?
One More point Ttelmah , did you test on both commands ( Write_eeprom() , and Write_Float_eeprom () ) ?
Thanx
Dean _________________ Find a way Or Make one . |
|
|
|
|
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
|