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:

; 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!

PIC16Cxx code:

On the newer PIC16Cxx parts (14-bit instructions) the four quadrant sine function is a little simpler and easier to use:
; 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.

	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

Other resources


Back to my PIC Projects page
Back to my home page

Last updated August 21, 2001

Copyright 1995, 1996, 1999, 2001 Eric Smith

eric@brouhaha.com

Valid HTML 3.2! check now