I've tested your code, and the results are quite encouraging. 
Some tests I've done :
INTF=38000 Output=56Hz
INTF=35000 Output=51.6Hz
INTF=30000 Output=44.3Hz
For each, INTF/Output=678, so it's "linear" now.
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