' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Uses PWM through an RC network to create an analog voltage.
' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------
DEVICE SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ 4_000_000
ID "PWM"
' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------
DAC VAR RB.0 ' output to RC network
' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------
angle VAR Byte
duty VAR Byte
tmpB1 VAR Byte
tmpB2 VAR Byte
' =========================================================================
PROGRAM Start
' =========================================================================
' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------
SIN SUB 1 ' returns sine of angle
COS SUB 1 ' returns cosine of angle
' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------
Start:
DO
FOR angle = 0 TO 255 ' sweep through angles
duty = SIN angle ' get sine of angel
duty = duty + 127 ' bias to 2.5 v
PWM DAC, duty, 1 ' charge RC network
NEXT
LOOP
' -------------------------------------------------------------------------
' Subroutine Code
' -------------------------------------------------------------------------
' Use: value = SIN angle
' -- "value" returned as signed byte (-127 to 127)
' -- angle is expressed in Brads (0 - 255)
SIN:
tmpB1 = __PARAM1 ' get angle
tmpB2 = tmpB1 ' make copy
IF tmpB2.6 = 1 THEN ' in 2nd or 4th quadrant?
tmpB1 = 0 - tmpB1 ' yes, move to 1st/3rd
ENDIF
tmpB1.7 = 0 ' reduce to 1st quadrant
READ SineTable + tmpB1, tmpB1 ' read sine
IF tmpB2.7 = 1 THEN ' was angle in 3rd/4th?
tmpB1 = 0 - tmpB1 ' yes, adjust
ENDIF
RETURN tmpB1
' -------------------------------------------------------------------------
' Use: value = COS angle
' -- "value" returned as signed byte (-127 to 127)
' -- angle is expressed in Brads (0 - 255)
COS:
tmpB1 = __PARAM1 + $40 ' get angle (adjust phase)
tmpB1 = SIN tmpB1 ' call sine table
RETURN tmpB1
' =========================================================================
' User Data
' =========================================================================
SineTable:
DATA 000, 003, 006, 009, 012, 016, 019, 022
DATA 025, 028, 031, 034, 037, 040, 043, 046
DATA 049, 051, 054, 057, 060, 063, 065, 068
DATA 071, 073, 076, 078, 081, 083, 085, 088
DATA 090, 092, 094, 096, 098, 100, 102, 104
DATA 106, 107, 109, 111, 112, 113, 115, 116
DATA 117, 118, 120, 121, 122, 122, 123, 124
DATA 125, 125, 126, 126, 126, 127, 127, 127
DATA 127