Fractional Math

Started by December 6, 2002
 Hello, I am working on a project with the DSP56F807, CodeWarrior 5.02, and SDK 2.5 and am fairly new to the DSP world. I have questions concerning fractional and integer math for my application. When reading an 807 ADC channel I am interpreting the value as a 16 bit fractional value (Frac16) which gives me a "percent full scale" reading which would be convenient to multiply by full scale to generate a value in units of volts, degrees, etc. For example if full scale for the input is 10V (before hardware attenuation) and the ADC reading is 0.5, the input voltage is 0.5 x 10V = 5V. I don't see a way to directly implement an equation like this due to the mixture of integer and fractional values. Is there an efficient way to do this (preferably in C) or should I go back to 16.16 - integer part in upper 16 bits and fractional part in lower 16? I feel that I am missing something here. Also while experimenting, I ran across what may be a compiler bug. When multiplying two Frac16 numbers and putting the result in a Frac32 variable I find that the result always seems to be 1/2 of the expected value. The code below is an example. 0.5 x 0.5 = 0.125 instead of 0.25. The compiler puts an asr instruction following the mpy that causes the problem. Has anyone seen this? ; 7: void Test16x16Multiply (void) ; 8: { ; 9: Frac16 a, b; ; 10: Frac32 c; ; 11: ; 0x00000000 FTest16x16Multiply: 0x00000000 0xCC02 movei #2,N 0x00000001 0xDE0F lea (SP)+N ; ; 12: a = FRAC16(.5); ; 0x00000002 0xA7B34000 moves #16384,X:0x0033 ; ; 13: b = FRAC16(.5); ; 14: ; 0x00000004 0xA7B24000 moves #16384,X:0x0032 ; ; 15: c = a * b; ; 0x00000006 0xB132 moves X:0x0032,Y0 0x00000007 0xB033 moves X:0x0033,X0 0x00000008 0x64C8 mpy +Y0,X0,B 0x00000009 0x7CB0 asr B 0x0000000A 0xD71F move B1,X:(SP) 0x0000000B 0xD1CBFFFF move B0,X:(SP-0x0001) ; ; 16: } 0x0000000D 0x9EFE lea (SP-0x0002) 0x0000000E 0xEDD8 rts Thanks for any help. Terry Litinas Project Engineer ITW Balance Engineering 1731 Thorncroft Troy, Mi. 48084 Ph: (248)643-2876 Fx: (248)643-2888
One of our engineers put together the attached MSWord document that allowed him to better understand the concept of fractional math.  It exposes the behaviour of the intrinsic and SDK functions that are supplied with the CW 5.0.2 and SDK 2.5 Software.  It includes on the end, the sample code used to build the information in the tables.

I would encourage you to examine the concepts in the document, and if we have a misunderstanding of the concepts please let me know!!  While this document primarily exposes the usage of the routines using integer variables (Word32, Word16) and not the Frac32 and Frac16 representation, they are both defined in port.h to be equivalent to long and short respectively.

Hope this is of help.

Jerry

-----Original Message-----
From: Terry Litinas [mailto:t...@itwbe.com]
Sent: Friday, December 06, 2002 7:33 AM
To: m...@yahoogroups.com

Hello,

I am working on a project with the DSP56F807, CodeWarrior 5.02, and SDK 2.5
and am fairly new to the DSP world. I have questions concerning fractional
and integer math for my application. When reading an 807 ADC channel I am
interpreting the value as a 16 bit fractional value (Frac16) which gives me
a "percent full scale" reading which would be convenient to multiply by full
scale to generate a value in units of volts, degrees, etc. For example if
full scale for the input is 10V (before hardware attenuation) and the ADC
reading is 0.5, the input voltage is 0.5 x 10V = 5V. I don't see a way to
directly implement an equation like this due to the mixture of integer and
fractional values. Is there an efficient way to do this (preferably in C) or
should I go back to 16.16 - integer part in upper 16 bits and fractional
part in lower 16? I feel that I am missing something here.

Also while experimenting, I ran across what may be a compiler bug. When
multiplying two Frac16 numbers and putting the result in a Frac32 variable I
find that the result always seems to be 1/2 of the expected value. The code
below is an example. 0.5 x 0.5 = 0.125 instead of 0.25. The compiler puts an
asr instruction following the mpy that causes the problem. Has anyone seen
this?;    7: void Test16x16Multiply (void)
;    8: {
;    9:       Frac16 a, b;
;   10:       Frac32 c;
;   11:
;
0x00000000                  FTest16x16Multiply:
0x00000000  0xCC02                 movei    #2,N
0x00000001  0xDE0F                 lea      (SP)+N
;
;   12:       a = FRAC16(.5);
;
0x00000002  0xA7B34000             moves    #16384,X:0x0033
;
;   13:       b = FRAC16(.5);
;   14:
;
0x00000004  0xA7B24000             moves    #16384,X:0x0032
;
;   15:       c = a * b;
;
0x00000006  0xB132                 moves    X:0x0032,Y0
0x00000007  0xB033                 moves    X:0x0033,X0
0x00000008  0x64C8                 mpy      +Y0,X0,B
0x00000009  0x7CB0                 asr      B
0x0000000A  0xD71F                 move     B1,X:(SP)
0x0000000B  0xD1CBFFFF             move     B0,X:(SP-0x0001)
;
;   16: }
0x0000000D  0x9EFE                 lea      (SP-0x0002)
0x0000000E  0xEDD8                 rtsThanks for any help.

Terry Litinas
Project Engineer
ITW Balance Engineering
1731 Thorncroft
Troy, Mi. 48084
t...@itwbe.com
Ph: (248)643-2876
Fx: (248)643-2888

_____________________________________

_____________________________________

To Join:  m...@yahoogroups.com

To Post:  m...@yahoogroups.com

To Leave: m...@yahoogroups.com

More Groups: http://www.dsprelated.com/groups.php3