View previous topic :: View next topic |
Author |
Message |
[email protected]
Joined: 30 Nov 2008 Posts: 5
|
Fast Math in Interrupts |
Posted: Tue Jul 07, 2009 2:28 pm |
|
|
I need a fast math function to be used inside an Interrupt.
I need to do this.
Int
(read timer 3 value)
Calculate a % of timer 3 that is between 5 and 40% of timer 3.
So you would think I would just use
Result = Timer3 * .05
or
Result = Timer3 * .4
The Multiply function is a floating point math function.
That disables the INT in the main code which causes me to miss interrupts.
How can I do this math without the floating point routines?
Is there another multiply function that I could use?
Any help would be greatly appreciaited.
Chris |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah Guest
|
|
Posted: Wed Jul 08, 2009 4:28 am |
|
|
As a further comment, remember that you can get binary divisions, without using normal arithmetic at all. Assume you have an unsigned int16 value, if you shift it right twice, you get the value *.25, for the cost of only half a dozen machine cycles. The compiler is 'smart' in this regard, and if you have such an unsigned value, and in the interrupt, use "Result=val/4", it will automatically substitute the shift.
Now, if (for instance), 0.375*, was an acceptable compromise, then you could use:
Result=val>>2;
Result+=Result>>1;
This would involve under 30 instructions, and generate the closest integer vallue below val*0.375.
Best Wishes |
|
|
[email protected]
Joined: 30 Nov 2008 Posts: 5
|
I solved it!! |
Posted: Thu Jul 09, 2009 6:46 am |
|
|
The multiplicand value will range from .055 to .388.
I solved this by first multiplying the multiplicand .055 - .388 by 65536. The result is a 16 bit integer. This is the main.
Then in the interrupt I use integer multiplication to multiply the Timer 3 value to the value in the 16bit interger. The result is an int32 which I shift right 16 times or (%65536).
The result is the number I wanted without the use of floating point math in the interrupt.
Chris Miller |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu Jul 09, 2009 7:21 am |
|
|
Depending on the range of timer3 I would consider using a lookup table.
Have a routine do the calculations and put it into an array, you then can access the correct value by using the timer3 value as an index.
This may be a problem if timer3 is 16bit or the range is greater than 256 values! |
|
|
|