Hi,
My codewarrior version is 10.6 and studying about AN5201SW now.
In my application, I want to calculate (tFrac16 type value * 3.2767) and get result again in tFrac16 type.
tFrac16 type value is between 0 and 10,000, so I expect that it does not exceed the express range of result_value.
How can I do this? please give me a hand.
For additional explanation(in AN5201SW)
I want to calculate ((tFrac16)requiredSpeed * (float)3.2767 = (tFrac16)RESULT_VALUE) in "AppRun" step.
"SWLIBS_Typedefs.h"
typedef unsigned char tU8; /*!< unsigned 8-bit integer type */
typedef signed char tS8; /*!< signed 8-bit integer type */
typedef unsigned short tU16; /*!< unsigned 16-bit integer type */
typedef signed short tS16; /*!< signed 16-bit integer type */
typedef unsigned long tU32; /*!< unsigned 32-bit integer type */
typedef signed long tS32; /*!< signed 32-bit integer type */
typedef signed long long tS64; /*!< signed 64-bit integer type */
typedef tS16 tFrac16; /*!< 16-bit signed fractional Q1.15 type */
typedef tS32 tFrac32; /*!< 32-bit Q1.31 type */
typedef float tFloat; /*!< single precision float type */
Hi SuBin Kim,
I can see some indication of misuse of the fraction arithmetic. The equations should be scaled to avoid such real-world transformations in the code. However, there is a solution:
You are looking for a number, which is 3.2767 higher than the requiredSpeed. Well, there may be such number until the requiredSpeed is higher than 0.305 in fraction. Why? Just imagine following example:
Now, in general, if you need to perform the operation of multiplication by float 3.2767, you need to do a division by inverted number, since the calculation needs to be done in Frac16 range of <-1.0, 1.0), inputs as well as the output. The inverted number is
1 / 3.2767 = 0.305185
x * 3.2767 = x / 0.305185
You should consider that the result should never be higher than 1.0 or less than -1.0. That means, your calculation has some range limitations, which have to be addressed.
In the words of code:
if(MLIB_Abs(requiredSpeed) < FRAC16(0.305185))
Frac16 result = MLIB_DivSat_F16(requiredSpeed, FRAC16(0.305185));
else
// requiredSpeed is out of range
Frac16 requiredSpeed is scaled to its maximum of 10,000 RPM. That means: if the value is 0.5 in fraction, it means 5,000 RPM (in the memory, there is 16,535 representing the 0.5).
For the case of 5,000 RPM, the result would be
0.5 / 0.305185 = 1.0 !!! (since the result overflows 1.0 and causes saturation)
In case the requiredSpeed = 0.1, the result would be
0.1 / 0.305185 = 0.32767, which is correct and in the real-world scale it means 3276.7 RPM.
Final note: there is a way to incorporate floating point operations in the code. Personally, I would not recommend it since it is simulated by a huge set of instructions (no natural support of floating point operations in S12ZVM) and you would lose performance. The S12ZVM supports fractional arithmetic calculations and it's really fast. Using the AMMCLib functions, the performance is even better than using *, /, +, - operators, since it calls the dedicated ASM instructions of the MAC unit.
Best regards,
Matej
Hi,
Did you try right click on the project -> Properties -> Settings -> S12ZLinker -> Input as you can see here: S12Z CW10.6 Floating point using ?
Did that help you?
Best regards,
Diana