How to do floating point operations ?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to do floating point operations ?

Jump to solution
3,494 Views
YTawil
Contributor I

Hi

 

About the problem:

 

I took a lot of time, but I'm still stuck in doing floating point mathematical operations in my MC9S12ZVM MCU program. Maybe the question is elementary, but usually in my other projects, the compiler handles the casting between floats and integers back and forth. In the project I use, which is a demo project of one of your developments board S12ZVMLMINIBRD_BLDC_SW_CW11 the default floating point is turned off that is why once I include any explicit floating point operation I ends up with compilation error like:

 

Symbol __fdiv in file  MC9S12ZVML128_BLDC_Sensorless_c.obj is undefined S12ZVMLMINIBRD_BLDC_SW_CW11 C/C++ Problem

 

I read parts of AMMCLIB manual and I tried to use the APIs like MLIB_Mul and MLIB_Div and so one, but I ended up with variables coded in 32/16 bit fixed point and did not find how to convert them back to integer.

 

The question:

 

One of the thing I want to do is:

1- Read one of the ADCs.

2- Convert to volt by multiplying the nummeric/digital value by 2.5V/1023.

3- Then scale the result using a voltage divider scale 0.85 (in my design).

4- Send the result back using CAN. Here I need to convert back from tFrac32 or tFrac16 to integer (how?)

Also is it possible and safe to enable the usual and direct floating point calculation for the demo project S12ZVMLMINIBRD_BLDC_SW_CW11 ? How (I did not find where from project settings)?

 

Thanks

Tags (3)
0 Kudos
Reply
1 Solution
3,478 Views
pachamatej
NXP Employee
NXP Employee

Hello,

I understand that many people coming from high-end platforms or computer programming are used to use floating point operations. But when moving to low-cost solutions, they struggle to understand benefits of fixed point arithmetic.

Here are some points to consider:

  • S12Z core does not support floating point operations natively. Any floating point operation would take a lot of time in comparison to fixed point equivalent calculation (e.g. 150 cycles instead of 2-cycles). The very same algorithm done in floating point may take significantly higher time than fixed-point version.
  • S12Z core is optimized to do many fixed-point calculations in a single step - we call it DSP support, which includes e.g. "MAC operations" - multiply and accumulate - typical implementation of integration in math (used in many signal processing functions or PI-controllers). 
  • The real world is typically interfaced with analog-to-digital converters or PWM modulators, which are by nature integer-oriented. Further more, ADC in S12Z is only 12-bit and PWM modulator is only 15-bit, so there is no benefit in having those numbers in 32-bit floating point. Typically, 16-bit numbers are enough.

In conclusion, I would recommend to have all the data in S12ZVM in fixed-point format (represented by tFrac16 or tFrac32). It seems that your CAN protocol accepts integers. Here you can see the benefit - no need to convert anything. You can just take tFrac16 number and treat it as Word16 (or short). Fixed-point tFrac16 numbers are internally stored as integers Word16 (short). The scale is the same as above, 0 to 32767 represents 0 - 5V in real-world scale.

Solution to your task:

  1. Read one of the ADC - use left-justified results (so if the number is 1,024 for 5V input, the result will be 65,535). Then, right-shift the result by one bit, so the result is 32,767 - this is already within the tFrac16 range. Now, you can store the result directly into your tFrac16 variable and consider the range as 0 - 32,767 is displayed as 0 - 1.0, which corresponds to real voltage scale of 0 - 5.0V. I recommend to use some digital filtering, such as GDFLIB_MAfilter or similar. Again, no need to scale the result. However, if your CAN protocol requires to have the voltage in e.g. 10 V scale, then you would divide the result by 2 (better to use right-shift by one bit).
  2. No need for further conversion. You just need to make a note about the scale mentioned as above.
  3. If there is any scale, you would like to apply, again, no need to do any math. You just make another note about your new scale, that the range of 0 - 32767 in integer (or 0 - 1.0 in fixed-point representation) corresponds to whatever voltage range, e.g. 0 - 4.325 V.
  4. No need for any further action, you can just write the tFrac16 variable to the CAN message, but the recipient of the message should be aware of the scale - if it is e.g. 0 - 32767 means 0 - 4.325 V.

If you have any further questions, please don't hesitate to reply.

Best regards,

Matej

View solution in original post

2 Replies
3,479 Views
pachamatej
NXP Employee
NXP Employee

Hello,

I understand that many people coming from high-end platforms or computer programming are used to use floating point operations. But when moving to low-cost solutions, they struggle to understand benefits of fixed point arithmetic.

Here are some points to consider:

  • S12Z core does not support floating point operations natively. Any floating point operation would take a lot of time in comparison to fixed point equivalent calculation (e.g. 150 cycles instead of 2-cycles). The very same algorithm done in floating point may take significantly higher time than fixed-point version.
  • S12Z core is optimized to do many fixed-point calculations in a single step - we call it DSP support, which includes e.g. "MAC operations" - multiply and accumulate - typical implementation of integration in math (used in many signal processing functions or PI-controllers). 
  • The real world is typically interfaced with analog-to-digital converters or PWM modulators, which are by nature integer-oriented. Further more, ADC in S12Z is only 12-bit and PWM modulator is only 15-bit, so there is no benefit in having those numbers in 32-bit floating point. Typically, 16-bit numbers are enough.

In conclusion, I would recommend to have all the data in S12ZVM in fixed-point format (represented by tFrac16 or tFrac32). It seems that your CAN protocol accepts integers. Here you can see the benefit - no need to convert anything. You can just take tFrac16 number and treat it as Word16 (or short). Fixed-point tFrac16 numbers are internally stored as integers Word16 (short). The scale is the same as above, 0 to 32767 represents 0 - 5V in real-world scale.

Solution to your task:

  1. Read one of the ADC - use left-justified results (so if the number is 1,024 for 5V input, the result will be 65,535). Then, right-shift the result by one bit, so the result is 32,767 - this is already within the tFrac16 range. Now, you can store the result directly into your tFrac16 variable and consider the range as 0 - 32,767 is displayed as 0 - 1.0, which corresponds to real voltage scale of 0 - 5.0V. I recommend to use some digital filtering, such as GDFLIB_MAfilter or similar. Again, no need to scale the result. However, if your CAN protocol requires to have the voltage in e.g. 10 V scale, then you would divide the result by 2 (better to use right-shift by one bit).
  2. No need for further conversion. You just need to make a note about the scale mentioned as above.
  3. If there is any scale, you would like to apply, again, no need to do any math. You just make another note about your new scale, that the range of 0 - 32767 in integer (or 0 - 1.0 in fixed-point representation) corresponds to whatever voltage range, e.g. 0 - 4.325 V.
  4. No need for any further action, you can just write the tFrac16 variable to the CAN message, but the recipient of the message should be aware of the scale - if it is e.g. 0 - 32767 means 0 - 4.325 V.

If you have any further questions, please don't hesitate to reply.

Best regards,

Matej

3,475 Views
YTawil
Contributor I

This is a perfect reply. Thanks!

0 Kudos
Reply