I've been interested in this as well. Using the principles of AN655, (only using DT_INTS and HPWM, rather than software PWM), here is some code. Not sure how clean my sine wave is, but it doesn't look too bad on the scope. Might be better if I trim the leads on the breadboard filter. Hopefully someone can have some fun with it. I have a feeling it might be smoother in DT_INTS using an ASM interrupt routine, so that is where I am headed next, thanks to Darrel and Bruce. Will try to give that a shot.

Code:
; Circuit Diagram:
; PIC18F2431
; Filter Diagram
;
; 2.7k 2.7k
; RC2 ___/\ /\ /\______/\ /\ /\________ Analog Output
; \/ \/ | \/ \/ |
; | |
; ----- 0.1uF ----- 0.1uF
; ----- -----
; | |
; GND GND
;
;
define OSC 40
asm
__CONFIG _CONFIG1H, _OSC_HSPLL_1H
__CONFIG _CONFIG2H, _WDTEN_OFF_2H & _WDPS_512_2H
__CONFIG _CONFIG4L, _LVP_OFF_4L
endasm
ADCON0 = 000000
ADCON1 = 000000
trisb = 111111
trisc = 111011
trisa = 111111
TMR2 = 16
PR2 = 129 ;set for 19.2Khz HPWM
LED1 var portC.1
LED2 var portC.3
Duty var word
CCP1CON.3 = 1 ' set to pwm mode
CCP1CON.2 = 1
T2CON.2=1
T2CON.0=1
STEPCOUNT var byte
stepcount = 32
; Set sine "table" in an array
sineval var byte[33]
sineval[1] = 128
sineval[2] = 148
sineval[3] = 167
sineval[4] = 185
sineval[5] = 200
sineval[6] = 213
sineval[7] = 222
sineval[8] = 228
sineval[9] = 230
sineval[10] = 228
sineval[11] = 222
sineval[12] = 213
sineval[13] = 200
sineval[14] = 185
sineval[15] = 167
sineval[16] = 148
sineval[17] = 128
sineval[18] = 108
sineval[19] = 89
sineval[20] = 71
sineval[21] = 56
sineval[22] = 43
sineval[23] = 34
sineval[24] = 28
sineval[25] = 26
sineval[26] = 28
sineval[27] = 34
sineval[28] = 43
sineval[29] = 56
sineval[30] = 71
sineval[31] = 89
sineval[32] = 108
timerone var word
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
include "ReEnterPBP-18.bas"
;LOW LED1
;high led2
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _sine, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
T1CON = $31 ; Prescaler = 8, TMR1ON
TMR1L = 255
TMR1H = 254
@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
timerone = $FD85 ;gives about 60 htz sine
Main:
pause 5
'timerone = timerone - 1 'uncomment to vary 60hz sine
if timerone = $F9FF then timerone = $FF00
GOTO Main
'---[TMR1_INT - interrupt handler]------------------------------------------
sine:
TMR1L = timerone.byte0
TMR1H = timerone.byte1
CCPR1L = sineval[STEPCOUNT]>>1
stepcount = stepcount -1
if stepcount = 0 then stepcount = 32
@ INT_RETURN
And changing the frequency of the sine (uncomment one line):
Bookmarks