Electrical – How to save a floating point value to a Microcontroller data Flash

armcortex-m0flashfloating pointisp

I'm trying to save some floating values to the Data flash of my Nuc220(ARM-M0 32 bit) Microcontroller using ISP procedure.

FMC->ISPCMD = FMC_ISPCMD_PROGRAM;   /* Set ISP Command Code */
FMC->ISPADR = 0x10000;              /* Set Target ROM Address. The address must be word alignment. */
FMC->ISPDAT = 22.5;                 /* Set Data to Program */
FMC->ISPTRG = 0x1;                  /* Trigger to start ISP procedure */
__ISB();                            /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG);                 /* Waiting for ISP Done */


FMC->ISPCMD = FMC_ISPCMD_READ; /* Set ISP Command Code */
FMC->ISPADR = 0x10000;         /* Set Target ROM Address. The address must be word alignment. */
FMC->ISPTRG = 0x1;             /* Trigger to start ISP procedure */
__ISB();                       /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG);            /* Waiting for ISP Done */
dataFloat = (float)(FMC->ISPDAT);

But the value read is 22.0 instead of 22.5 , I also get a warning of, 'implicit conversion to integer' while compilation. How can I do this without error?

Best Answer

Your problem probably arises from an implicit type conversion from a float to an int at this line:

FMC->ISPDAT = 22.5; /* Set Data to Program */

If it were me working on this, I would bundle a float and an int into a union like this:

union {
   uint32_t intVal;
   float floatVal;
} myUnion;

And then simply write the number into the float field:

myUnion.floatVal = 22.5f;

and then read the value as an int like so:

FMC->ISPDAT = myUnion.intVal;

This example assumes that sizeof(float) == sizeof(uint32_t) on your system. Alternatively you can do some compile time gymnastics to make a byte array the same size as your float size like so:

union {
   uint8_t[sizeof(float)] byteArray;
   float floatVal;
} myUnion;

Which works because sizeof is a compile time operator. One additonal note, you'll notice I added an 'f' after the 22.5. This informs the compiler to treat the number literal as a float and not as an int, which evidently is the type it would prefer. This is why your number is being truncated to 22.0, since there is an implicit int conversion taking place, most likely because the ISPDAT member of the FMC struct is an integral type of some kind.