Searching \ for '[PIC]: Maths on a 16F876' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/math/index.htm?key=math
Search entire site for: 'Maths on a 16F876'.

Exact match. Not showing close matches.
'[PIC]: Maths on a 16F876'
2001\04\10@220523 by

Hi,
I need to implement the following equation in a 16F876.
RESULT = (255 / A) * B
A and B are bytes (each have possible values of 01 to FF)
RESULT is a word (unsigned) for a timer routine counter.
Speed is not an issue. Code space is not really either.
What's the best way to do this sort of thing?
Regards...

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email listservmitvma.mit.edu with SET PICList DIGEST in the body

See.

http://www.piclist.com/techref/microchip/math/basic.htm

for maths routines.

Search the PICLIST.COM web pages they have a world of information that has
helped me a lot.

Pete

> {Original Message removed}
I wrote;
> > I need to implement the following equation in a 16F876.
> > RESULT = (255 / A) * B
> > A and B are bytes (each have possible values of 01 to FF)
> > RESULT is a word (unsigned) for a timer routine counter.
> > Speed is not an issue. Code space is not really either.
> > What's the best way to do this sort of thing?

Further to this, can I simply use the "8 bit by 8 bit to 24 bit floating
point" www.piclist.com/techref/microchip/math/div/8by8to24fp-ng.htm
for the first (divide) part, then the "24 bit by 8 bit" multiply for the
second?
www.piclist.com/techref/microchip/math/mul/23x8bbaj.htm
I'm not much at that sort of math if you hadn't guessed by now!  :-)
Regards...

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestmitvma.mit.edu

For best resolution, you need to do a 16 bit multiply (B * 255)  and then
divide by A.

Graham
----- Original Message -----
From: Peter Betts <ext-peter.bettsNOKIA.COM>
To: <PICLISTMITVMA.MIT.EDU>
Sent: Wednesday, April 11, 2001 7:16 AM
Subject: Re: [PIC]: Maths on a 16F876

{Quote hidden}

> > {Original Message removed}
> I need to implement the following equation in a 16F876.
> RESULT = (255 / A) * B
> A and B are bytes (each have possible values of 01 to FF)
> RESULT is a word (unsigned) for a timer routine counter.

You probably want to do the multiply first to maintain your precision. Does
mean having a 16 bit result that you then divide by 8 bit, but as the
multiply is a 7 bit shift plus an add, it will not take long. There should
be a suitable divide routine in the FAQ.

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestmitvma.mit.edu

Thanks for that, I didn't think of re-arranging it that way.
Actually, I can probably make the constant 256 which
means that I could put B in the high byte and then divide
by A. The error would be acceptable for the intended usage.
So all I really need is a 16 bit / 8 bit divide routine then?
That will give me a 16 bit result for my counter won't it?

Graham wrote:
{Quote hidden}

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestmitvma.mit.edu

> > RESULT = (255 / A) * B

Do you really need 255*B  ?

Say you have variables

A
B_Hi
B_Lo

If you can get away with 256*B then you just need to store B into B_Hi and
make B_Lo = 0.

Now just perform the 16bit (B_Hi:B_Lo) division by 8bit A.

I think it would be quicker to multiply by 256 (a non event as it's the high
byte of a 16bit word) and then subtract B if you actually do want 255 rather
than do a long multiplication by 255.

What are you trying to calculate?

Pete

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestmitvma.mit.edu

David Duffy <PICLISTMITVMA.MIT.EDU> wrote:

> I need to implement the following equation in a 16F876.
> RESULT = (255 / A) * B
> A and B are bytes (each have possible values of 01 to FF)
> RESULT is a word (unsigned) for a timer routine counter.
> Speed is not an issue. Code space is not really either.
> ....
> Actually, I can probably make the constant 256 which
> means that I could put B in the high byte and then divide
> by A. The error would be acceptable for the intended usage.

Yeah, you could do that... Or you could leave it at 255, and do
the multiplication like this:

MOVF    B,W
MOVWF   PRODUCT_HI
SUBLW   0
MOVWF   PRODUCT_LO
DECF    PRODUCT_HI

That's only two instructions more than what you'd need to do a
multiply by 256.

> So all I really need is a 16 bit / 8 bit divide routine then?
> That will give me a 16 bit result for my counter won't it?

Yes.  If you decide to make the constant 256, though, you can do
the division in about half the time that a regular 16/8 division
would take... But you already said that speed isn't an issue, so
you might as well use 255 and do a full 16/8 divide.

-Andy

=== Andrew Warren - fastfwdix.netcom.com
=== Fast Forward Engineering - San Diego, California
=== http://www.geocities.com/SiliconValley/2499

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestmitvma.mit.edu

> > I need to implement the following equation in a 16F876.
> > RESULT = (255 / A) * B
> > A and B are bytes (each have possible values of 01 to FF)
> > RESULT is a word (unsigned) for a timer routine counter.

B*255 / A

Now computing B*255 is very easy. Just treat it as

B*256 - B

This will give you a 16 bit result. Then use a 16 divided by 8 giving 16
routine for the division.

Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level
software)

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestmitvma.mit.edu

> I need to implement the following equation in a 16F876.
> RESULT = (255 / A) * B
> A and B are bytes (each have possible values of 01 to FF)
> RESULT is a word (unsigned) for a timer routine counter.
> Speed is not an issue. Code space is not really either.
> What's the best way to do this sort of thing?

If neither speed nor space is an issue just call math routines.  You may
have to expand the values to mutiple bytes first, depending on what math
routines you use.  Microchip has some math routines in app notes.

********************************************************************
Olin Lathrop, embedded systems consultant in Littleton Massachusetts
(978) 742-9014, olinembedinc.com, http://www.embedinc.com

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestmitvma.mit.edu

Peter wrote:
> > > RESULT = (255 / A) * B
>Do you really need 255*B  ?
>Say you have variables
>A
>B_Hi
>B_Lo
>
>If you can get away with 256*B then you just need to store B into B_Hi and
>make B_Lo = 0.
>
>Now just perform the 16bit (B_Hi:B_Lo) division by 8bit A.
>
>I think it would be quicker to multiply by 256 (a non event as it's the high
>byte of a 16bit word) and then subtract B if you actually do want 255 rather
>than do a long multiplication by 255.

Thanks to all those who helped me see the answer to this.
Sometimes the easy (obvious) answer just needs a nudge.
I will multiply * 255 (make it high byte & decrement) and do
the division with one of the routines on the piclist.com site.

>What are you trying to calculate?

A 16 bit timer value based on the # of steps to travel & how fast to get there.
Sounds weird but hey - you asked!  :-)
Regards...

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestmitvma.mit.edu

> > > I need to implement the following equation in a 16F876.
> > > RESULT = (255 / A) * B
> > > A and B are bytes (each have possible values of 01 to FF)
> > > RESULT is a word (unsigned) for a timer routine counter.

Bob Ammerman wrote:
{Quote hidden}

I have looked at the division routines on the PicList page but can't
seem to find one that's 16 bit divide by 8 bit with a 16 bit result.
I don't need the remainder, just the 16 bit result. Maybe I'm missing
something but the routines listed don't seem to do what I need.
Please feel free to point out the obvious answer to me!  :-)
Regards...

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestmitvma.mit.edu

Andy Warren:
{Quote hidden}

I've done it like this

decf    B,w
movwf   x_int_h
clrf    x_int_l

Does that make sense?

> > So all I really need is a 16 bit / 8 bit divide routine then?
> > That will give me a 16 bit result for my counter won't it?
>
>     Yes.  If you decide to make the constant 256, though, you can do
>     the division in about half the time that a regular 16/8 division
>     would take... But you already said that speed isn't an issue, so
>     you might as well use 255 and do a full 16/8 divide.

I've used the first half of this 16/8 to 16 routine
www.piclist.com/techref/microchip/math/div/16by8lzf-ng.htm
but the output seems wrong for some instances.
Does anyone have an easy routine that only does unsigned integers?
A and B are in the range of 01h - ffh and the output is 0001h - ffffh.
Any help with this is appreciated. :-)
Regards...

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

I wrote this "multiply by 255" code:

> >         MOVF    B,W
> >         MOVWF   PRODUCT_HI
> >         SUBLW   0
> >         MOVWF   PRODUCT_LO
> >         DECF    PRODUCT_HI

and David Duffy <PICLISTMITVMA.MIT.EDU> replied:

> I've done it like this
>
>          decf    B,w
>          movwf   x_int_h
>          clrf    x_int_l
>
> Does that make sense?

David:

It makes sense, but it's not correct.

What you've calculated is 256 * (B - 1), which is not the same
as 255 * B.

-Andy

=== Andrew Warren --- aiwcypress.com
=== IPD Systems Engineering, CYSD
=== Cypress Semiconductor Corporation
===
=== Opinions expressed above do not
=== necessarily represent those of
=== Cypress Semiconductor Corporation

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

Andy wrote:
{Quote hidden}

Doh!  What a dummy I'd be!
Oh well, I put in your code to fix that (my) bug but am still having
problems when A gets lower than 06h. Maybe I've got an error in
the division routine. The required equation is (B*255)/A
I still haven't found a suitable simple 16 by 8 in 16 routine.
Regards...

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

On Wed, 18 Apr 2001, Andrew Warren wrote:

{Quote hidden}

I really don't see why you can't just do this:

decf   B,w
movwf  PRODUCT_HI
xorlw  0xff
movwf  PRODUCT_LO

:)

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

> I've used the first half of this 16/8 to 16 routine
> www.piclist.com/techref/microchip/math/div/16by8lzf-ng.htm
> but the output seems wrong for some instances.
> Does anyone have an easy routine that only does unsigned integers?
> A and B are in the range of 01h - ffh and the output is 0001h - ffffh.
> Any help with this is appreciated. :-)
> Regards...

David, have you tried the fixed version down in the web page? Anyway,
I deleted the buggy version, and there is only the fixed one now.

The first part of it should work fine for you!

Nikolai

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

Scott Dattalo [almost] brilliantly stated:

That B * 255 can be computed by:

>
>     decf   B,w
>     movwf  PRODUCT_HI
>     xorlw  0xff
>     movwf  PRODUCT_LO
>

Except, what happens if B == 0?

decf B,W        ; W = 0xFF
movwf        PRODUCT_HI     ; Product HI = 255
xorlw    0xFF    ;W = 0
movwf        PRODUCT_LO    ; Product lo = 0

Not such a good thing.

0 * 255 is not == 65280 (0xFF00)

Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level
software)

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

>
>Except, what happens if B == 0?
>
>decf B,W        ; W = 0xFF
>movwf        PRODUCT_HI     ; Product HI = 255
>xorlw    0xFF    ;W = 0
>movwf        PRODUCT_LO    ; Product lo = 0
>
>Not such a good thing.
>
>0 * 255 is not == 65280 (0xFF00)

Troublemaker :)
--
Dave's Engineering Page: http://www.dvanhorn.org
Where's dave? http://www.findu.com/cgi-bin/find.cgi?kc6ete-9

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

On Wed, 18 Apr 2001, Bob Ammerman wrote:

{Quote hidden}

Yeah, I saw that. However, the original snippet suffers from the same
problem. But you could follow it with:

skpnz
clrf  PRODUCT_HI

Scott

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

Nikolai wrote:
> > I've used the first half of this 16/8 to 16 routine
> > www.piclist.com/techref/microchip/math/div/16by8lzf-ng.htm
> > but the output seems wrong for some instances.
> > Does anyone have an easy routine that only does unsigned integers?
> > A and B are in the range of 01h - ffh and the output is 0001h - ffffh.
> > Any help with this is appreciated. :-)
> > Regards...
>
>David, have you tried the fixed version down in the web page? Anyway,
>I deleted the buggy version, and there is only the fixed one now.
>
>The first part of it should work fine for you!

I found a bug in the 16 bit counter in the ISR. Double Doh!
I still have a bug in the code but the divide works well AFAIK.
Thanks also to those that helped me with the multiply,etc.
Regards...

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.

More... (looser matching)
- Last day of these posts
- In 2001 , 2002 only
- Today
- New search...