PDA

View Full Version : 6 HPWM signal generation with PIC18F4431



pxidr84
- 10th February 2011, 20:22
Hi there,

I'm currently making a 3-phase variable frequency drive.
I'm using the PIC18F4431 (5V - 40 pins - 40MHz), who's perfect for motor control (8 hardware PWM outputs).

Datasheet : http://ww1.microchip.com/downloads/en/DeviceDoc/39616d.pdf

I like to generate 3 high-side hardware PWM (HU, HV, HW) and 3 low-side hardware PWM (LU, LV, LW - same as HU, HV, HW but inverted with a low deadtime) for fed my high and low-side IGBTs.
I would like a PWM carrier frequency between 2 and 20kHz (approx.)

Picbasic Pro seems to use CCP1 and CCP2 modules with "HPWM" command, but I get only 2 HPWM outputs.
I have no idea how to use these hardware PWM modules on my PIC.

Thanks for your help.

HenrikOlsson
- 10th February 2011, 20:38
Hi,
PBP (the HPWM command) only suports PWM thru the standard CCP modules, you'll have to set up the PWM registers manually. A quick search for 18F4431 on the forum brings up a couple of threads, this one (http://www.picbasic.co.uk/forum/showthread.php?t=7095&highlight=18F4431) for example, contains some sample code from Bruce which may serve as a starting point.

pxidr84
- 10th February 2011, 20:43
Hi,
PBP (the HPWM command) only suports PWM thru the standard CCP modules, you'll have to set up the PWM registers manually. A quick search for 18F4431 on the forum brings up a couple of threads, this one (http://www.picbasic.co.uk/forum/showthread.php?t=7095&highlight=18F4431) for example, contains some sample code from Bruce which may serve as a starting point.

Thanks, I will take a look.

pxidr84
- 11th February 2011, 23:32
Okay, I've a little bit modified the Bruce's program.
It runs well in ISIS Proteus with my defined duty cycles, and all of the 6 PWM outputs works.

But there is a little problem :
http://i53.tinypic.com/wu0bh0.jpg

As you can see, U and W phases are working properly, but not the V phase (the low-side PWM is not inverted like the others).

Here's my modified code :

DEFINE LOADER_USED 1
DEFINE OSC 20

' At 20MHz, to figure a PWM frequency of 19.455kHz
' TPWM = time period of PWM frequency
' PTPER = 12-bit period register PTPERL and PTPERH
' PTMRPS = PWM time base prescaler
'
' (PTPER+1)*PTMRPS 257
' TPWM = ---------------- = ------------ = 0.0000514
' Fosc/4 5000000
'
' Frequency = 1/TPWM = 1/0.0000514 = 19.455kHz
'
' PWM resolution (bits resolution for duty cycle)
'
' log(20MHz/19.455kHz) 3.01
' Resolution = ------------------ = ----------- = 10 bits
' .301 .301

' so we'll need a word sized var for Duty
uduty VAR WORD
vduty VAR WORD
wduty VAR WORD

PORTB = 0 ' clear port latch
TRISB = %11000000 ' PWM0,1,2,3,4,5 outputs

TRISC = 2 ' RC1 = FLTA input (ground RC1 to halt PWM)
' RC1 should be pulled high for normal PWM operation
' when fault A is enabled.
' PCPWM init
DTCON = %00000101 ' ~500nS dead-time (for complementary outputs only)
PTCON0 = %00000100 ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
' PTCON0 = %00000100 would give 19.45kHz/4
PTPERL = 0 '
PTPERH = 1 ' PTPER = $0100 or 256d for ~19.45kHz

' PWM4,5 independent, PWM0,1,2,3 complementary
PWMCON0 = %01010100 ' PWM[5:0] outputs enabled
PWMCON1 = 1 ' updates enabled, overrides sync w/timebase
PTCON1 = %10000000 ' PWM time base is ON, counts up
FLTCONFIG = %00000011 ' enable fault A, cycle-by-cycle mode


'Phases duty test
uduty = 800 ' ~50%
vduty = 500
wduty = 300

pwmlp: ' PWM update loop

'PWM U phase
PDC0L = uduty.LowByte
PDC0H = uduty.HighByte

'PWM V phase
PDC1L = vduty.LowByte
PDC1H = vduty.HighByte

'PWM W phase
PDC2L = wduty.LowByte
PDC2H = wduty.HighByte

goto pwmlp

Thanks in advance for any advice.

HenrikOlsson
- 12th February 2011, 07:41
Hi,
Are you sure it's not the W-phase output that isn't complementary?

Look at the PWMCON0 register, you have it set to %01010100 which means that PWM0 and PWM1 is in complentary mode while PWM2 (the W-phase according to your code) is in independant mode.

/Henrik.

pxidr84
- 12th February 2011, 13:33
Hi,
Are you sure it's not the W-phase output that isn't complementary?

Look at the PWMCON0 register, you have it set to %01010100 which means that PWM0 and PWM1 is in complentary mode while PWM2 (the W-phase according to your code) is in independant mode.

/Henrik.

Thanks a lot, you guided me on the right way.
I've read the datasheet, and especially the "PWMCON0" register description. I've modified the value to PWMCON0 = %01000000, and now the 3 phases are working very well (the low-side V phase is now inverted properly).

Now, I've to modify the duty according to a sinus function. I think about it.

pxidr84
- 12th February 2011, 21:22
A last question : I've doubts about the duty cycle. What's the exact range of the duty cycle?

If I define a duty cycle between 0-10, the simulator oscilloscope gives me weird things (the inverted signal "jumps")...
If I define a duty cycle above 1023, same thing...

The code used :

' At 20MHz, to figure a PWM frequency of 19.455kHz
' TPWM = time period of PWM frequency
' PTPER = 12-bit period register PTPERL and PTPERH
' PTMRPS = PWM time base prescaler
'
' (PTPER+1)*PTMRPS 257
' TPWM = ---------------- = ------------ = 0.0000514
' Fosc/4 5000000
'
' Frequency = 1/TPWM = 1/0.0000514 = 19.455kHz
'
' PWM resolution (bits resolution for duty cycle)
'
' log(20MHz/19.455kHz) 3.01
' Resolution = ------------------ = ----------- = 10 bits
' .301 .301

'PIC initialization
DEFINE LOADER_USED 1
DEFINE OSC 40

'Port registers configuration
PORTB = 0 ' Clear ports
TRISB = %11000000 ' PWM 0,1,2,3,4,5 outputs
TRISC = 2 ' RC1 = FLTA input (ground RC1 to halt PWM), pull-up resistor on RC1

'PCPWM registers configuration
DTCON = %00001010 ' Deadtime (500ns)
PTCON0 = %00000100 ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
PTCON1 = %10000000 ' PWM time base is ON, counts up, 19.45kHz/4
PTPERL = 0 ' PWM low-side
PTPERH = 1 ' PWM high-side

'PWM registers configuration
PWMCON0 = %01000000 'PWM 0,1,2,3,4,5 set in pair mode
PWMCON1 = %00000001 'PWM timer sync configuration
FLTCONFIG = %00000011 'Fault configuration

'U, V and W duty variables
uduty VAR WORD
vduty VAR WORD
wduty VAR WORD

'Phases duty
uduty = 1
vduty = 1000
wduty = 1000

pwmlp: ' PWM update loop

'PWM U phase
PDC0L = uduty.LOWbyte
PDC0H = Uduty.HIGHByte

'PWM V phase
PDC1L = vduty.LOWbyte
PDC1H = vduty.HIGHByte

'PWM W phase
PDC2L = wduty.LOWbyte
PDC2H = wduty.HIGHByte

goto pwmlp

HenrikOlsson
- 12th February 2011, 22:35
Hi,
The available resolution depends on the actual PWM frequency, you can see in the code how Bruce has calculated it for you. If you haven't changed the code the resolution is 10 bits (0-1023).

The PCPWM module have a configurable dead-time generator which inserts a deadtime between turning off the upper switch and turning on the lower switch. When aproaching the "ends" of the available resolution this can distort the output waveform and I suspect that is what you're seeing.

If you don't need deadtime you can turn it off. If you do need deadtime you should make sure that the dutycyle never aproaches the values where you're starting to see distortion. You usually can't use extreme dutycycles anyway due to the MOSFET/IGBT highside drivers need to refresh its bootstrap capacitor charge.

pxidr84
- 19th February 2011, 11:03
Okay, the code is now capable to calculate 3 sine waves (one for each phase).

I can modify the frequency (by increasing or decreasing freqdiv), but I've difficulties to set a phase angle (0-120-240° for U, V and W respectively) and I've difficulties to set a sinus amplitude (for exemple, if I want a 0-50% dutycycle, I will write uduty=uduty*0.5, but PBP does not support float maths).

Thanks for your help. I use Darrel Taylor's interrupt system for sine-wave generation loop.


'PIC initialization
DEFINE LOADER_USED 1
DEFINE OSC 40


'DT interrupt system include
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts


'PWM calculation variables
uduty VAR WORD 'U phase duty
vduty VAR WORD 'V phase duty
wduty VAR WORD 'W phase duty
t VAR byte 'Incremental value


'Inverter U/F variables
freqdiv var WORD 'Frequency diviser
FREQdiv=0 'Range : 0-65535


'Port registers configuration
PORTB=%0 ' Clear ports
TRISB=%11000000 ' PWM 0,1,2,3,4,5 outputs


'PCPWM registers configuration
DTCON=%110 ' Deadtime (600ns)
PTCON0=%100 ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
PTCON1=%10000000 ' PWM time base is ON, counts up, 19.45kHz/4
PTPERL=%0 ' PWM low-side
PTPERH=%1 ' PWM high-side


'PWM registers configuration
PWMCON0=%1000000 'PWM 0,1,2,3,4,5 set in pair mode
PWMCON1=%1 'PWM timer sync configuration


'Interrupt processor
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag
INT_Handler TMR1_INT, _pwmint, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM


'Timer configuration
T1CON=%10000001 ; Prescaler = 1:1, TMR1ON, 16-bit counter
@ INT_ENABLE TMR1_INT ; Enable Timer 1 interrupts


'Main loop
mainlp:

pause 1000

goto mainlp

'PWM calculation and update interrupt
pwmint:
t=0

for T=0 to 255 step 1

'Frequency diviser
pauseus freqdiv

'PWM U phase calculation
uduty=((sin(t)+128)*4)

'PWM V phase calculation
vduty=((sin(t)+128)*4)

'PWM W phase calculation
wduty=((sin(t)+128)*4)

'PWM U phase update
PDC0L=uduty.LOWbyte
PDC0H=Uduty.HIGHByte

'PWM V phase update
PDC1L=vduty.LOWbyte
PDC1H=vduty.HIGHByte

'PWM W phase update
PDC2L=wduty.LOWbyte
PDC2H=wduty.HIGHByte

next t

@ INT_RETURN

HenrikOlsson
- 19th February 2011, 11:30
Hi,
How about:

'PWM U phase calculation
uduty=((sin(t)+128)*4)

'PWM V phase calculation
vduty=((sin(t+85)+128)*4)

'PWM W phase calculation
wduty=((sin(t+170)+128)*4
5180

It's true that you can't mutliply by 0.5 but you can divide by 2. You can also use the ** operator to multiply by units of 1/65536 so instead of doing x=y*0.72 you do x=y**47186 (where 47186 comes from 65536*0.72)

/Henrik.

pxidr84
- 19th February 2011, 12:50
Hi,
How about:

'PWM U phase calculation
uduty=((sin(t)+128)*4)

'PWM V phase calculation
vduty=((sin(t+85)+128)*4)

'PWM W phase calculation
wduty=((sin(t+170)+128)*4
5180

It's true that you can't mutliply by 0.5 but you can divide by 2. You can also use the ** operator to multiply by units of 1/65536 so instead of doing x=y*0.72 you do x=y**47186 (where 47186 comes from 65536*0.72)

/Henrik.

Thanks a lot for your tips :rolleyes:
Just a question : what simulator are you using ? (because my ISIS Proteus gives me very weird results):

http://img233.imageshack.us/img233/4387/isisr.jpg

It's your code with angle phase offsets...

HenrikOlsson
- 19th February 2011, 14:11
Hi,
I'm not using a simulator, I just sent the values to the PC and plotted them with EXCEL. Here's the exact code I used to test with:

DEFINE LOADER_USED 1
DEFINE OSC 20
DEFINE HSER_BAUD 19200

i VAR BYTE
T VAR BYTE
uDuty VAR WORD
vDuty VAR WORD
wDuty VAR WORD

Main:
For i = 0 to 2 'Make three periods
T=0

for T=0 to 255
' PWM U phase calculation
uduty=((sin(t)+128)*4)

' PWM V phase calculation
vduty=((sin(t+85)+128)*4)

' PWM W phase calculation
wduty=((sin(t+170)+128)*4)

HSEROUT [DEC uDUTY, ",", dec vDUTY, ",", dec wDUTY, 13]
next
NEXT
WereDone:
Goto WereDone

Try removing C3, C6 and C8 to start with.

pxidr84
- 19th February 2011, 17:07
Hi,
I'm not using a simulator, I just sent the values to the PC and plotted them with EXCEL. Here's the exact code I used to test with:

DEFINE LOADER_USED 1
DEFINE OSC 20
DEFINE HSER_BAUD 19200

i VAR BYTE
T VAR BYTE
uDuty VAR WORD
vDuty VAR WORD
wDuty VAR WORD

Main:
For i = 0 to 2 'Make three periods
T=0

for T=0 to 255
' PWM U phase calculation
uduty=((sin(t)+128)*4)

' PWM V phase calculation
vduty=((sin(t+85)+128)*4)

' PWM W phase calculation
wduty=((sin(t+170)+128)*4)

HSEROUT [DEC uDUTY, ",", dec vDUTY, ",", dec wDUTY, 13]
next
NEXT
WereDone:
Goto WereDone

Try removing C3, C6 and C8 to start with.

In reality, I think that my RC filter in Proteus is bad.

If I watch the raw PWM outputs, it seems perfectly good (with correct phase angles and duty cycles). However, in extreme duty (like 0 or 1023), the PWM "jumps" (like before, I think it's a sim issue, I will try the PIC in the real life with an oscilloscope).

In other words, my code is working quite well now, thanks for the "**", I didn't know this operator before, until now.

HenrikOlsson
- 19th February 2011, 17:38
Hi,
Like I said in an earlier post, I think it is the dead-time insertion that makes the waveform "jump" at the extreme ends. Do try it with real hardware and let us know how it goes. Just remember that if you low-pass filter the PWM to watch it on a scope might not see any artifacts introduced by the deadtime insertion - if indeed that is what's causing it. So make sure you watch the "raw" PWM signals as well in order to see if it behaves as in the simulator.

As a simple test, try removing the deadtime insertion from the code and see if it still looks strange in the simulator.

/Henrik.

pxidr84
- 19th February 2011, 22:26
Hi,
Like I said in an earlier post, I think it is the dead-time insertion that makes the waveform "jump" at the extreme ends. Do try it with real hardware and let us know how it goes. Just remember that if you low-pass filter the PWM to watch it on a scope might not see any artifacts introduced by the deadtime insertion - if indeed that is what's causing it. So make sure you watch the "raw" PWM signals as well in order to see if it behaves as in the simulator.

As a simple test, try removing the deadtime insertion from the code and see if it still looks strange in the simulator.

/Henrik.

Yes, of course I've readed your post above. I've modified the code (add +3 to the end of each line), now the PWM signal doesn't "jump" anymore.
However, if I remove the deadtime or even modify it, the jumpy PWM remains.

Now signals are better, but sine are not perfect for the highest frequencies, I think that my low-pass filter hasn't good R and C values (1k and 1000nF).

http://img832.imageshack.us/img832/9530/isis2d.jpg

senertek
- 20th February 2011, 09:27
hi ,
I have already developped many ac inverters range 0.75 kw to 915 kw..with . I seen this thread ..it s very good..to see picbasic projects in this field....
Designing one 3 phase ac inverter is not easy project...you must know many kind of points about high voltage igbt , drivers , dcbus topologys ,emc ,emi , multi tasking etc...(it take many years)
If you want , I can help for your project..
I can try your codes with my high voltage kits , igbt driver modules ...and inform you ..codes works or not...

savas

pxidr84
- 20th February 2011, 10:49
hi ,
I have already developped many ac inverters range 0.75 kw to 915 kw..with . I seen this thread ..it s very good..to see picbasic projects in this field....
Designing one 3 phase ac inverter is not easy project...you must know many kind of points about high voltage igbt , drivers , dcbus topologys ,emc ,emi , multi tasking etc...(it take many years)
If you want , I can help for your project..
I can try your codes with my high voltage kits , igbt driver modules ...and inform you ..codes works or not...

savas

Thanks.

Well, I'm doing studies in electrical engineering, so I've a litte knowledge about this. :)
I'm using an intelligent IGBT module from STMicroelectronics, the STGIPS20K60 (datasheet : http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00244265.pdf).

No drivers needed (they're integrated), just optocouplers.

pxidr84
- 24th February 2011, 17:00
Ok, a little update.

I've tested the program on the real PIC with an oscilloscope. All of the output signals are correct, but the sine cycle is very slow (about 4 seconds to make a complete sine period, so f=1/4=0,25Hz).
The PWM frequency seems correct (3,245kHz).
I've defined correctly the configuration fuses (or bits), with "HS oscillator" setting, because I'm using a 40MHz quartz oscillator connected to OSC1/OSC2 pins with 22pF ceramic capacitors.

The code (note I'm not using the FOR... NEXT loop in this case, like the upper programs, it's a lot faster if I use the FOR... NEXT loop, but I don't know why) :


'PIC initialization
DEFINE OSC 40
DEFINE LCD_EREG PORTD
DEFINE LCD_DREG PORTD
DEFINE LCD_EBIT 0
DEFINE LCD_RSBIT 1


'DT interrupt system include
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts


'Port registers configuration
PORTB=%0 ' Clear ports
TRISB=%11000000 ' PWM 0,1,2,3,4,5 outputs


'PCPWM registers configuration
DTCON=%110 ' Deadtime (600ns)
PTCON0=%100 ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
PTCON1=%10000000 ' PWM time base is ON, counts up, 19.45kHz/4
PTPERL=%0 ' PWM low-side
PTPERH=%1 ' PWM high-side


'PWM registers configuration
PWMCON0=%1000000 'PWM 0,1,2,3,4,5 set in pair mode
PWMCON1=%1 'PWM timer sync configuration


'Interrupt processor
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag
INT_Handler TMR1_INT, _pwmint, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM


'Timer configuration
T1CON=%10000001 ; Prescaler = 1:8, TMR1ON, 16-bit counter
@ INT_ENABLE TMR1_INT ; Enable Timer 1 interrupts


'PWM calculation variables
uduty VAR WORD 'U phase duty
vduty VAR WORD 'V phase duty
wduty VAR WORD 'W phase duty
dutydiv var WORD 'Frequency diviser
dutymul VAR WORD 'Duty multiplier
t VAR byte 'Incremental value


'Variables definition
dutydiv=0 'Range : 0-65535
dutymul=65535 'Range : 0-65535 (for exemple, 32767=0.5)
t=%0 'T initial value


'Main program loop
mainlp:

HIGH PORTA.0
pause 100
LOW PORTA.0
pause 100

goto mainlp


'PWM calculation and update interrupt
pwmint:

'Frequency diviser
pauseus dutydiv

'PWM U, V, W phases calculation
uduty=(((sin(t)+%01111111)*%100)**dutymul)+%100
vduty=(((sin(t+%01010101)+%01111111)*%100)**dutymu l)+%100
wduty=(((sin(t+%10101010)+%01111111)*%100)**dutymu l)+%100

'PWM U phase update
PDC0L=uduty.LOWbyte
PDC0H=uduty.HIGHByte

'PWM V phase update
PDC1L=vduty.LOWbyte
PDC1H=vduty.HIGHByte

'PWM W phase update
PDC2L=wduty.LOWbyte
PDC2H=wduty.HIGHByte

'T variable verification and incrementation
if t<%11111111 then
t=t+%1
else
t=%0
endif

@ INT_RETURN

I think it's a TIMER problem (TMR1 is at 32kHz, isn't it?)

HenrikOlsson
- 24th February 2011, 18:05
Hi,
Yes, it's probably a timer problem. You have TMR1 set up to derive its clock from the main oscillator (Fosc/4) so 10Mhz in your case. (Your code comments says you have a prescaler of 8 but you don't - it's 1:1.

TMR1 is a 16bit timer and generates an interrupt when it overflows from $FFFF to $0000. In your case this means that the interrupt frequency is 10MHz/65536 = 152.6Hz. In other words, the pwmint interrupt service routine is executed 156 times per second.

If a complete sinus cycle consists of 256 "steps" you should get a frequency of 152.6/256=0.6Hz but you claim 0.25Hz so I'm not sure what's going on exactly.

If you want to speed up the frequency you must increase the interrupt frequency. You do this by preloading TMR1 in the interrupt service routine so that it doesn't have to count all the way from 0. If you, for example, preset it to 32768 you'll get twice as many interrupts per second as when letting it free run.

/Henrik.

pxidr84
- 27th February 2011, 10:38
Thanks Henrik, now I use TMR1L and TMR1H registers, I got a 40 Hz sine (it's better).

I've heavly modified the code, I didn't use the SIN function anymore, but a lookup table with 72 values (5 degrees/value).

Now, for debugging, I want to vary the timer value. For that, I use two buttons, one for increase (PORTC.4), one for decrease (PORTC.5), and then display the value to my LCD.

The LCD works fine, but not the inputs. If I push the buttons, nothing happens. No increase or decrease. Same thing in the simulator.

My 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 10000
DEFINE LCD_DATAUS 1000


' BAS includes
INCLUDE "DT_INTS-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
timer var word
amplitude var word
carrier VAR word


' Variables definition
ustep=72 ' 360 degrees phase angle
vstep=48 ' 240 degrees phase angle
wstep=24 ' 120 degrees phase angle
timer=60950 ' Frequency adjust (60950=80Hz)
amplitude=65535 ' Sinewave amplitude adjust (65535=max amplitude)
carrier=1023 ' Carrier frequency adjust (1023=13kHz)


' PWM carrier frequency register configuration
PTPERL=carrier.lowbyte
PTPERH=carrier.highbyte


' Inverter startup
pause 2000
Lcdout $FE,1
LCDOUT $FE,2,"Varidrive 1.0"
LCDOUT $FE,$C0,"DR Electronique"
pause 2000


' Interrupt processor
ASM
INT_LIST macro
INT_Handler TMR1_INT, _pwmint, ASM, yes
endm
INT_CREATE
ENDASM


' Timer configuration
T1CON=%1
@ INT_ENABLE TMR1_INT


test var word
test=1


' Main program loop
mainlp:

' Debug display
LCDOUT $FE,1
LCDOUT $FE,2,"Timer var :"
LCDOUT $FE,$C0,#test

if PORTC.4=1 then test=test-1
if PORTC.5=1 then test=test+1
pause 100

goto mainlp


' PWM calculation and update interrupt
pwmint:

' Sinewaves frequency
TMR1L=timer.lowbyte
TMR1H=timer.highbyte

' 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=72
if vstep=0 then vstep=72
if wstep=0 then wstep=72

@ INT_RETURN


The faulty code is in bold.

pxidr84
- 2nd March 2011, 11:02
Problem resolved, I will open a new thread.

oswalam
- 1st December 2012, 05:02
hello, i am new to this forum, I am final year electrical engg. student, my project is 'Speed control of Induction motor using PCPWM in PIC18f4431'. Plz guide me how to go about it, i want to write a code for sinusoidal PWM generation using PCPWM in edge aligned mode.

oswalam
- 6th March 2013, 05:00
Which Simulator you people are using for viewing waveforms???? Thanks