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.
And changing the frequency of the sine (uncomment one line):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




Bookmarks