Searching \ for '16 bit square root routine for 17c43' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=bit+square+root
Search entire site for: '16 bit square root routine for 17c43'.

Truncated match.
'16 bit square root routine for 17c43'
1998\07\27@134644 by

Hi all !
Where could I get a 16 bit square root routine for PIC 17C43 ?

Juha

juha tuomi wrote:
>
> Hi all !
> Where could I get a 16 bit square root routine for PIC 17C43 ?
>
> Juha

Check out:

http://www.interstice.com/~sdattalo/technical/software/pic/picsqrt.html

This was written for the midrange core, but it should work (or be
adaptable to the 16-bit core). Andy David has written a square root
routine specifically for the 17Cxx family. Maybe he'll post it? Or you
can try contacting him:

"Andy David" <akdavidultronics.co.uk>

Scott

> Hi all !
> Where could I get a 16 bit square root routine for PIC 17C43 ?
>
> Juha

The following code takes the sqrare root of a 16 bit number and returns a
fixed point result of 8 bits integer and 8 bits fraction. The main loop of
the
routine generates one bit fro every interation. There are square root
routines
that converge in fewer interations.

Walter Banks

#pragma has PIC16;
#pragma has MUL;

long SQRT (long l)
/*
Square root V1.0.

Hayward/Banks approximation.

This routine generates a square root to
16 bit resolution taking a 16 bit argument
normalizing the argument and returning a 16 bit
real number that consists of 8 bits interger and
8 bit fractional parts. The MS8bits are the interger
part.

i i i i  i i i i . f f f f  f f f f
| | | |  | | | |   | | | |  | | | |
128 |32 |  8 4 2 1  .5 | | |  | | |  .00390625
64  16           .25  | |  | |  --.0078125
.125-  |  |  ----.015625
.0625--    ------.03125

These routines may be adapted for any purpose when
used with the MPC Code Development system.  No
warranty is implied or given as to their usability
for any purpose.

Byte Craft Limited
Waterloo, Ontario
(519) 888-6911

Gordon Hayward / Walter Banks
*/

{
unsigned int n,j,k;
unsigned long t @ 0x18;  // Multiply result
n = 0;
while( (l & 0xc000) == 0)
{
n++;
l <<= 2;
}
for (j = 0, k = 0x80; k != 0; k >>=1)
{
j = j | k;
t = j * j;
if (t > l) j = j & (~k);
}
t = j;
return (t << (8-n));
}

unsigned long result;
unsigned int int_part, frac_part;
void main(void)
{
result = SQRT(6000);
int_part  = result >> 8;
frac_part = result & 0xff;
}

>Hi all !
>Where could I get a 16 bit square root routine for PIC 17C43 ?
>
>Juha

The following is a C version to provide a 16-bit input with 8-bits of
output. This uses perfect rounding. It is not difficult to expand this to
provide more bits of output, ie. fixed point results.

unsigned byte Sqrt16(unsigned int X)
{ unsigned int Test = 0xFF00;
unsigned int Bit =  0x8000;
if (X == 0) return 0;
X = X - 1;
do {
Test = (Test ^ Bit) >> 1;
if (X >= Test)
{ X -= Test;
Test |= Bit;
}
} while ((Bit >>= 2) != 0);
return (unsigned byte)(Test >> 1);
}

Convertion to PIC assembly language is not difficult. The following is
this same code for the 14-bit midrange PIC code. I have never tried to write
it for the 16-bit versions.

; Routine   :   Sqrt16
; Purpose   :   Takes a squareroot of a 16-bit number, result is an 8-bit
;               number. Rounds results, inputs between (n*(n+1))
;               and (n*(n-1))-1 are returned as n. The algorithm is a
;               optimized binary search algorithm, creating the results a
;               bit per loop.
; Inputs    :   Acc -- word accumulater. 16-bit input.
; Returns   :   w -- results of the square root, rounded.
;               Acc -- value in here is trashed.
; Globals   :   sqrt_tst -- temp word variable.
;               sqrt_bit -- temp word variable.
; Timing    :   219 to 227 cycles including short call and return.

Sqrt16
movf Acc+1,w
iorwf Acc,w
skpnz
retlw 0x00   ; exit if 0.

; decrease input by 1 step, to change compare direction.
incf Acc+1,f
decfsz Acc,f
decf Acc+1,f

; set up bit value and partial for testing.
clrf sqrt_bit           ; clear bit pattern, want 0x8000
clrf sqrt_bit+1         ; high byte, first clear.
bsf sqrt_bit+1,7        ; set the highest bit.
clrf sqrt_tst
movlw high ((256*255)) ; sqrt_tst == 0xFF00
movwf sqrt_tst+1
; loop, we do this until all bits are shifted out of sqrt_bit.
;   This is done a total of 8 loops.
clrc                    ; clear carry
Sqrt16_loop
; set test value to (test - bit) / 2, can use XOR to subtract.
xorwf sqrt_tst,f
movf sqrt_bit+1,w       ; high byte, deal with borrow.
xorwf sqrt_tst+1,f
; do /2
rrf sqrt_tst+1,f
rrf sqrt_tst,f
; check if accumulator is greater than test value.
movf sqrt_tst,w
subwf Acc,f
movf sqrt_tst+1,w
skpc                    ; skip if not borrow.
incfsz sqrt_tst+1,w
subwf Acc+1,f           ; carry set if borrow
bc Sqrt16_c             ; branch if no borrow
Sqrt16_a
; on borrow we want to undo the subtract. Undo high byte.
addwf Acc+1,f       ; reverse high byte.
movf sqrt_tst,w     ; get low byte.
addwf Acc,f         ; all undone, can ignore carry.
; test value is left unchanged, clear carry for later code.
clrc
goto Sqrt16_d       ; down to end of loop test.
Sqrt16_c
; set test to test + bit, can use OR instead.
movf sqrt_bit,w
addwf sqrt_tst,f  ; carry is not possible
movf sqrt_bit+1,w  ; using ADD to clear carry.
addwf sqrt_tst+1,f      ; carry is not possible here.
Sqrt16_d
; shift bit pattern down by 2 bits, carry is already clear.
rrf sqrt_bit+1,f        ; shift down by 2.
rrf sqrt_bit,f          ; first bit out always is 0.
rrf sqrt_bit+1,f        ; shift down by 2 again.
rrf sqrt_bit,f          ; if carry out if this bit then done.
bnc Sqrt16_loop         ; loop until done.

; return results, test value / 2.
rrf sqrt_tst+1,w
rrf sqrt_tst,w

; results are in w, return them.
return

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