View previous topic :: View next topic |
Author |
Message |
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
Using data or calibration factors from eeprom ? |
Posted: Fri Dec 03, 2010 7:30 pm |
|
|
Greetings - just wondering what the consensus was as to using data from eeprom
(on the chip) for calibration factors etc. Is it better to simply read the data from
the eeprom each time I need it or is it better at the start of main() to copy the
settings from eeprom into ram variables for use during the normal program (assume
I am not trying to save 10 bytes of RAM at this point ). Just curious what most
people do when they have their calibration factors stored in eeprom.
(18F14K22, compiler 4.114 )
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Last edited by gpsmikey on Tue Dec 07, 2010 7:10 pm; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Sat Dec 04, 2010 4:02 am |
|
|
For myself, read them into RAM.
Have a structure, containing all the configuration data, say something like:
Code: |
struct config_data {
int8 data_ok=0xAA;
int16 wash_time=200;
int16 adc_zero=40;
int16 adc_full=984;;
int16 output_4mA=166;
int16 output_20mA=900;
}
|
Then on boot, you read the first byte from the EEPROM. If it is 0xAA, you can assume the data _has_ been written at some time in the past, and read the whole block. If not, then you write the default values (which are already in the example shown), and call the config routine...
When updating the config. you again just write the whole block, when you leave the config routine.
The example given is for a simple instrument, which washes at intervals, and otherwise, reads a value from the ADC, adjusting it to a scale based upon the 'zero', and 'full' points, performs a linearisation, and puts the result out on a 4-20mA interface.
Obviously you would use values to suit what you want to do.
If you want real reliability on the RAM, then maintain a checksum byte in the config. Check this at intervals, and if it has gone wrong, you can read the data back.
It is much more convenient in any particular subroutine, to be able to use the variables 'by name', and reduces the risk of errors from addressing the wrong thing....
Best Wishes |
|
|
FFT
Joined: 07 Jul 2010 Posts: 92
|
|
Posted: Sat Dec 04, 2010 7:49 am |
|
|
@Ttelmah,
Could you explain how do you write and read that struct into/from eeprom by code?
What about if the struct has some float variables?
Thanks. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Sat Dec 04, 2010 10:09 am |
|
|
I use generic 'block' read write routines:
Code: |
#ifdef __PCH__
#bit GIE=0xFF2.7
#else
#bit GIE=0xB.7
#endif //No support for hardware interrupt priorities as written
//EPROM save/retrieve routines. Keep interrupts 'on', if enabled, for
//as much as possible
void EEPROM_GET(int *ptr,int num,int addr) {
int count;
int1 int_enabled;
int_enabled=GIE;
for (count=0;count<num;count++)
{
disable_interrupts(global);
ptr[count]=READ_EEPROM(addr+count);
if (int_enabled) enable_interrupts(global);
}
}
void EEPROM_PUT(int *ptr,int num,int addr) {
int count;
int1 int_enabled;
int_enabled=GIE;
for (count=0;count<num;count++)
{
disable_interrupts(global);
WRITE_EEPROM(addr+count,ptr[count]);
if (int_enabled) enable_interrupts(global);
}
}
|
Then to read the whole structure, from the bottom of the EEPROM
EEPROM_GET(&config_data,sizeof(config_data),0)
and EEPROM_PUT to write the structure.
Best Wishes |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Sat Dec 04, 2010 10:22 am |
|
|
Thanks for the info and the examples. I'll follow your example and read the cal factors into RAM and use them there. That is a good idea with the checksum/CRC for the data to maintain validity of the data (also verifies the data in EEPROM if you have a checksum there).
Thanks for the help.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Sat Dec 04, 2010 10:33 am |
|
|
and, as one final comment, float makes no difference. You just declare it as part of the structure, initialise it if you have a 'default' value, and it is handled the same as any other data type.
Best Wishes |
|
|
FFT
Joined: 07 Jul 2010 Posts: 92
|
|
Posted: Sat Dec 04, 2010 11:07 am |
|
|
Thanks so much for the idea.
if we want to read/write only the int16 output_4mA variable? Is there any trick for finding its address? |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Sat Dec 04, 2010 1:05 pm |
|
|
There's is one potential inconvenience. Every time new firmware is downloaded into Flash, data EEPROM may be blanked. If you don't want the EEPROM to be blanked, change one setting in the CCS Device Programmer (CCSload). Settings -> Read, Write, Erase operations -> uncheck Data EEPROM. _________________ Read the label, before opening a can of worms. |
|
|
FFT
Joined: 07 Jul 2010 Posts: 92
|
|
Posted: Sun Dec 05, 2010 2:34 pm |
|
|
@Ttelmah,
FFT wrote: | if we want to read/write only the int16 output_4mA variable? Is there any trick for finding its address? |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Dec 05, 2010 2:49 pm |
|
|
Quote: | Is there any trick for finding its address? |
Download the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Look in this section:
Quote: |
Built-in Functions
STANDARD
C MEMORY
|
Look for a function that will tell you the offset of an element in a structure.
Then write a test program, and test it. |
|
|
|