Searching \ for '16 bit numbers in a 8 bit architecture' in subject line. ()
Help us get a faster server
FAQ page: techref.massmind.org/techref/index.htm?key=bit+numbers+bit
Search entire site for: '16 bit numbers in a 8 bit architecture'.

Truncated match.
'16 bit numbers in a 8 bit architecture'
1998\02\04@134644 by

I need to be able to have a 16 bit wide number and be able to implement it
in a PIC (16C73).  The 16 bit length is a counter for cycles (65535).

How do I handle this?  Check for overflow in one register and then
increment another register?

Rob
Rob <PICLISTMITVMA.MIT.EDU> wrote:

> I need to be able to have a 16 bit wide number and be able to
> implement it in a PIC (16C73).  The 16 bit length is a counter for
> cycles (65535).
>
> How do I handle this?  Check for overflow in one register and then
> increment another register?

Yeah, Bob... The code usually looks like this:

INCFSZ  COUNTER_LO
GOTO    \$+2
INCF    COUNTER_HI

-Andy

=== Andrew Warren - fastfwdix.netcom.com
=== Fast Forward Engineering - Vista, California
=== http://www.geocities.com/SiliconValley/2499
On Wed, 4 Feb 1998 13:42:50 -0500 Rob <robzsHICOM.NET> writes:
>I need to be able to have a 16 bit wide number and be able to
>implement it
>in a PIC (16C73).  The 16 bit length is a counter for cycles (65535).
>
>How do I handle this?  Check for overflow in one register and then
>increment another register?

Yes, obviously you need two 8-bit registers to store a 16-bit number.  I
usually allocate registers for numbers larger than 8 bits in
"little-endian" form, meaning the MSB is immediately after the LSB in
RAM.

The most obvious way to increment it is to always increment the low byte,
and increment the high byte if the low byte is 0 after incrementing:

incf    num_l,f         ;Inc. low count (always).
skpnz                   ;Skip if didn't roll over
incf    num_h,f         ;Inc. high only if low rolled
over

If you had allocated the registers little-endian, then you could use
'num_l+1' (instead of 'num_h') to access the high byte.  This saves
having to label every byte like I did in the example above.  The routine
always takes 3 instruction cycles, regardless of the value of the number
(there is a 2-cycle way to do a 16 bit count, but it's not for
beginners).  After the routine, the Z flag will be set if num_h also
rolled over, indicating the number has counted beyond the maximum and is
now 0000.

_____________________________________________________________________
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]
I have seen two solutions to this question.  My question is there a reason to
avoid

INCFSZ counter1,F
INCF    counter2, F

Mike Keitz wrote:

{Quote hidden}

--
David Sprenkle
FerretTronics--Servo Control Chips and Software
http://www.busprod.com/ferrettronics/
David Sprenkle <PICLISTMITVMA.MIT.EDU> wrote:

> I have seen two solutions to this question.  My question is there a
> reason to avoid
>
> INCFSZ counter1,F
> INCF    counter2, F

There's DEFINITELY a reason to avoid THAT method, David; it
doesn't work.

You need a "GOTO \$+2" betwen the instructions; otherwise, both
bytes will be incremented every time EXCEPT when counter1
overflows.

-Andy

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

>(there is a 2-cycle way to do a 16 bit count, but it's not for
>beginners)
You are right, and come to think of it I have coded it and debugged it at
least once.  Its funny how bad ideas still come back to haunt me.  I have
another question so I don't wasted your email space.

How secure is the code potection on the 12C5XX and 16C5X series chips.  I

Andrew Warren wrote:

{Quote hidden}

--
David Sprenkle
FerretTronics--Servo Control Chips and Software
http://www.busprod.com/ferrettronics/
On Wed, 4 Feb 1998, Andrew Warren wrote:

> David Sprenkle <PICLISTMITVMA.MIT.EDU> wrote:
>
> > I have seen two solutions to this question.  My question is there a
> > reason to avoid
> >
> > INCFSZ counter1,F
> > INCF    counter2, F
>
>     There's DEFINITELY a reason to avoid THAT method, David; it
>     doesn't work.

Wait a second Andy, it does work... If you make a slight MODification.
You oughta remember since it was your idea. The trick is
(with counter1 and counter2 initially zero):

INCFSZ counter1,F
DECF  counter2,F

followed later by:
MOVF   counter1
ADDWF  counter2,W   ;Get the 'real' high byte count

The idea is that counter2 is decremented EVERY time counter1
is incremented EXCEPT when counter1 rolls over. So for the
256 increments there are 255 decrements. And decrementing
a register 255 times is equivalent to incrementing it once.
The only problem is that the 'true' 16-bit counter value
is only valid when counter1 rolls over. The extra code to
get the 'real' counter2 value compensates for this. I realize
that this 4-instruction solution is worse than the original
3-instruction solution. However, the real benefit is obtained
by putting the first two instructions into a time critical
loop and the last two into the post processing.

If I make it to work tomorrow then I'll re-post the gory
reasons why this works.

Scott
On Wed, 4 Feb 1998 16:44:48 -0800 David Sprenkle <sprenkleBUSPROD.COM>
writes:
>I have seen two solutions to this question.  My question is there a
>reason to
>avoid
>
>INCFSZ counter1,F
>INCF    counter2, F

This doesn't work "correctly", because the increment of counter2 is done
only if counter1 is *not* 0 (The PIC17CXX has a "increment and skip if
not 0" instruction that is ideal for this situation, but the 16CXX only
has the option to skip if zero).  So the count in counter2 is not
incremented every 256 counts as would be desired.

This is the 2-cycle counter I referred to earlier.  It is possible to
convert the count to a proper 16-bit number by subtracting counter2 from
counter1, and using this value as the high byte.  The value of counter1
is of course the correct low byte, since it was incremented every time
the routine executed just like a conventional counter does.

Further theory of the technique was discussed some time ago.  I think the
routine was originally proposed by one of the "heavy hitters" maybe
Payson or Dattalo, but I could be mistaken.

_____________________________________________________________________
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]
>I have seen two solutions to this question.  My question is there a reason to
>avoid
>
>INCFSZ counter1,F
>INCF    counter2, F

Close, but no cigar.  If you notice, BOTH counters increment except when
counter1 rolls over to zero.

Dwayne Reid   <dwaynerplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, Alberta, CANADA
(403) 489-3199 voice     (403) 487-6397 fax
> /Morgan
>
> >(there is a 2-cycle way to do a 16 bit count, but it's not for
> >beginners)

Well, if you do...

incfsz  foo
incf    bar

Then foo:bar will cycle through all 65,536 values.  They won't go through
those values in order, however; in addition, the above doesn't provide
any particularly cheap ways of checking for a specific spot in the count
sequence.  Is this the 2-cycle method referred to, or is there some other
method I'm not seeing?
Now this is more like it!

It's these little pearls of wisdom that I was hoping to see on this
list!

This one goes in the code fragment tool box...  Thanks Scott!

Chuck

> {Original Message removed}
A current topic of conversation is:

>On Wed, 4 Feb 1998, Andrew Warren wrote:
>
>> David Sprenkle <PICLISTMITVMA.MIT.EDU> wrote:
>>
>> > I have seen two solutions to this question.  My question is there a
>> > reason to avoid
>> >
>> > INCFSZ counter1,F
>> > INCF    counter2, F
>>
>>     There's DEFINITELY a reason to avoid THAT method, David; it
>>     doesn't work.
>
>Wait a second Andy, it does work... If you make a slight MODification.
>You oughta remember since it was your idea. The trick is
>(with counter1 and counter2 initially zero):

Just to add my two cents, these two instruction counts are very useful for
making a minimum cycle 16 bit event counter.

clrf   Count
clrf   Counthi

:                            ;  Wait for Event

Loop
incfsz Count                  ;  Increment the Counter
incf  Counthi
btfsc/s Condition             ;  Get out of the loop
goto  Loop

movf   Counthi, w             ;  Make "Counthi" Valid
subwf  Count, w
movwf  Counthi

After executing this code, Counthi:Count will be a valid 16 bit count of the
number of times through the loop.  Each execution of the loop is 5 cycles.

This snippet of code is useful when a 16 bit timer is not available, or the
range of events necessitates the use of a 16 bit counter.

To be honest, it's probably a limited set of special cases that would make
this method of timing an event appropriate.

myke

Opus:  There's a 465 pound woman pruning her azelias while wearing a pink
stretch bodysuit.

911 Operator:  So what's the emergency?

Opus:  From a taste perspective, it's a crisis of biblical proportions!
Mauro, Chuck wrote:
>
> Now this is more like it!
>
> It's these little pearls of wisdom that I was hoping to see on this
> list!
>
> This one goes in the code fragment tool box...  Thanks Scott!

Actually, you should thank Andy.

And then I wrote:

> > If I make it to work tomorrow then I'll re-post the gory
> > reasons why this works.

Well, I made it to work (barely) and here's a copy of the post
I sent last July that explains this stuff to a degree guranteed
to induce boredom.

Andrew Warren wrote:
{Quote hidden}

Was it only me or did anybody else out there appreciate the
significance of this code? Probably only half the list was impressed,
half could care less, and the remaining half of us miscounted the
number of cycles.

Here's how this beaut works:
Each time through the loop, the low byte of the pulse width is
incremented. The high byte is decremented every iteration EXCEPT
when the low byte rolls over, i.e. when the low byte is incremented
from 255 to 0.

An arbitrary 16-bit number may be written in terms of two unique
8-bit numbers as:

X = a*256 + b

And we want to count the number iterations so that we end up with:
X = pulse_width_hi*256 + pulse_width_low
or
pulse_width_lo = b
pulse_width_hi = a

At the label DONE the contents of the variables are:

pulse_width_lo = b
pulse_width_hi = (-255*a - b) mod 256

In other words, we already have the low byte. The high byte requires
some explanation. First, the number of times the low byte rolls over
is 'a' times. For each rollover, we decrement the high byte 255 times.
This accounts for the "-255*a". The remaining 'b' times we also
decrement the high byte. The "mod 256" just emphasizes that we
are dealing with 8-bit variables.

MOD identities:
The pulse_width_hi expression can be simplified:

pulse_width_hi = (-255*a - b) mod 256

= ( (-255*a) mod 256 - b mod 256 ) mod 256

= ( ((-255 mod 256)*(a mod 256)) mod 256 - b ) mod 256
because i) b mod 256 = b   by definition
ii)  (x*y) mod z = ( (x mod z) * (y mod z) ) mod z

= ( ((1 mod 256) * a) mod 256 - b) mod 256
because i) a mod 256 = a   by definition
ii)  -x mod z = (z - x) mod z

pulse_width_hi = (a - b) mod 256

And finally, the last two instructions add 'b' to pulse_width_hi

pulse_width_hi = (a - b + b) mod 256
= a !!!! (as in excitement not factorial)

Consider these examples

259 iterations:
259 = 1*256 + 3
at DONE, pulse_width_lo = 3 and
pulse_width_hi = (0 - 255 - 3) mod 256 = -2 mod 256 = 0xfe.

And 0xfe + 3 = 1.

515, at DONE pulse_width_lo = 3 and _hi would be
(0 - 255*2 - 3) mod 256 = 0xff. And 0xff + 3 = 2.
and 515 = 2*256 + 3

12803, at DONE pulse_width_lo = 3 and _hi would be
(0 - 255*50 - 3) mod 256 = 0x2f. And 0x2f + 3 = 0x32.
and 12803 = 50*256 + 3 (and 50 base 10 = 0x32).

After a private congratulations to Andy I get this response:

>  Geez, Scott, it's only an itty-bitty loop...

Come on Andy, quit being so MODest.

Scott
--
"The problem with television is not the resolution."
Hugh. F. Frohbach
Egg on my face again.

Someonw wrote:

>>I have seen two solutions to this question.  My question is there a reason to
>>avoid
>>
>>INCFSZ counter1,F
>>INCF    counter2, F

Then I wrote:

>Close, but no cigar.  If you notice, BOTH counters increment except when
>counter1 rolls over to zero.

Then Scott wrote:

Wait a second Andy, it does work... If you make a slight MODification.
You oughta remember since it was your idea. The trick is
(with counter1 and counter2 initially zero):

(code deleted)

Thanks, guys!  It **IS** a neat code snippet.

I do like this list.  Get up, get mail, learn something new.  I LOVE it!!

dwayne
Dwayne Reid   <dwaynerplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, Alberta, CANADA
(403) 489-3199 voice     (403) 487-6397 fax

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