
Originally Posted by
HenrikOlsson
Hi,
Interrupt frequency of 39060Hz?
Previously you said you wanted an output of 120Hz and with 72 steps per sin-cycle that's 120*72=8640Hz interrupt frequency. The math is then like this
65535 - (10,000,000 / 8640) + 1 = 64378
64378 is what the timer reload value is and this means that there's 65536-64378=1158 cycles between interrupts. 1158 cycles times 100ns per cycle equals 115.8us between interrupts 1/115.8us = 8635Hz so it's pretty close.
This means that there's only 1158 cycles (or instructions if you will) between interrupts. In this time the PIC has to save all the PBP system variables, reload the timer, execute your interrupt service routine and then restore all the PBP system variables.
Why are you trying to interrupt at ~39kHz? That's only about 256 cycles between interrupts which I'm pretty sure won't be enough time to do all that needs to get done in the interrupt.
Finally, this line:
Code:
If PortC.4 = 1 Then InterruptFrequency = InterruptFrequency -1 : Flag = 1
Probably doesn't work like you think. Here,
Flag gets set no matter what the state of of PortC.4 actually is. So you are always running the recalc routine. If you want Flag to be set
only when PortC.4 is high you need to change it to:
Code:
If PortC.4 = 1 THEN
InterruptFrequency = InterruptFrequency - 1
Flag = 1
ENDIF
Well, for 120Hz, I need an interrupt frequency of 120*90=10800Hz.
If I configure this in my program, I get output sines of only ~16Hz.
So what's wrong?
The code :
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
Dummy VAR WORD
Dummy2 VAR WORD
Dummy3 VAR WORD
InterruptFrequency VAR WORD
TMRCopy VAR WORD
TimerReloadValue VAR WORD
' 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
Dummy2 = 10000
Dummy3 = 10000
InterruptFrequency = 10800
' PWM carrier frequency register configuration
PTPERL=carrier.lowbyte
PTPERH=carrier.highbyte
' 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:
Dummy = Dummy2 * Dummy3
TimerReloadValue = Div32 InterruptFrequency
TimerReloadValue = 65535 - TimerReloadValue + 1
flag=0
' Main program loop
mainlp:
LCDOUT $FE,2,"F: ",#InterruptFrequency
lcdout $FE,$C0,"R: ",#TimerReloadValue
if PORTC.4=1 then
InterruptFrequency=InterruptFrequency-1
flag=1
ENDIF
if PORTC.5=1 then
InterruptFrequency=InterruptFrequency+1
flag=1
ENDIF
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
The "flag" problem is corrected now, I can change frequency during runtime.
And there is my sine table (if needed) :
Code:
' Sine table (4 degrees/step, 90*4=360 degrees)
sine var byte[90]
sine[1]=128
sine[2]=137
sine[3]=146
sine[4]=155
sine[5]=163
sine[6]=172
sine[7]=180
sine[8]=188
sine[9]=196
sine[10]=203
sine[11]=210
sine[12]=217
sine[13]=223
sine[14]=229
sine[15]=234
sine[16]=239
sine[17]=243
sine[18]=247
sine[19]=250
sine[20]=252
sine[21]=254
sine[22]=255
sine[23]=255
sine[24]=255
sine[25]=255
sine[26]=254
sine[27]=252
sine[28]=250
sine[29]=247
sine[30]=243
sine[31]=239
sine[32]=234
sine[33]=229
sine[34]=223
sine[35]=217
sine[36]=210
sine[37]=203
sine[38]=196
sine[39]=188
sine[40]=180
sine[41]=172
sine[42]=163
sine[43]=155
sine[44]=146
sine[45]=137
sine[46]=128
sine[47]=119
sine[48]=110
sine[49]=101
sine[50]=93
sine[51]=84
sine[52]=76
sine[53]=68
sine[54]=60
sine[55]=53
sine[56]=46
sine[57]=39
sine[58]=33
sine[59]=27
sine[60]=22
sine[61]=17
sine[62]=13
sine[63]=9
sine[64]=6
sine[65]=4
sine[66]=2
sine[67]=1
sine[68]=0
sine[69]=0
sine[70]=1
sine[71]=2
sine[72]=4
sine[73]=6
sine[74]=9
sine[75]=13
sine[76]=17
sine[77]=22
sine[78]=27
sine[79]=33
sine[80]=39
sine[81]=46
sine[82]=53
sine[83]=60
sine[84]=68
sine[85]=76
sine[86]=84
sine[87]=93
sine[88]=101
sine[89]=110
sine[90]=119
Bookmarks