3 channel PWM with customize duty cycle


Closed Thread
Results 1 to 40 of 57

Hybrid View

  1. #1
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,
    Perhaps you could do something like:
    Code:
    For i = 0 to 2
      Phase(i) = Phase(i) + 1
      If Phase(i) > 185 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
    And the ChangeBridgeDrive subroutine might then look something like:
    Code:
    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 PORTA.1              ' Invert the state of the pin
            TOGGLE PORTA.2              ' Invert the state of the pin
     
        Case 1                          ' It was Phase 2 that rolled over
            TOGGLE PortB.1              ' Invert the state of the pin
            TOGGLE PortB.2              ' Invert the state of the pin
     
     
        Case 2                          ' It was Phase 1 that rolled over
            TOGGLE PortC.1              ' Invert the state of the pin
            TOGGLE PortC.2              ' Invert the state of the pin
     
        END SELECT
     
    RETURN
    Again, it compiles but I've not tested. One concern I have is the time between the two outputs for each halfbridge switching but since the dutycycle is effectively zero at the time of switching there should be no risk of shoot-thru etc. This of course also depends on the design of the hardware which I haven't seen so I'm just raising a warning about it.

    /Henrik.
    Last edited by HenrikOlsson; - 21st April 2011 at 14:54.

  2. #2


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    hi,

    i compile the additional example of yours into my codes and it works ok but at the toggle part dint works well.

    attached is the simulation using the real pic simulation named result:
    as you can see i want it to be the pin rc3 should be high and pin rc0 should be low at 1 cycle but result show both of pin is high.
    i try to change the code a bit into: ( for phase 1 only)

    Code:
    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
            High PORTC.3              ' Invert the state of the pin
            Low PORTC.0              ' Invert the state of the pin
     Toggle PORTC.3
     Toggle PORTC.0
    it end like attached file name result2.
    yes im also worried about the shoot thru in the beginning but then i realise time
    between each cycle to launch is about 1.8ms, so it should be enough time before it collide each others.

    please help advice the code.

    photoelectric
    please help advice.
    Attached Images Attached Images   

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,
    Well, you have to set the pins to the correct state at the start of the program - before you start the PWM-loop otherwise they will both start low and then toggle together. Set one high and the other low at the beginning, before you actually start the PWM.

    Or create a subroutine which sets everything up properly and simply GOSUB that routine at startup or whenever you need to "restart" it.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,

    yes, i set all the pin state 1st but outside the main loop, i simulate it and my switching and my 3 phases channel all works ok.
    i will test it in the real physical PIC tmrw and see the results, then feed back to you again.

    photoelectric

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,

    ive just test it on real physical PIC and found out that phase 1 and phase 2 works fine but phase 3 wont work very well.
    As you can see from the attached named Phase 1 shows the correct generated pwm, same as phase 2.
    However, file Phase 3 show that the signal from portb.3 always high as a result generating wrong pwm switching.
    ive recheck the circuit but nothing wrong with it.
    i also simulate the program using real PIC simulation and nothing was wrong.
    So, i guess maybe the code got something problem.
    below is my complete coding:


    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.

    thanks
    Attached Images Attached Images   

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,
    OK, so you're saying that it works in the simulator but not in the real world? Or does it not work in the simularor either?

    What do YOU think might be the problem and what have YOU tried in order to figure it out?

    Have you:
    A) Checked the datasheet to see if there's anything specific with PortB.3?
    B) Tried another pin, just as an experiment, to see if the logic of the code works?
    C) Connect a LED to PortB.3 and write code to turn that on and off so you KNOW that the pin actually works and is configured properly
    D) Disconnect the external logic and measured on the pin directly.
    E) Anything else?

    Let me know what you've tried and what the results are.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,
    its works on simulator for all phases but in real world only phase 3 as i mention before.

    i think its the pin portb.4 and portb.3 on the PIC16F737 but im not sure.

    A) yes, i have check the function of portb.3 and portb.4 -

    based on the datasheet
    portb.3:
    -Digital I/O.
    -CCP2 capture input, compare output, PWM output.
    -Analog input channel 9.
    portb.4:
    -Digital I/O.
    -Analog input channel 11.

    since i declare portb.5 as the ccp3, should be no problem for portb.3.
    portb.4 same function as i use for phase 1 and 2

    B)i tried another pin which is portb.2 and portb.3, still not function well (seem like it wont toggle properly)

    C)havent done it yet. will test using it next week and feedback to you again.

    D)Yes, i measure part A and B directly to the pin PIC

    btw, i test it on the breadboard. havent change the breadboard yet but i dont think its the reason.

    i will test it again friday next week and feedback to you.
    if u have any more idea on testing error please let me know

    photoelectric

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts