Code:
ClearWDT
DEFINE OSC 20
Phase VAR BYTE[3] ' Array used as pointers into lookuptable.
DutyCycle VAR WORD[3] ' Array storing the dutycycles retreived from the table
Temp VAR WORD ' Temporary variable to avoid hard to understand array indexing
i VAR BYTE ' General purpose counter
TRISC.2 = 0 ' Set PORTC.2 (CCP1) to output
TRISC.1 = 0 ' Set PORTC.1 (CCP2) to output
TRISB.5 = 0 ' Set PORTB.5 (CCP3) to output
CCP1CON = %00001100 ' Set CCP1 to PWM
CCP2CON = %00001100 ' Set CCP2 to PWM
CCP3CON = %00001100 ' Set CCP3 to PWM
T2CON = %00000101 ' Turn on Timer2, Prescale=4
PR2 = 249 ' Set PR2 to get 5KHz out
ADCON1 = 7 ' Set All PortB to Digital port
' The lookup table has 50 entries long, to get 120° phase shift we need to
' "start" the second phase at 1/3 of the cycle and the third phase at 2/3
' of the table. 50/3=15 so first phase starts at 0, second phase at 15
' and third phase at 30.
' Initilise pointers.
Phase[0] = 0 : Phase[1] = 17 : Phase[2] = 34
High PORTC.3 'Set the initial state for portc.3
Low PORTC.0 'Same
High PORTC.6 'Same
Low PORTC.5 'Same
High PORTB.4 'Same
Low PORTB.3 'Same
Main:
if portb.2=1 then
GoSub GetDuty ' Retrieve the dutycycle values for all three phases
GoSub SetDutyCycle ' Set the three PWM modules accordingly
' Now increment the individual table pointers and make sure they wrap
' around to zero when they reach the end of the table. That way they
' will always stay 17 "steps" (120°) from each other.
For i = 0 TO 2
Phase[i] = Phase[i] + 1
IF Phase[i] > 50 Then
Phase[i] = 0 'When pointer is > 50 we need to wrap around to 0.
GoSub ChangeBridgeDrive 'One phase is starting over, go change the outputs.
EndIF
Next
PauseUs 77 'Use each duty cycle for 85us before going to another
endif
if portb.2=0 then
gosub GetDutyWhenFault
endif
GoTo Main
SetDutyCycle:
' Get value from the array of dutycycles and put it in the dutycycle
' registers of the 3 PWM modules. We could have used the array directly
' but this way (using a Temp variable) is easier to understand.
Temp = DutyCycle[0] ' Get dutycyle for phase 1 from the array and store in temp.
CCP1CON.4 = Temp.0 ' Set the LSB's
CCP1CON.5 = Temp.1
CCPR1L = Temp >> 2 ' Set the 8 high bits
Temp = DutyCycle[1] ' Same procedure.
CCP2CON.4 = Temp.0
CCP2CON.5 = Temp.1
CCPR2L = Temp >> 2
Temp = DutyCycle[2] ' Same procedure.
CCP3CON.4 = Temp.0
CCP3CON.5 = Temp.1
CCPR3L = Temp >> 2
Return
GetDutyWhenFault:
Temp = 0 ' Set dutycyle for phase 1 to 0%.
CCP1CON.4 = Temp.0 ' Set the LSB's
CCP1CON.5 = Temp.1
CCPR1L = Temp >> 2 ' Set the 8 high bits
Temp = 0 ' Same procedure for phase 2
CCP2CON.4 = Temp.0
CCP2CON.5 = Temp.1
CCPR2L = Temp >> 2
Temp = 0 ' Same procedure for phase 3
CCP3CON.4 = Temp.0
CCP3CON.5 = Temp.1
CCPR3L = Temp >> 2
return
' -----------------------
'-------------------------------------------------------
' ---- Subroutine to retreive the three dutycycle values from the table.
' ---- Values will be stored in the DutyCycle array.
' ------------------------------------------------------------------------------
GetDuty:
' This For-Next loop runs three times. Each time it gets the value from the lookuptable
' that Phase[i] is pointing at. The Phase array pointers are incremented in the main loop
' and are always 15 "steps" appart so that a 120° phase shift is preserved.
For i = 0 TO 2
LookUp2 Phase[i], [0,60,130,190,250,310,370,430,480,540,590,640,690,730,770,810,840,870,_
910,930,950,970,980,990,1000,1000,1000,990,980,970,950,930,910,870,840,810,770,730,690,_
640,590,540,480,430,370,310,250,190,130,60,0],Temp
' Lookup2 can't handle an array as the designator so we need to
' put the value in a temporary variable first and then move
' it to the array of dutycycles.
DutyCycle[i] = Temp
Next
Return
ChangeBridgeDrive:
' When we come here the value i contains the phase counter that just got reset so we
' can use that to determine for which phase we should switch the outputs.
Select Case i
Case 0 ' It was Phase 1 that rolled over
Toggle PORTC.3 ' Invert the state of the pin
Toggle PORTC.0 ' Invert the state of the pin
Case 1 ' It was Phase 2 that rolled over
Toggle PORTC.5 ' Invert the state of the pin
Toggle PORTC.6 ' Invert the state of the pin
Case 2 ' It was Phase 3 that rolled over
Toggle PORTB.4 ' Invert the state of the pin
Toggle PORTB.3 ' Invert the state of the pin
End Select
Return
End
thanks
Bookmarks