Full Version : Sine Functions (PIC ASM)
avr >>PIC 8051 ZILOG ARM TI H8 ETC >>Sine Functions (PIC ASM)


Admin3- 04-18-2006
Implementing the Sine function on the PIC

For many applications it is necessary to use some basic trigonometry such as the sine function. On a small PIC it is impractical to use traditional methods such as series approximation or CORDIC to compute the sine function, so a table lookup is preferred. By taking advantage of trigonometric identities, it is only necessary to store a single quadrant of the lookup table.
For an example of how to adapt this code to have different scaling of the result, see my PWM DTMF Dialer project.


--------------------------------------------------------------------------------

PIC16C5x code:

CODE


; Copyright 1995 Eric Smith
; Permission is granted to copy this code for noncommercial purposes provided
; that the above copyright notice is preserved intact.

; A first quadrant sine table.  Angles are in units of 1/256 of a circle.
; The result is scaled by 127, thus the range is -127 to +127.
; Requires two file registers, temp and zero, the latter of which must be
;   initialized to zero.
; On entry, argument angle is in W
; On exit,  result is in temp
sinetbl:
addwf pc
retw 000h,003h,006h,009h,00ch,010h,013h,016h
retw 019h,01ch,01fh,022h,025h,028h,02bh,02eh
retw 031h,033h,036h,039h,03ch,03fh,041h,044h
retw 047h,049h,04ch,04eh,051h,053h,055h,058h
retw 05ah,05ch,05eh,060h,062h,064h,066h,068h
retw 06ah,06bh,06dh,06fh,070h,071h,073h,074h
retw 075h,076h,078h,079h,07ah,07ah,07bh,07ch
retw 07dh,07dh,07eh,07eh,07eh,07fh,07fh,07fh
retw 07fh

; A four quadrant sine function using the table.  Note that because of the
; limited depth of the return stack on the PIC16C5x, this code can't be called
; from a subroutine, so I often put it inline.

; If it is known that the argument is in the first quadrant, it is easier to
; just call sinetbl directly and get the result in W.

sine: movwf temp; save arg
btfsc temp,6; is arg in the 2nd or 4th quadrant?
subwf zero,w; yes, complement it to reduce to 1st or 3rd
andlw 07fh; reduce to 1st quadrant
call sinetbl; get magnitude
btfsc temp,7; was it 3rd or 4th quadrant?
subwf zero,w; yes, complement result
movwf temp
retlw 0; 16C5x can't return a value in W!
[code]

--------------------------------------------------------------------------------

PIC16Cxx code:

On the newer PIC16Cxx parts (14-bit instructions) the four quadrant sine function is a little simpler and easier to use:
The sublw instruction (which subtracts W *from* a literal) can be used to take the 2's complement of W without requiring a dedicated file register to contain 0.
The return instruction allows the result to be returned in W rather than temp.
Because of the deeper return stack it is OK to call the four quadrant sine function from a subroutine.

[code]
; Copyright 1995 Eric Smith
; Permission is granted to copy this code for noncommercial purposes provided
; that the above copyright notice is preserved intact.

; A four quadrant sine function using the table.  If it is known that the
; argument is in the first quadrant, it is easier to just call sinetbl
; directly.

sine: movwf temp; save arg
btfsc temp,6; is arg in the 2nd or 4th quadrant?
sublw 0; yes, complement it to reduce to 1st or 3rd
andlw 07fh; reduce to 1st quadrant
call sinetbl; get magnitude
btfsc temp,7; was it 3rd or 4th quadrant?
sublw 0; yes, complement result
return


--------------------------------------------------------------------------------

Parallel Evolution

When there is an optimal (or near optimal) way to code a simple subroutine, it is natural that several programmers trying to optimize code would reach the same (or nearly the same) result. In this case, Parallax had some concern about the origin of my Sine code above, since they use basically the same code. Although my code was developed completely independently, and I believe I've demonstrated that to their satisfaction, I've agreed to include their code on this web page as well. Of course, since it is under their copyright, you'll have to request permission from them if you want to use it.

CODE

The Sine Function from the BASIC Stamp II
 (C)1995 Parallax, Inc.
     -reproduced with permission-
;
;
; Lookup sin - 8 cycles
;
; example: (w=angle)
;  call lookup_sin;2+8
;  snb temp.7 ;1
;  mov w,zero-w;1
;  (w=sin)
;
lookup_sin mov temp,w ;1
 snb temp.6 ;1
 mov w,zero-w;1
 and w,#7Fh ;1
 jmp pc+w ;2+2

 retw 0,3,6,9,12,16,19,22
 retw 25,28,31,34,37,40,43,46
 retw 49,51,54,57,60,63,65,68
 retw 71,73,76,78,81,83,85,88
 retw 90,92,94,96,98,100,102,104
 retw 106,107,109,111,112,113,115,116
 retw 117,118,120,121,122,122,123,124
 retw 125,125,126,126,126,127,127,127
 retw 127




Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.