The following is Scott Dattalos belated reply to a post from the piclist that I forwarded to him since his name was mentioned in it. You may remember that Scott (and Tajaart and ....) left the PIClist due to an excessive volume of unmarked and often childish off topic posts which he felt wasted more of his time than he could afford. Even off the list, Scott can't resist the impulse to help, and suggested that I forward his "better way" back to the list. James Newton mailto:jamesnewton@geocities.com phone:1-619-652-0593 http://techref.homepage.com NOW OPEN (R/O) TO NON-MEMBERS! Members can add private/public comments/pages ($0 TANSTAAFL web hosting) PICLIST guide: http://204.210.50.240/techref/default.asp?url=piclist.htm -----Original Message----- From: Scott Dattalo [mailto:sdattalo@unix.sri.com] Sent: Monday, November 15, 1999 4:45 PM To: James Newton Subject: Re: FW: GPS units On Tue, 2 Nov 1999, James Newton wrote: > Date: Tue, 2 Nov 1999 14:19:47 -0800 > From: James Newton > To: Scott Dattalo > Subject: FW: GPS units > > Just thought you would like to know that you have a reputation for "knowing > a better way" > It would be nice to see you on the PIClist again. Sorry I haven't responded sooner -- I've been really busy. This saturday I'll be moving to Texas... Check below for my response, which you're welcome to forward to the piclist. > > > -----Original Message----- > From: pic microcontroller discussion list > [mailto:PICLIST@MITVMA.MIT.EDU] On Behalf Of Nikolai Golovchenko > Sent: Tuesday, November 02, 1999 9:48 AM > To: PICLIST@MITVMA.MIT.EDU > Subject: Re: GPS units > > > >> Has anyone done > >> the conversion from 4 byte real (units 1/256 seconds) to degrees, minutes > >> and seconds in a PIC > >> in assembler? > >> It would look something like > ((B1*256^3)+(B2*256^2)+(B3*256)+B4)/3600)/256. > >> Would a simple > >> 16F84 be able to do that? > >> > >> Henk VK2GWK (PA0ADC) > > > >On that math, no problem on an 'F84; what you're talking about is > >simply generating a 32-bit number from the 4 bytes B1, B2, B3, B4, then > >dividing it by 3600 and by 256. You can start off by doing the divide > >by 256 (just shift the decimal place - B4 is now to the right of the > >decimal place) - then divide by 3600. Scott Dattalo or someone probably > >has a better way here, of course. > > > Yeah. Peace of cake.. :) > > 1. Convert to degrees > deg = B1B2B3B4 / (3600 * 256) > You will need 32 by 24 fixed point divide routine from Application Note 617. > 2. Convert residue to minutes > min = res / (60 * 256) > Same routine may be used, though 24 by 16 is enough. > 5. Convert residue to seconds and "subseconds" > sec = res / 256 - higher byte of residue > ssec = res - sec * 256 - lowest byte of residue > He's right though... I do have a better way to do it. 3600 = 60*60 = 15 * 15 * 16 = 225 * 16. So you can shift right 4 first and then you only need to divide by an 8-bit number (225) instead of a 16-bit number. Now 225 = 0xe1 = b11100001. Division by 225 is the same as 1/225 = 1/(256 - 31) Which plugged into here: N N / / e \ / e \2 / e \3 \ ------- = --- * | 1 - |---| + |---| - |---| + ... | v + e v \ \ v / \ v / \ v / / gives N N / / 31\ / 31\2 / 31\3 \ ------- = --- * | 1 + |---| + |---| + |---| + ... | 225 256 \ \256/ \256/ \256/ / now note that 31 = 32 - 1. So multiplication by 31 is the same as: N * 31 = N << 5 - N And division by 256 is just a shift right 8 positions. So this whole thing boils down to a few shifts and a few additions. Simple! Obviously you'll need to be careful with round offs and etc., but resorting to 16-bit division is an unnecessary overhead unless you've got the routine already debugged and you have the time to waste to perform the calculation. Regards, Scott