Page 1 of 1

Floating point calculation in an 8 bit processor

Posted: 11 Mar 2008, 16:39
by Samaya
Oh my word this is hair raising. I need to stay away from floating point but cant because I am dividing a number. My processing time is 186us for the calculation but my loop time limit is 360us and my ucontroller still needs to run interrupts, a 16 bit timer, input capture port which is timed, create a PWM signal, refresh a I2C bus and scan 3 buttons without missing anything.

I might be able to make it.... :banghead: :banghead: :banghead:

Posted: 11 Mar 2008, 17:02
by viceroy
um....ya...

Have fun :)

Posted: 11 Mar 2008, 17:13
by halo
what micro are you using... I had a very similar problem with my last design and i managed to work my way around it... just break it down for me slowly and ill try help you out.

Posted: 11 Mar 2008, 17:18
by Hex_Rated
A PIC would be able to do that. Use fixed point int for floats. :wink:

Posted: 11 Mar 2008, 17:20
by halo
Hex_Rated wrote:A PIC would be able to do that. Use fixed point int for floats. :wink:
Hmm, that wasnt good enough for me when i was doing me design last term... the micro had to be up and ready for an interrupt very quickly and i had to trick around to get mine to time right...

Posted: 11 Mar 2008, 17:43
by Hex_Rated
Fixed pt is better than float on 8 bit cpus. It wont solve all your issues but its a start. Playing with int priorities is something else you can do to speed them up. Ive been writing embedded soft professionally for 6 years, those cpus are much faster than most people think.

Posted: 11 Mar 2008, 17:52
by halo
Hex_Rated wrote:Fixed pt is better than float on 8 bit cpus. It wont solve all your issues but its a start. Playing with int priorities is something else you can do to speed them up. Ive been writing embedded soft professionally for 6 years, those cpus are much faster than most people think.
completely agree with you, but my design just got out of hand last time, and i had work around alot of timing issues... my code could have simpler and my design less complex, but i was too close to deadline to rework the solution, so i had to cheat :)

Posted: 11 Mar 2008, 18:29
by Hex_Rated
A lot of my clients have got spaghetti coded overly complex designs (mostly cause they cant make up their fn minds). Its what being an embedded soft eng is all about!

Posted: 12 Mar 2008, 08:11
by Samaya
I am using an Atmel ATmega168 uC. My problem is that I need to use this formula: (X/(Y*0.00005))*3600). It is the only way I can think of to get the values I need. So can you see the floating point? The X value is set only once but the Y value is constantly changing. The Y value can be anything from 0.0000036 to 4294967296. The X value can be anything from 0,1 to 1000 when set. So if you could think of another method of working this out without dividing or using floats, I am all ears...

Posted: 12 Mar 2008, 12:47
by Hex_Rated
The range is too much to use a 32bit unsigned long fixed pt calc. You do need to use a float or maybe a 64bit long if the compiler supports it. You could implement your own 64bit integer format by combining 2 32bit ints. Integer division is much faster than floating point division. It is also possible to use bit shifts for multiplication and division on integer calculations which will squeeze even more performance out. eg MUL 3600 at the end would become:

((ans << 8 ) + (ans << 6) + (ans << 5) + (ans <<3) )<<1) + ((ans <<8 ) + (ans << 6) + (ans << 5) + (ans << 3) ) <<3 )

Which works out to be: 320ans x 2 + 320ans x 8 = 10x320ans = 3200ans
Given ans = (X/(Y/20,000))

Have you tried timing the calculation to see if it truly is the bottleneck? It's possible that you're looking in the wrong place.

Posted: 12 Mar 2008, 16:03
by Samaya
I used the AVR studio simulator and got a processed time of 186us. I also only typed the calculation in the program (about 4 lines of actual code) no other code, So I am pretty sure its the bottle neck.

BUT now this morning things got WAY more complicated. I now have to implement our company protocol in the unit so we can "talk" remotely with the unit. So we decided to throw out the 8-bit and use an 32-bit ARM Thumb uC(AT91SAM7S64). Doesn't make my life any easier though, I still need to do the calculation. I'll look at your suggestion. I forgot I could use bit shifting.
Thanks man.

Posted: 12 Mar 2008, 19:38
by halo
well, if i understand your problem correctly you have to solve the following:

(X/(Y*0.00005) * 3600)

this can be rewritten as

(X/Y) * (3600/0.00005) = (X/Y)*(72x10^6) = (X/Y)*((64+8 )*10^6)

=(X/Y)*64*10^6 +(X/Y)*8*10^6

the times 64 and times 8 are simple shift right operations (64 = 6 shifts right and 8 = 3 shifts right) and the time 10^6 is a simple addition to a floating points power(unless you are using base 2).

thats how i would streamline the calculate....