Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Copying variables to External memory

Status
Not open for further replies.

scorrpeio

Full Member level 5
Full Member level 5
Joined
Dec 26, 2006
Messages
286
Helped
10
Reputation
20
Reaction score
9
Trophy points
1,298
Activity points
3,496
I have interfaced the nvram with MSP430 through I2C. Compiler used is CCS4.0

I have few variables in float, int and long type which I need to save to the nvram periodically and retrieve back after every power on.

Problem No. 1.
I tried to save the data to memory using unsigned char*. But, my compiler doesnt allow me to assign char pointer to float variable even typecasting.

Problem No. 2
I understand that the data copied to the nvram is in the form of unsigned char so I am worried, if I copy float type variable in the form of bytes to memory, I wont be able to retrive the original value of the variable from the memory.

Please let me know, if I have 10-20 variables in float, long and int format, how can I save them in the nvram such that when I retrieve them, I can restore their values back.
 

I2C memory doesn't know the concept of float, long and int. It only understands the concept of 8-bits of data at a particular memory location.
It is up to your own C code to translate a float, long or whatever into a stream of 8-bit bytes and to send them to the NVRAM in the sequence of your
choosing. When you read the NVRAM, of course you need to ensure that you read the NVRAM in a sequence which is compatible with the way you
originally wrote to the NVRAM.

There was a post recently about how to transfer variables in a data-set from a PC to memory. The concept is similar for the sake of understanding.
See here for that post. That post shows how a stream of bytes can be translated to unsigned char and signed char. It would also have worked for float.
 
you can copy your data into an unsigned char array using memcpy and then write the array to EEPROM, e.g.
Code:
   #include <string.h>
#include <stdio.h>

int main()
{
    unsigned char data[100]={0};
    int index=0;
    int i=10;
    float f=23.95f;
    double pi=3.1415926;
    // copy data
    memcpy(data, (void *)&i, sizeof(i));
    index=sizeof(i);
    memcpy(&data[index], (void *)&f, sizeof(f));
    index += sizeof(f);
    memcpy(&data[index], (void *)&pi, sizeof(pi));
    index+=sizeof(double);
    // write index bytes from data[0] starting at address 20 in EEPROM
    EEWriteBytes( 20, data, index);
    // check what is in data
    int j;
    float f1;
    double pi1;
    memcpy(&j, data, sizeof(int));
    memcpy(&f1, &data[sizeof(int)], sizeof(float));
    memcpy(&pi1, &data[sizeof(int)+sizeof(float)], sizeof(double));
    printf("%d %f %lf\n", j, f1, pi1);
}
when you read from EEPROM use memcpy to extract the data


However, it is very easy to get the offsets incorrect
I would tend to create structures for information to be written to EEPROM (or USB, Ethernet, etc), e.g.
Code:
typedef struct
 {
    int i;
    float f;
    double pi;
 } DATA;

int main()
{
    DATA d={10, 23.95f, 3.14159};
    // write structure starting at address 20 in EEPROM
    EEWriteBytes( 20, &d, sizeof(DATA));
 
Last edited:
Hello!

But, my compiler doesnt allow me to assign char pointer to float variable even typecasting.

I'm a little bit surprised about what you write. That would be against C rules.
I don't have CCS4 anymore and therefore cannot verify, but here is what I tried
in CCS5.

Code:
loat a, b;
char * aptr, * bptr;
int i;
//  Initialization
a = 1.2345;
b = 0;
aptr = (char *)(&a);  // Assign a char * to float variable a
bptr = (char *)(&b);  // Assign a char * to float variable b
// Copy b pointer to a pointer
for(i = 0 ; i < 4 ; ++i) {
    bptr[i] = aptr[i]
}

Set a breakpoint, and progress step by step. You will notice by looking at a and
b values in the CCS debugger, that there is no problem at all in casting a float
value as a char* array. In the for loop, observe the value of b. It will take various
values and ending with the same value as a.
By the way, using char or unsigned char doesn't matter.

Now, something a little bit out of scope, but generally float values should be avoided
if they are not native to one environment.
I'm aware that in some cases (e.g. IIR filters), using a few floats can save you a lot
of headaches, but usually everything can be done using integers from ADC (which yields
integers) to output. Everything is discrete, and doing floating point operation on
an MSP430 costs really a lot of computation cycles (if I remember correctly, a simple
floating point multiplication takes more than 300 clock cycles).

You might consider fixed point operation that are possible with the hardware multiplier
and which are extremely fast.

Dora.
 
Hello!



I'm a little bit surprised about what you write. That would be against C rules.
I don't have CCS4 anymore and therefore cannot verify, but here is what I tried
in CCS5.

Code:
loat a, b;
char * aptr, * bptr;
int i;
//  Initialization
a = 1.2345;
b = 0;
aptr = (char *)(&a);  // Assign a char * to float variable a
bptr = (char *)(&b);  // Assign a char * to float variable b
// Copy b pointer to a pointer
for(i = 0 ; i < 4 ; ++i) {
    bptr[i] = aptr[i]
}

Set a breakpoint, and progress step by step. You will notice by looking at a and
b values in the CCS debugger, that there is no problem at all in casting a float
value as a char* array. In the for loop, observe the value of b. It will take various
values and ending with the same value as a.
By the way, using char or unsigned char doesn't matter.

Now, something a little bit out of scope, but generally float values should be avoided
if they are not native to one environment.
I'm aware that in some cases (e.g. IIR filters), using a few floats can save you a lot
of headaches, but usually everything can be done using integers from ADC (which yields
integers) to output. Everything is discrete, and doing floating point operation on
an MSP430 costs really a lot of computation cycles (if I remember correctly, a simple
floating point multiplication takes more than 300 clock cycles).

You might consider fixed point operation that are possible with the hardware multiplier
and which are extremely fast.

Dora.



I was trying to achieve exactly this thing.
I could not do this one... (UINT8_T*)&floatVariable
Now, I implemented the above pointer and its working.
But, the question is, when I retrieve back the data, how to make it float again? Is there any library function available or using the same pointer casting I can do this?

Also, that was valuable information about the float. In my project I need to calculate values upto 3 or 4 decimal places so I had to use float. By the way, is it still possible to avoid float and use fixed point arithmatic for this? (The values are really important to me than the speed of execution because of project need)
 

I2C does not support the float type data storage...
one solution can be that you use floating point conversion to fixed point and then store the value. It works for DSPs, dnt know if it will work for MSP..
 
I have done it.
(char*)& float does my job.
 

I2C does not support the float type data storage...
Don't know what you mean? An I2C connected memory device doesn't care for the meaning of data stored to it. A sequence of bytes can represent any kind of data, e.g. integer, strings or float.
 

Hello!

Also, that was valuable information about the float. In my project I need to calculate values upto 3 or 4
decimal places so I had to use float. By the way, is it still possible to avoid float and use fixed point arithmatic
for this? (The values are really important to me than the speed of execution because of project need)

With a plain 16-bit integer, you have already 5 significant digits which should do the job.
Beside this, it all depends on what operation you want to perform, I cannot be more accurate
without knowing exactly what calculation it is.

Dora.
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top