I changed the interrupt service routine type to be ASM to speed things up a bit. I had not realized that this could be done under certain conditions. As long as I am not multiplying or dividing in the service routine, it is ok to use PBP statements in an ASM type ISR. See Darrel's explanation here: http://www.picbasic.co.uk/forum/show...2454#post82454 for more info. For three phase Power Control PWM , check out http://www.scalerobotics.com/72-how-...nterrupts.html
; Circuit Diagram: ; using PIC18F2431 RC2 pin ; 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 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" ;not needed for ASM type interrupt service routines ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _sine, ASM, 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
-Walter

And for dual phase sine:
I need to work on the filter for this one. Had to change the step range from 32 steps to 36 steps, so I could get 120 degrees separation from the two sines. Now the R/C filter needs to be adjusted.
; Circuit Diagram: ; using PIC18F2431 RC2 pin (first sine) and RC1 pin (second sine wave) ; 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 clear ADCON0 = 000000 ADCON1 = 000000 trisb = 111111 trisc = 111001 trisa = 111111 TMR2 = 16 PR2 = 115 ;set for 21.6Khz HPWM (=36 steps*10 times*60htz) CCP1CON.3 = 1 ' set to pwm mode CCP1CON.2 = 1 CCP2CON.3 = 1 ' set to pwm mode CCP2CON.2 = 1 T2CON.2=1 T2CON.0=1 STEPCOUNT var byte stepcount = 36 stepcount2 var byte duty var word stepcount2 =24 'set start of 2nd sine wave 120 degrees off from first sine ; Set sine "table" in an array ; each step represents 10 degrees sineval var byte[37] sineval[1] = 128 ;0 degrees sineval[2] = 146 ;10 degrees sineval[3] = 163 sineval[4] = 179 sineval[5] = 194 sineval[6] = 206 sineval[7] = 216 sineval[8] = 224 sineval[9] = 228 sineval[10] = 230 ;90 degrees sineval[11] = 228 sineval[12] = 224 sineval[13] = 216 ;120 degrees sineval[14] = 206 sineval[15] = 194 sineval[16] = 179 sineval[17] = 163 sineval[18] = 146 sineval[19] = 128 ;180 degrees sineval[20] = 110 sineval[21] = 93 sineval[22] = 77 sineval[23] = 62 sineval[24] = 50 sineval[25] = 40 sineval[26] = 32 sineval[27] = 28 sineval[28] = 26 sineval[29] = 28 sineval[30] = 32 sineval[31] = 40 sineval[32] = 50 sineval[33] = 62 sineval[34] = 77 sineval[35] = 93 sineval[36] = 110 timerone var word portc.0 = 1 INCLUDE "DT_INTS-18.bas" ; Base Interrupt System ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _sine, ASM, yes endm INT_CREATE ; Creates the interrupt processor ENDASM T1CON = $01 ; Prescaler = 8, TMR1ON TMR1L = 255 TMR1H = 254 @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts timerone = 60950 ;gives about 60 htz sine Main: @ NOP GOTO Main '---[TMR1_INT - interrupt handler]------------------------------------------ sine: TMR1L = timerone.byte0 TMR1H = timerone.byte1 duty = sineval[STEPCOUNT] CCPR1L = Duty >> 1 CCPR2L = sineval[stepcount2] >>1 stepcount = stepcount -1 stepcount2 = stepcount2 - 1 if stepcount2 = 0 then stepcount2 =36 if stepcount = 0 then stepcount = 36 @ INT_RETURN
; Circuit Diagram for triple phase sine wave ; using PIC18F2431 RB1, RB3 and RB5 pins ; Filter Diagram (needs one for each pin, so times 3) ; ; 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 clear ADCON0 = 000000 ADCON1 = 000000 portb=0 trisb = 000000 trisc = 000010 trisa = 000000 DTCON = 000101 'dead time for complimentary ouputs PTCON0 = 000000 '1:1 postscale, Fosc/4 1:1 prescale, free running mode PTPERL = 206 'for 21.6khz PTPERH = 1 PWMCON0 =010100 'PWM[5:0] ouputs enabled PWMCON1 = 1 'updates enabled, overrides sync w/timebase PTCON1 = 000000 'PWM timebase is on, counts up FLTCONFIG = 000010 'disable fault A, cycle by cycle mode STEPCOUNT1 var byte stepcount2 var byte stepcount3 var byte stepcount1 = 36 'offset start steps for multiple sine waves stepcount2 = 24 'set start of 2nd sine wave 120 degrees off from first sine stepcount3 = 12 duty1 var word duty2 var word duty3 var word ; Set sine "table" in an array ; each step represents 10 degrees sineval var byte[37] sineval[1] = 128 ;0 degrees sineval[2] = 146 ;10 degrees sineval[3] = 163 sineval[4] = 179 sineval[5] = 194 sineval[6] = 206 sineval[7] = 216 sineval[8] = 224 sineval[9] = 228 sineval[10] = 230 ;90 degrees sineval[11] = 228 sineval[12] = 224 sineval[13] = 216 ;120 degrees sineval[14] = 206 sineval[15] = 194 sineval[16] = 179 sineval[17] = 163 sineval[18] = 146 sineval[19] = 128 ;180 degrees sineval[20] = 110 sineval[21] = 93 sineval[22] = 77 sineval[23] = 62 sineval[24] = 50 sineval[25] = 40 sineval[26] = 32 sineval[27] = 28 sineval[28] = 26 sineval[29] = 28 sineval[30] = 32 sineval[31] = 40 sineval[32] = 50 sineval[33] = 62 sineval[34] = 77 sineval[35] = 93 sineval[36] = 110 timerone var word portc.0 = 0 INCLUDE "DT_INTS-18.bas" ; Base Interrupt System ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _sine, ASM, yes endm INT_CREATE ; Creates the interrupt processor ENDASM T1CON = $01 ; Prescaler = 8, TMR1ON timerone = 60950 ;gives about 60 htz sine @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts Main: @ NOP GOTO Main '---[TMR1_INT - interrupt handler]------------------------------------------ sine: TMR1L = timerone.byte0 TMR1H = timerone.byte1 duty1 = sineval[STEPCOUNT1] duty1 = duty1 <<2 PDC2L = duty1.lowbyte PDC2H = duty1.highbyte duty2 = sineval[STEPCOUNT2] duty2 = duty2 <<2 PDC0L = duty2.lowbyte PDC0H = duty2.highbyte duty3 = sineval[STEPCOUNT3] duty3 = duty3 <<2 PDC1L = duty3.lowbyte PDC1H = duty3.highbyte stepcount1 = stepcount1 - 1 stepcount2 = stepcount2 - 1 stepcount3 = stepcount3 - 1 if stepcount1 = 0 then stepcount1 = 36 if stepcount2 = 0 then stepcount2 = 36 if stepcount3 = 0 then stepcount3 = 36 @ INT_RETURN
Re: K42 and Timer Interrupts
Thanks for the explanation.
Ioannis - 28th April 2025, 19:28I misinterpreted these paragraphs. My understanding was to have ASYNC cleared and use Fosc/4.
Ioannis