I've tested your code, and the results are quite encouraging.
Some tests I've done :
For each, INTF/Output=678, so it's "linear" now.INTF=38000 Output=56Hz
INTF=35000 Output=51.6Hz
INTF=30000 Output=44.3Hz
But when the interrupt frequency is above ~39060Hz, the ReloadTimer jumps from ~62975 to ~63405 ! Of course, the sines jumps ~10Hz upper.
Code:' PIC initialization DEFINE OSC 40 DEFINE LCD_DREG PORTC DEFINE LCD_EREG PORTD DEFINE LCD_RSREG PORTD DEFINE LCD_EBIT 0 DEFINE LCD_RSBIT 1 DEFINE LCD_COMMANDUS 4000 DEFINE LCD_DATAUS 1000 ' BAS includes INCLUDE "DT_INTS-18.bas" INCLUDE "ReEnterPBP-18.bas" INCLUDE "Sine_table.bas" ' Port registers configuration TRISB=%11000000 ' PWM 0,1,2,3,4,5 outputs TRISC=%00110000 ' +/- buttons ' PCPWM registers configuration DTCON=%110 ' Deadtime (600ns) PTCON0=%0 ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode PTCON1=%10000000 ' PWM time base is ON, counts up, 19.45kHz/4 PWMCON0=%1000000 ' PWM 0,1,2,3,4,5 set in pair mode PWMCON1=%1 ' PWM timer sync configuration ' PWM calculation variables ustep var byte vstep var byte wstep var byte uduty var word vduty var word wduty var word amplitude var word carrier VAR word flag var bit ' Variables definition ustep=90 ' 360 degrees phase angle vstep=60 ' 240 degrees phase angle wstep=30 ' 120 degrees phase angle amplitude=65535 ' Sinewave amplitude adjust (65535=max amplitude) carrier=1023 ' Carrier frequency adjust (1023=13kHz) flag=0 ' Menu flag ' PWM carrier frequency register configuration PTPERL=carrier.lowbyte PTPERH=carrier.highbyte InterruptFrequency VAR WORD Dummy VAR WORD Dummy2 VAR WORD Dummy3 VAR WORD TMRCopy VAR WORD TimerReloadValue VAR WORD InterruptFrequency = 38000 ' Interrupt processors ASM INT_LIST macro INT_Handler TMR1_INT,_pwmint,PBP,yes endm INT_CREATE ENDASM ' Interrupts enable @INT_ENABLE TMR1_INT T1CON.0=1 recalc: Dummy2 = 10000 Dummy3 = 10000 Dummy = Dummy2 * Dummy3 TimerReloadValue = Div32 InterruptFrequency TimerReloadValue = 65535 - TimerReloadValue + 1 ' Main program loop mainlp: flag=0 LCDOUT $FE,2,"F: ", #InterruptFrequency lcdout $FE, $C0," R: ", #TimerReloadValue if PORTC.4=1 then InterruptFrequency=InterruptFrequency-1 : flag=1 if PORTC.5=1 then InterruptFrequency=InterruptFrequency+1 : flag=1 if flag=1 then goto recalc goto mainlp ' PWM calculation and update interrupt (Timer 1) pwmint: T1CON.0 = 0 ' Stop TMR1 TMRCopy.HighByte = TMR1H ' Copy value of TMR1 registers TMRCopy.LowByte = TMR1L TMRCopy = TMRCopy + TimerReloadValue ' Add reload value (compensates for overhead) TMR1H = TMRCOPY.HighByte ' And back to TMR1 TMR1L = TMRCopy.LowByte T1CON.0 = 1 ' Restart Timer ' PWM U phase calculation uduty=sine[ustep] uduty=uduty<<4**amplitude ' PWM V phase calculation vduty=sine[vstep] vduty=vduty<<4**amplitude ' PWM W phase calculation wduty=sine[wstep] wduty=wduty<<4**amplitude ' PWM U, V and W update PDC0L=uduty.lowbyte PDC0H=uduty.highbyte PDC1L=vduty.lowbyte PDC1H=vduty.highbyte PDC2L=wduty.lowbyte PDC2H=wduty.highbyte ' Phase angle calculation ustep=ustep-1 vstep=vstep-1 wstep=wstep-1 ' Phase angle reinitialization if ustep=0 then ustep=90 if vstep=0 then vstep=90 if wstep=0 then wstep=90 @INT_RETURN





Bookmarks