CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

[solved] IEEE float and Microchip float confusion

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Emmo



Joined: 02 Feb 2017
Posts: 14

View user's profile Send private message

[solved] IEEE float and Microchip float confusion
PostPosted: Fri Jul 07, 2017 8:34 am     Reply with quote

Hello everyone,

I've been a bit confused about float formats. I was working with a pic18f67j94 and ccs modbus library. I was reading out float values from a sensor and converted them to Microchip float:
Code:

unsigned int32 value = 0;
float Modbus_Values[MODBUS_VALUES_TO_READ] = {-256, -256, -256, -256, -256, -256, -256, -256};
.
.
.
change_wordorder();
value  = (((int32)modbus_rx.data[1]<<24) | ((int32)modbus_rx.data[2]<<16) | ((int32)modbus_rx.data[3]<<8) | ((int32)modbus_rx.data[4]));
Modbus_Values[TEMPERATURE_REQUEST] =  f_IEEEtoPIC((int32)value);

This was working very well. Now I've changed the controller to pic24fj512gb606 (Compiler v5.073) and I get strange values. I found out that pic24 is working inside with IEEE float format.
These are the 4 Bytes I get from modbus:
41 F3 FD 53
After shifting them to value, value is 30.498693 (IEEE float selected to display). This is still right. But after converting f_IEEEtoPIC((int32)value), Modbus_Values[TEMPERATURE_REQUEST] is -0,0 (displayed as Microchip float) or 4.20944358E9 (displayed as IEEE float). This is wrong :(
I also tried casting it like this:
Code:

Modbus_Values[TEMPERATURE_REQUEST] =  (float)value;


But I got strange values, too and not 30.49. So how can I store an IEEE float, which is splitted into 4 Bytes, back into a IEEE float? What I'm doing wrong?

I spend now some hours to get it working, but now I'm out of ideas :-/
Thanks in advance!


Last edited by Emmo on Mon Jul 10, 2017 4:17 am; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 07, 2017 1:06 pm     Reply with quote

My advice is, get this floating point format conversion program:
http://www.piclist.com/techref/microchip/math/fpconvert.htm
In the Binaries section, click on the link for floatconv10.zip and download it.

Open the zip file and drag the floatconv.exe onto your Windows desktop.
Ignore the rest of it. Run the program, type in your byte values and
select the format you want on the left side, and click the button to
convert to float. Or vice versa. Investigate the problem.
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Fri Jul 07, 2017 1:16 pm     Reply with quote

All you need to do is use the same memory area for two types:
Code:

    float fpval;
    unsigned int32 intval;
#byte intval=fpval;


Then with your number stored in 'fpval', you can use 'intval' where you previously used the result of the conversion.

Key point is that the conversion gives an int32, containing the four bytes in IEEE order. On the PIC30/24, the bytes are already in the right order, so all you need is an int32 variable that uses the same memory space as the float variable.

You can either do this as shown with #byte (which allows you to locate two variables to the same space), or using a union:
Code:

union {
    unsigned int32 ival;
    float fval;
} combine;

Then if you write the float into combine.fval, combine.ival contains the int32.

Note that I'm explicitly using an unsigned int32. On the PIC18, the default integer is unsigned. On the PIC24, the default is signed. Hence it is better to be explicit.
Emmo



Joined: 02 Feb 2017
Posts: 14

View user's profile Send private message

PostPosted: Mon Jul 10, 2017 4:16 am     Reply with quote

Ttelmah wrote:
All you need to do is use the same memory area for two types:
Code:

    float fpval;
    unsigned int32 intval;
#byte intval=fpval;


Then with your number stored in 'fpval', you can use 'intval' where you previously used the result of the conversion.

Key point is that the conversion gives an int32, containing the four bytes in IEEE order. On the PIC30/24, the bytes are already in the right order, so all you need is an int32 variable that uses the same memory space as the float variable.

You can either do this as shown with #byte (which allows you to locate two variables to the same space), or using a union:
Code:

union {
    unsigned int32 ival;
    float fval;
} combine;

Then if you write the float into combine.fval, combine.ival contains the int32.

Note that I'm explicitly using an unsigned int32. On the PIC18, the default integer is unsigned. On the PIC24, the default is signed. Hence it is better to be explicit.


Ohh yeah it is working! Thank you very much! You saved my week :-)
I just have to remove the ";" after #byte

Code:

float fpval;
unsigned int32 intval;
#byte intval=fpval
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Tue Jul 11, 2017 8:56 am     Reply with quote

My semicolon autopilot was on... Smile

Have been posting for a few days with a very small screen and slow 'broadband'. Makes it easy to not spot mistakes like this...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group