Code:
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
TRISB.5 = 0
CCP1CON = %00001100 ' Set CCP1 to PWM
CCP2CON = %00001100
CCP3CON = %00001100
T2CON = %00000101 ' Turn on Timer2, Prescale=4
PR2 = 249 ' Set PR2 to get 5KHz out
' The lookup table has 186 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. 186/3=62 so first phase starts at 0, second phase at 62
' and third phase at 123.
' Initilise pointers.
Phase[0] = 0 : Phase[1] = 15 : Phase[2] = 30
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:
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 62 "steps" (120°) from each other.
For i = 0 TO 2
Phase[i] = Phase[i] + 1
IF Phase[i] > 46 Then
Phase[i] = 0 'When pointer is > 185 we need to wrap around to 0.
GoSub ChangeBridgeDrive 'One phase is starting over, go change the outputs.
EndIF
Next
PauseUs 300
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
' ------------------------------------------------------------------------------
' ---- 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 62 "steps" appart so that a 120° phase shift is preserved.
For i = 0 TO 2
LookUp2 Phase[i], [0,0,70,137,208,275,341,408,470,529,588,643,694,745,788,827,866,898,925,_
953,968,984,996,1000,996,984,968,953,925,898,866,827,788,745,_
694,643,588,529,470,408,341,275,208,137,70,0,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 1 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
please help to advice.
Bookmarks