Advanced C EEPROM routines
For PIC microcontrollers
Background
EEPROM memory, as found in most (if not all) PIC devices, is an array of byte sized
cells. It is very simple to write char,
int and long variables to EEPROM,
since the individual bytes that make up the variable are easily separated through
the use of binary shifting. However, more complex variables, e.g.: float, double and structs can’t be handled
in the same was as char, int and
long variables, so a
different approach is needed. In order to store these variables,
the separate bytes that make up the variable need to be accessed and then stored
in EEPROM.
Implementation
The method I have used involves the use of pointers. Consider the following example:
float num=1.3245;
char *ptr=#
ptr now points
to the starting address of num. Because ptr is a pointer of type char
(1 byte), *ptr
will return the first byte that makes up num. *(ptr+1) will
return the second byte, *(ptr+2) will
return the third and so on. This way, the separate bytes the make
up the floating point number can be retrieved and then stored. Exactly
the same method can be used to retrieve the separate bytes in ANY variable or structure,
providing you know the size of the variable, in bytes.
Code
Here are code listings for functions to read/write a float and a generic object
to EEPROM.
typedef unsigned
char byte;
typedef unsigned
int word;
float Eeprom_Read_Float(word addr)
{
float result;
byte *ptr=&result;
byte i;
for (i=0;i<4;i++)
*(ptr++)=Eeprom_Read(addr++);
return result;
}
void Eeprom_Write_Float(word addr,float
data)
{
byte *ptr=&data;
byte i;
for (i=0;i<4;i++)
Eeprom_Write(addr++,*(ptr++));
}
void Eeprom_Write_Obj(word addr,void
*obj,byte size)
{
byte i,*ptr=(byte *)obj;
for (i=0;i<size;i++)
Eeprom_Write(addr++,*(ptr++));
}
void Eeprom_Read_Obj(word addr,void
*obj,byte size)
{
byte i,*ptr=obj;
for (i=0;i<size;i++)
*(ptr++)=Eeprom_Read(addr++);
}
The first two functions should be pretty self explanatory – Eeprom_Read_Float
will take an address in EEPROM then reconstruct and return the 4-byte floating point
value stored there. Eeprom_Write_Float will take a floating
point value and store it, starting at the specified address, in EEPROM.
Eeprom_Write_Float(0,num);
Eeprom_Write_Float(4,3.142);
buf=Eeprom_Read_Float(0); //buf = 1.32456
buf=Eeprom_Read_Float(4); //buf = 3.142
The last two functions, Eeprom_Write_Obj
and
Eeprom_Read_Obj can be used to read and write ANY variable/structure
to EEPROM. Both functions require you to specify an EEPROM address, a pointer to
the object to be written/read and the size of the object in bytes. The following examples illustrates the use of these functions:
my_struct var={5,10,"PICs are ace",1.23e-6};
my_struct buf;
Eeprom_Write_Obj(0,&var,sizeof(var));
//Write the structure to EEPROM
Eeprom_Read_Obj(0,&buf,sizeof(buf));
//buf now equals var
long num=184030000,lbuf;
Eeprom_Write_Obj(0,&num,sizeof(num));
//You can use these functions to read/write any variable type
Eeprom_Read_Obj(0,&lbuf,sizeof(lbuf));
//lbuf = 184030000
|