Hi there,
I am using NXP MC9S12ZVML64 mcu with with Automotive Math and Motor Control Library
I am using GFLIB_ControllerPIrAW_F16 library i.e GFLIB_ControllerPIrAW((tFrac16)lf16Error, (GFLIB_CONTROLLER_PIAW_R_T_F16 *) &PIPrms, F16);
for calculating Speed Pi output and current PI output and through switching mechanisim i am selecting one PI value among speed pi and current PI
i am feeding the selected PIoutput value to the MLIB_Mul((tFrac16)PIOut, (tFrac16)CONSTANT_VALUE,F16)) for calculating duty.
and this above sequence of code is working fine.
I want to use GFLIB_ControllerPIrAW_F32 library for above scenario only , can you please let me know that what are the changes required for using
GFLIB_ControllerPIrAW_F32 library instead of GFLIB_ControllerPIrAW_F16 library.
Is there any limitation for using GFLIB_ControllerPIrAW_F32 library with MC9S12ZVML64 mcu.
and also please let me know if i want to feed the same error which is in terms of (tFrac32)lf16Error as GFLIB_ControllerPIrAW_F32 input by only changing the typecasting to tFrac32 if this can be done directly or,i
is there any requirement of increasing the error value in terms of frac32 scale by left shifting the (tFrac32)lf16Error << 15 and then using the same scaled error value as input to GFLIB_ControllerPIrAW_F32 library, is this method is correct.
Please suggest the correct approach to shift to GFLIB_ControllerPIrAW_F32 library using the same GFLIB_ControllerPIrAW_F16 inputs for generating similar kind of results.
Solved! Go to Solution.
Hello,
you can convert 16-bit fractional values to 32-bit fractional format using the library function MLIB_ConvertPU_F32F16. Note that GFLIB_ControllerPIrAW_F32 uses 32-bit parameters so you will need to recalculate them as well. If you want to convert the 32-bit output of GFLIB_ControllerPIrAW_F32 back to 16-bit format, use the function MLIB_ConvertPU_F16F32.
Hello,
you can convert 16-bit fractional values to 32-bit fractional format using the library function MLIB_ConvertPU_F32F16. Note that GFLIB_ControllerPIrAW_F32 uses 32-bit parameters so you will need to recalculate them as well. If you want to convert the 32-bit output of GFLIB_ControllerPIrAW_F32 back to 16-bit format, use the function MLIB_ConvertPU_F16F32.
Thanks petrz for the response it really helped a lot.
I have one doubt,
suppose, ErrorVar (variable datatype is frac32) = 40000 - fsu16Var(variable consist frac16 values)
scenario1 :-
if fsu16Var is 0
lf32error = 40000
how to convert this variable to frac32 value to feed to the below library as 32bit error input.
GFLIB_ControllerPIrAW(Error, (GFLIB_CONTROLLER_PIAW_R_T_F16 *) &PIPrms, F32)
can you suggest any approach for above scenario.
it seems for above scenario i can not use MLIB_ConvertPU_F32F16() for getting scaled frac32 bit error value for input to GFLIB_ControllerPIrAW(Error, (GFLIB_CONTROLLER_PIAW_R_T_F16 *) &PIPrms, F32)
First of all, if PIPrms is a struct of type GFLIB_CONTROLLER_PIAW_R_T_F16, you will need to create a new struct of type GFLIB_CONTROLLER_PIAW_R_T_F32 for use with GFLIB_ControllerPIrAW_F32 and fill it with correctly recalculated parameters (refer to AMMCLib User's Guide how to calculate the parameters for 32-bit controller).
The 32-bit controller expects 32-bit input value. You cannot directly subtract tFrac16 value from a tFrac32 value. The tFrac16 value must be converted to tFrac32 and then it can be subtracted from another tFrac32 value.
Example:
#include "gflib.h"
tFrac16 f16VarA = (tFrac16)0; // 16-bit value
tFrac32 f32VarB = (tFrac32)40000; // 32-bit value
tFrac32 f32InErr;
tFrac32 f32Output;
tFrac16 f16ConvertedValue;
GFLIB_CONTROLLER_PIAW_R_T_F32 trMyPI = GFLIB_CONTROLLER_PIAW_R_DEFAULT_F32;
void main(void)
{
// Initialize the controller parameters
trMyPI.f32CC1sc = FRAC32(0.01); // use your correct value instead of 0.01
trMyPI.f32CC2sc = FRAC32(0.02); // use your correct value instead of 0.02
trMyPI.u16NShift = 1; // use your correct value instead of 1
trMyPI.f32UpperLimit = FRAC32(1.0); // use your correct value instead of 1.0
trMyPI.f32LowerLimit = FRAC32(-1.0); // use your correct value instead of -1.0
// Subtract 16-bit value from 32-bit value: f32VarB - f16VarA
f32InErr = MLIB_Sub_F32(f32VarB, MLIB_ConvertPU_F32F16(f16VarA));
// Call the controller function
f32Output = GFLIB_ControllerPIrAW_F32(f32InErr, &trMyPI);
// The 32-bit output is in f32Output.
// You can convert f32Output to 16-bit value if needed
f16ConvertedValue = MLIB_ConvertPU_F16F32(f32Output);
}
Thanks again petrz.
i appreciate your quick reponse.
Again i have one concern,
eqation(1) :: f32ErrorVar = (tFrac32)40000 - fsu16Var
fsu16Var -> (variable consist frac16 but only contains positive value and sometime its value can go more then 32767 but less then 65535 so variable datatype definition is used as unsigned16)
so to feed this error to below library
GFLIB_ControllerPIrAW(f32ErrorVar, (GFLIB_CONTROLLER_PIAW_R_T_F32 *) &PIPrms, F32)
if i use MLIB_ConvertPU_F32F16(fsu16Var)
i can loose some data from fsu16Var as library accept the input value with tFrac16 typecasting to every input , please correct me if i am wrong.
So any library or approach that can be followed to convert this fsu16Var to tFrac32Var value without loosing any value.
It is important to understand that fixed-point fractional arithmetic works with fixed range and variable resolution. What that means is that regardless of whether your integer representation goes up to 32767 or 65535 or even 2147483647, it will always correspond to the same fractional range [0.0; 1.0) in case of unsigned arithmetic and [-1.0; 1.0) in case of signed arithmetic.
We write integer constants in the code only because the C language does not allow us to write fractional values directly (i.e. we write 32767 instead of 0.9999694824218750). Both 32767 (as 16-bit signed integer) and 0.9999694824218750 (as 16-bit signed fractional) correspond to the same bit pattern in the CPU register:
AMMCLib functions work with signed fractional values which are in the fixed range [-1.0; 1.0) and the resolution is 0.00003052 for the tFrac16 type and 0.0000000004657 for the tFrac32 type.
You will need to decide what should be the fractional format representation of your variable fsu16Var. If you want to represent it as Q0.16 unsigned fractional value in the range [0.0; 1.0), then you will need to cast it to tFrac32 and shift left by 15:
In general, the fixed-point implementation of any application requires scaling of all physical quantities to fit in the fractional range [-1.0; 1.0), i.e. dividing all voltages, currents, etc. by their maximum possible limits. Depending on what physical quantity is represented by fsu16Var, you should be able to deduce the correct representation in the fractional format.
Hi petrz,
Thanks again.
Is there any library that supports conversion of unsigned 16 variable to signed 16 value or any approach that can be followed to achieve this type of conversion.
Thanks.
We don't have a dedicated library function for this conversion, but it can be achieved with one line of code. Assuming that you have a 16-bit unsigned fractional value in the Q0.16 format, you can convert it to 16-bit signed fractional value in the Q1.15 format by shifting it right and then casting the result to the tFrac16 type. This will map the input values from the original range [0.0; 1.0) to the new range [-1.0; 1.0) and reduce the resolution by 1 bit (you lose the least significant bit in the shift right operation).