EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Storing Floating point numbers in serial eeprom

Started by Pravin June 24, 2006
Hi all,
I am using MSP430F149 and IAR Embedded WorkBench v4.30.

I have problem storing a floating point number in serial eeprom.

I have successfully seperated floating point number into 4 bytes.

unsigned char count,x[4];
float data;
data = 79.0;

for(count=0; count<4; count++)
x[count] = (*(((char*)&data)+count));

I am not able to combine the numbers so as to get the original float
number.
This fails,
for(count=0; count<4; count++)
(*((&data)+ count)) = x[count];

Anyhelp will be appreciated.

Thanks,
Pravin

Beginning Microcontrollers with the MSP430

Try something like this...

float my_variable; // long type also works ok
unsigned char *tmp_ptr;
unsigned int addr;

// Save variable
tmp_ptr = (unsigned char *)&my_variable;
addr = 0x0000;
save2eeprom(*tmp_ptr++,addr++); // var LSByte
save2eeprom(*tmp_ptr++,addr++)
save2eeprom(*tmp_ptr++,addr++)
save2eeprom(*tmp_ptr,addr); // var MSByte

// Load variable
tmp_ptr = (unsigned char *)&my_variable;
addr = 0x0000;
*tmp_ptr++ = readfromeeprom(addr++)
*tmp_ptr++ = readfromeeprom(addr++)
*tmp_ptr++ = readfromeeprom(addr++)
*tmp_ptr = readfromeeprom(addr)

Calin

Pravin wrote:
>
> Hi all,
> I am using MSP430F149 and IAR Embedded WorkBench v4.30.
>
> I have problem storing a floating point number in serial eeprom.
>
> I have successfully seperated floating point number into 4 bytes.
>
> unsigned char count,x[4];
> float data;
> data = 79.0;
>
> for(count=0; count<4; count++)
> x[count] = (*(((char*)&data)+count));
>
> I am not able to combine the numbers so as to get the original float
> number.
> This fails,
> for(count=0; count<4; count++)
> (*((&data)+ count)) = x[count];
>
> Anyhelp will be appreciated.
>
> Thanks,
> Pravin
>
>



The easiest way is to just create a union sort of like so :

typedef union {
float my_variable;
unsigned char tmp[4];
} float_split_t;

place it in ram :

float_split_t my_float;

loading/storing the float :

my_float.my_variable = 1.2345;

inserting/extracting the separate bytes use the 4 uchar members of the array:

my_float.tmp[0] , my_float.tmp[1] , my_float.tmp[2] , my_float.tmp[3]

The 4 bytes loading /storing can easily be rolled in a loop or something like that.
It's also easy to re-use the code on little/big endian MCus, just change the order in which you
treat the bytes, LSByte to MSByte..

> I am not able to combine the numbers so as to get the original float
> number.

After you read the bytes, store them back in the proper order into the union, and then read the
float member of the union, piece of cake.

HTH
-- Kris

-----Original Message-----
From: m... [mailto:m...] On Behalf Of Gabriel Calin
Sent: Sunday, 25 June 2006 4:16 AM
To: m...
Subject: Re: [msp430] Storing Floating point numbers in serial eeprom

Try something like this...

float my_variable; // long type also works ok
unsigned char *tmp_ptr;
unsigned int addr;

// Save variable
tmp_ptr = (unsigned char *)&my_variable;
addr = 0x0000;
save2eeprom(*tmp_ptr++,addr++); // var LSByte
save2eeprom(*tmp_ptr++,addr++)
save2eeprom(*tmp_ptr++,addr++)
save2eeprom(*tmp_ptr,addr); // var MSByte

// Load variable
tmp_ptr = (unsigned char *)&my_variable;
addr = 0x0000;
*tmp_ptr++ = readfromeeprom(addr++)
*tmp_ptr++ = readfromeeprom(addr++)
*tmp_ptr++ = readfromeeprom(addr++)
*tmp_ptr = readfromeeprom(addr)

Calin

Pravin wrote:
>
> Hi all,
> I am using MSP430F149 and IAR Embedded WorkBench v4.30.
>
> I have problem storing a floating point number in serial eeprom.
>
> I have successfully seperated floating point number into 4 bytes.
>
> unsigned char count,x[4];
> float data;
> data = 79.0;
>
> for(count=0; count<4; count++)
> x[count] = (*(((char*)&data)+count));
>
> I am not able to combine the numbers so as to get the original float
> number.
> This fails,
> for(count=0; count<4; count++)
> (*((&data)+ count)) = x[count];
>
> Anyhelp will be appreciated.
>
> Thanks,
> Pravin
>
>
Pravin wrote:
> Hi all,
> I am using MSP430F149 and IAR Embedded WorkBench v4.30.
>
> I have problem storing a floating point number in serial eeprom.
>
> I have successfully seperated floating point number into 4 bytes.
>
> unsigned char count,x[4];
> float data;
> data = 79.0;
>
> for(count=0; count<4; count++)
> x[count] = (*(((char*)&data)+count));
>
> I am not able to combine the numbers so as to get the original float
> number.
> This fails,
> for(count=0; count<4; count++)
> (*((&data)+ count)) = x[count];

You actually have two problems with your code:

1) Your assigning a "unsigned char" to a float, this means that C will
insert a cast from unsigned char (or rather, int) to float.

2) C will not perform byte arithmetic when you add a pointer and an
integer, say N. Instead, C steps N full objects forward, overwriting
whatever data is placed after "data".

You could fix the code by something like the following:

for(count=0; count<4; count++)
(*(((char*)&data)+count)) = x[count];
However, I would recommend that you should listen to the others in this
group and use the "union" method instead. It is earier to understand and
contains much less magic that could go wrong.

-- Anders Lindgren, IAR Systems
--
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.

Nice approach. Much better than using pointer :)

Calin

Microbit wrote:
>
> The easiest way is to just create a union sort of like so :
>
> typedef union {
> float my_variable;
> unsigned char tmp[4];
> } float_split_t;
>
> place it in ram :
>
> float_split_t my_float;
>
> loading/storing the float :
>
> my_float.my_variable = 1.2345;
>
> inserting/extracting the separate bytes use the 4 uchar members of the
> array:
>
> my_float.tmp[0] , my_float.tmp[1] , my_float.tmp[2] , my_float.tmp[3]
>
> The 4 bytes loading /storing can easily be rolled in a loop or
> something like that.
> It's also easy to re-use the code on little/big endian MCus, just
> change the order in which you
> treat the bytes, LSByte to MSByte..
>
> > I am not able to combine the numbers so as to get the original float
> > number.
>
> After you read the bytes, store them back in the proper order into the
> union, and then read the
> float member of the union, piece of cake.
>
> HTH
> -- Kris
>
> -----Original Message-----
> From: m...
> [mailto:m... ] On
> Behalf Of Gabriel Calin
> Sent: Sunday, 25 June 2006 4:16 AM
> To: m...
> Subject: Re: [msp430] Storing Floating point numbers in serial eeprom
>
> Try something like this...
>
> float my_variable; // long type also works ok
> unsigned char *tmp_ptr;
> unsigned int addr;
>
> // Save variable
> tmp_ptr = (unsigned char *)&my_variable;
> addr = 0x0000;
> save2eeprom(*tmp_ptr++,addr++); // var LSByte
> save2eeprom(*tmp_ptr++,addr++)
> save2eeprom(*tmp_ptr++,addr++)
> save2eeprom(*tmp_ptr,addr); // var MSByte
>
> // Load variable
> tmp_ptr = (unsigned char *)&my_variable;
> addr = 0x0000;
> *tmp_ptr++ = readfromeeprom(addr++)
> *tmp_ptr++ = readfromeeprom(addr++)
> *tmp_ptr++ = readfromeeprom(addr++)
> *tmp_ptr = readfromeeprom(addr)
>
> Calin
>
> Pravin wrote:
> >
> > Hi all,
> > I am using MSP430F149 and IAR Embedded WorkBench v4.30.
> >
> > I have problem storing a floating point number in serial eeprom.
> >
> > I have successfully seperated floating point number into 4 bytes.
> >
> > unsigned char count,x[4];
> > float data;
> > data = 79.0;
> >
> > for(count=0; count<4; count++)
> > x[count] = (*(((char*)&data)+count));
> >
> > I am not able to combine the numbers so as to get the original float
> > number.
> > This fails,
> > for(count=0; count<4; count++)
> > (*((&data)+ count)) = x[count];
> >
> > Anyhelp will be appreciated.
> >
> > Thanks,
> > Pravin
> >
> >
>
>
Hi,
Thanks all for your help.

Pravin


The 2024 Embedded Online Conference