3 channel PWM with customize duty cycle


Closed Thread
Results 1 to 40 of 57

Hybrid View

  1. #1


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,

    Im still trying to understand your explaination.
    So i have to use count command?
    can you give me an example of code for me to refer to?

    photoelectric

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,
    I'm sorry to say this but it sounds like you need to take a step back and work thru the basics of programming with PBP. We can keep giving you code here until we've basically written the whole thing for you and you still wouldn't understand how it works.

    Pause does just that - it pauses - no other code (except if you're using interrupts) is running while the Pause exeuctes. Like this:
    Code:
    Main:
      High PortB.0
      Pause 100
      Low PortB.0
      Pause 100
    Goto Main
    This will blink a LED connected to PortB.0 at 5Hz. If you put another pause in there, like:
    Code:
    Main:
      High PortB.0
      Pause 100
      Low PortB.0
      Pause 100
     
      Pause 1000
    Goto Main
    It won't blink at 5Hz because you just told it to pause for another second. The same thing happens with your 4ms pause. The FOR NEXT loop that is supposed to keep running and feeding the PWM module with a new dutycycle evert 210us will stop - completely - for the 4ms duration. But because the PWM is generated by hardware it will keep outputting whatever dutycycle it was last told to do.

    The count command is used to count pulses on a pin, I don't think that is what you want?

    The following is ONE way of doing it. This compiles fine but I have NOT tested it.
    Code:
    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
     
    ' 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] = 61 : Phase[2] = 123
     
    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 then 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] > 185 then Phase[i] = 0         'When pointer is > 185 we need to wrap around to 0.
      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 = DutyCyle[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,18,34,52,68,85,102,119,137,152,170,187,203,220,236,253,267,285,302,_
         318,334,350,367,382,397,413,429,443,459,474,489,504,518,533,547,562,575,589,603,616,_
         630,643,655,669,681,693,706,718,729,740,752,764,774,785,795,806,815,825,835,844,853,_
         861,870,879,887,895,901,909,916,923,929,935,941,946,952,957,962,967,971,974,978,_
         981,984,987,990,992,994,996,997,998,999,999,1000,999,999,998,997,997,996,994,992,_
         990,987,984,981,978,974,971,967,962,957,952,946,941,935,929,923,916,909,901,895,_
         887,879,870,861,853,844,835,825,815,806,795,785,774,764,752,740,729,718,706,693,_
         681,669,655,643,630,616,603,589,575,562,547,533,518,504,489,474,459,443,429,413,_
         397,382,367,350,334,318,302,285,267,253,220,203,187,170,152,137,119,102,85,68,_
         52,34,18,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
    /Henrik.

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,
    Thanks again for the example. This is my 1st time using PIC Basic pro languange and im trying very hard to learn it. hope you can assist me more in the future.

    i test it and it works fine for all three phases.(according to my value of lookup)
    Phase 1 launch for 17.6ms
    Phase 2 launch at 7ms of the phase 1
    Phase 3 launch at 13.2ms of the phase 1

    now, im trying to add six signal from six port pin connected to the external AND gate so that i can control the the 3 phases.
    Attached is the schematic diagram.

    what should i adjust in the codes so that
    when
    RA1 is high and RA2 is low pwm from ccp1 is launch other word is Q1 is launch and then after 1 complete cycle,
    RA1 is low , RA2 is high Q4 is launch.

    and so on.

    thanks,
    photoelectric
    Attached Images Attached Images  

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,
    I'm not completely sure I understand but anyway.....

    You can use any of the phase counters, take Phase[0] for example. It'll count from 0 to 185 and then start over, count from 0 to 185 on and on and on. Every time it's 0 a new cycle starts. Use that as your "trig" to change the output pattern to the external logic.

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: 3 channel PWM with customize duty cycle

    Hi,

    my explanation is same like coding below:

    Code:
    defineosc 20	
    DUTY1 var word	
    DUTY2 var word	
    FREK var word	
    
    frek=5000	
    Loop:		
    high port.1	
    
    	GOSUB FIRE	
    
    low portb.1	
    high portb.2	
    
    	GOSUB fire	
    
    low portb.2	
    gotoLoop
    
    fire:
    
    For DUTY1 = 0 TO 44
    
    LookUp DUTY1, [0,18,35,53,70,87,104,120,135,150,164,177,190,201,211,221,229,236,_
    243,247,251,254,255,254,251,247,243,236,229,221,211,201,189,_
    177,164,150,135,120,104,87,70,53,35,18,0],DUTY2
    
    hpwm 1,DUTY2,frek	
    next DUTY1
    
    RETURN
    end
    but that coding only applicable for 1 phase only.
    based on your coding example, i want it to be:
    The 1st time it count from 0 to 185 , portc.3 will be high and portc.0 will be low then 2nd time it count from 0 to 185, portc.3 will be low and portc.0 will be high.

    do i need to make new loop, let say:

    loop:
    IF Phase[0] =0 '1st time it count
    high portc.3
    low portc.0
    then Phase[0]=0 'second time it count
    high portc.0
    low portc.3
    goto loop

    please help advice

    photoelectric

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


    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.

  7. #7


    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   

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