Floating point calculation in an 8 bit processor

All topics about coding, designing, etc. goes in here.
Post Reply
Samaya
Registered User
Posts: 2018
Joined: 23 Oct 2002, 02:00
Location: Not on this forum

Floating point calculation in an 8 bit processor

Post 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:
viceroy
Registered User
Posts: 3565
Joined: 27 Mar 2006, 02:00
Location: I forget

Post by viceroy »

um....ya...

Have fun :)
Image
halo
Registered User
Posts: 2412
Joined: 30 Apr 2003, 02:00
Location: on a ring, far,far away
Contact:

Post 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.
Image
Hex_Rated
Registered User
Posts: 3679
Joined: 19 Jan 2006, 02:00
Contact:

Post by Hex_Rated »

A PIC would be able to do that. Use fixed point int for floats. :wink:
DFI LanParty X48 LT-2TR
Intel Q9450 @ 3.2Ghz
Dell 24" 2408WFP | Phillips 37" 1080p
Sapphire HD4870 X2 2GB
4GB Corsair DDR-2 1066 | Thermalrite 120 Ultra Extreme | G9 Mouse | G15 Keyboard
Vista Ultimate x64
halo
Registered User
Posts: 2412
Joined: 30 Apr 2003, 02:00
Location: on a ring, far,far away
Contact:

Post 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...
Image
Hex_Rated
Registered User
Posts: 3679
Joined: 19 Jan 2006, 02:00
Contact:

Post 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.
DFI LanParty X48 LT-2TR
Intel Q9450 @ 3.2Ghz
Dell 24" 2408WFP | Phillips 37" 1080p
Sapphire HD4870 X2 2GB
4GB Corsair DDR-2 1066 | Thermalrite 120 Ultra Extreme | G9 Mouse | G15 Keyboard
Vista Ultimate x64
halo
Registered User
Posts: 2412
Joined: 30 Apr 2003, 02:00
Location: on a ring, far,far away
Contact:

Post 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 :)
Image
Hex_Rated
Registered User
Posts: 3679
Joined: 19 Jan 2006, 02:00
Contact:

Post 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!
DFI LanParty X48 LT-2TR
Intel Q9450 @ 3.2Ghz
Dell 24" 2408WFP | Phillips 37" 1080p
Sapphire HD4870 X2 2GB
4GB Corsair DDR-2 1066 | Thermalrite 120 Ultra Extreme | G9 Mouse | G15 Keyboard
Vista Ultimate x64
Samaya
Registered User
Posts: 2018
Joined: 23 Oct 2002, 02:00
Location: Not on this forum

Post 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...
Hex_Rated
Registered User
Posts: 3679
Joined: 19 Jan 2006, 02:00
Contact:

Post 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.
DFI LanParty X48 LT-2TR
Intel Q9450 @ 3.2Ghz
Dell 24" 2408WFP | Phillips 37" 1080p
Sapphire HD4870 X2 2GB
4GB Corsair DDR-2 1066 | Thermalrite 120 Ultra Extreme | G9 Mouse | G15 Keyboard
Vista Ultimate x64
Samaya
Registered User
Posts: 2018
Joined: 23 Oct 2002, 02:00
Location: Not on this forum

Post 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.
halo
Registered User
Posts: 2412
Joined: 30 Apr 2003, 02:00
Location: on a ring, far,far away
Contact:

Post 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....
Image
Post Reply