A slicker way to be constantly changing the duty cycle?


Closed Thread
Results 1 to 15 of 15

Hybrid View

  1. #1
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: A slicker way to be constantly changing the duty cycle?

    Hi Hank, Let me take a stab at this for you.

    In your first example, you set the duty directly with constants. No surprizes there I don't think.

    In the second example, you are changing the variable named DUTY, but this is not associated with the ccp reg's, so they never get changed.

    In the third example, you are using a variable named DUTY to to assign values to the ccp reg's. This is the method I would use as it seem the easiest to me. It takes care of all the bit switching and all your code needs to do is change the value of DUTY.

    To combine the second and third example, make the ccp assigns in the third example a subroutine. Then in the second example, before each pause, call the sub. I think in this way it will seem like it does exactly what you want.

    To do what I think you are trying, I think you need to alais the ccp reg's. for example:

    Code:
    CCP2CON.4    VAR Duty.0       'Bit 0
    CCP2CON.5    VAR Duty.1       'Bit 1
    CCPR2L.0    VAR Duty.2
    CCPR2L.1    VAR Duty.3
    CCPR2L.2    VAR Duty.4
    CCPR2L.3    VAR Duty.5
    CCPR2L.4    VAR Duty.6
    CCPR2L.5    VAR Duty.7
    Now I have NO idea if this will actually work, Try at you own risk
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

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


    Did you find this post helpful? Yes | No

    Default Re: A slicker way to be constantly changing the duty cycle?

    Hi Hank, Bert,

    Bert already gave you the answer, but just to clarify. The code I showed you doesn't alias anything. It is code that needs to execute when ever you want to change the dutycycle - as you've discovered. The easiest way IMHO is to simply create a subroutine and GOSUB it when you want the dutycycle changed, like:
    Code:
    Duty VAR BYTE
    i VAR Byte
     
    Main:
    For i = 0 to 255              'Fade up
      Gosub SetIt
      Pause 2
    Next
     
    For i = 255 to 0 Step -1  'Fade down
      Gosub SetIt
      Pause 2
    Next
     
    Goto Main
     
    SetIt:
      CCP2CON.4 = Duty.0
      CCP2CON.5 = Duty.1
      CCPR2L = Duty >> 2
    RETURN

  3. #3
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: A slicker way to be constantly changing the duty cycle?

    Hi Guys.

    Firstly Bert....apologies I didn't post the full code (ironically, I thought for simplicity's sake)....further up my program, I had exactly as you'd outlined, namely...

    Code:
     
    CCP2CON.4 =  duty.0
    CCP2CON.5 =  duty.1
    CCPR2L.0   =  duty.2 
    CCPR2L.1   =  duty.3
    CCPR2L.2  =   duty.4
    CCPR2L.3  =   duty.5
    CCPR2L.4  =   duty.6
    CCPR2L.5  =   duty.7
    in fact I tried Henrik's simpler way first, but when that didn't work (ie period register didn't update as I thought they should), I mapped them longhand as above.

    Apologies for not showing the full picture....and many thanks for helping me out (again!)

    Henrik,

    Sometimes I get so wrapped up that I lose sight of the obvious (I had many things on the go yesterday ....ultimately cracking a long standing coding issue (yay) ....but while doing so, I think my brain got fogged).....yep, my variable 'Duty' is not 'tracked' in real time as it were, which means I do need to update the period setting bits bt y pointing at my variable everytime I wish to change the duty...so yes, your sub routine is the order of the day.

    Many, many thanks

    ....thanks heavens for forums like this with people so willing to help.
    Last edited by HankMcSpank; - 24th April 2011 at 11:40.

  4. #4
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: A slicker way to be constantly changing the duty cycle?

    Just as a footnote to this, going the longhand way with HPWM & setting the registers manually (vs copping out & using the easy HPWM command), has rescued back a fair bit of program space ...and my LEDS are fading a bit smoother too.

    So to sum up, this will get your HPWM running on CCP2 (Pin 7) on a 16f1824....

    Code:
    DEFINE CCP2_REG PORTC     'route CCP2 output to PortC.3  Pin7 (16f1824)
    DEFINE CCP2_BIT 3         'route CCP2 ouput to PortC.3  Pin7 (16f1824)
    duty var byte
     
    CCP2CON    = %00001100   ' Turn HPWM on on CCP2
    TRISC.3   = 1            'Disable the CCP2 pin output driver by setting the bit
    CCPR2L.6 = 0             'I'm only using 8 bit PWM so clear the top two bits (these would be using for 9/10 bit HPWM)
    CCPR2L.7 = 0             'I'm only using 8 bit PWM so clear the top two bits (these would be using for 9/10 bit HPWM)
    PR2          = 63        'This sets the PWM period (frequency) to 15.625KHZ @4MHZ  (I hope so at least - I've  not scoped it!) and yields the full 255 bits of resolution
    CCPTMRS0 = %11110011     'This is the CCP Timer select register - these bits select 'CCP2 USING TIMER2'
    T2CON = %00000100        'TIMER2 ON 1:1 PRESCALER 1:1 POSTSCALER
    TRISC.3   = 0            'Enable the CCP2 pin output driver by clearing the bit
     
    Main:
    duty = 255
    gosub Change_PWM
    pause 500
    duty = 0
    gosub Change_PWM
    pause 500
    goto Main
     
    Change_PWM:              'the following three lines for 8 bit PWM
    CCP2CON.4 = Duty.0       'Bit 0    
    CCP2CON.5 = Duty.1       'Bit 1
    CCPR2L    = Duty >> 2    'Bit 2-7
    return
    the above code will give you some LED blinkage (you can never have enough LED blinkage) to prove it's working ....all you have to do is change the variable "Duty" & then a Gosub to change the HPWM duty cycle.

    Many thanks to all who helped
    Last edited by HankMcSpank; - 24th April 2011 at 22:48.

  5. #5
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default Re: A slicker way to be constantly changing the duty cycle?

    No all you have to do is get it to ramp 0>255>0 and you will be one step closer to your original intent - specifically wanting leds to fade niceley without any flickering.
    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!!

  6. #6
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: A slicker way to be constantly changing the duty cycle?

    Quote Originally Posted by rmteo View Post
    No all you have to do is get it to ramp 0>255>0 and you will be one step closer to your original intent - specifically wanting leds to fade niceley without any flickering.
    Oh, I've done that bit (& that wasn't the intent of my little bit of code above....which was simply to help others that may want to explore setting the HPWM registers manually)...

    Code:
     
    Main:
     
    decrement:
    if duty > 20 then 
    duty = duty -1
    gosub Change_PWM
    pause 3
    goto  decrement
    endif
    if duty >8 then 
    duty = duty -1
    gosub Change_PWM
    pause 15
    goto decrement
    endif
    if duty >1 then 
    duty = duty -1
    gosub Change_PWM
    pause 25
    goto decrement
    endif
     
    pause 100
     
    increment:
    if duty <10 then 
    duty = duty +1
    gosub Change_PWM
    pause 25
    goto increment
    endif
    if duty <20 then 
    duty = duty +1
    gosub Change_PWM
    pause 15
    goto increment
    endif
    if duty <255 then 
    duty = duty +1
    gosub Change_PWM
    pause 3
    goto increment
    endif
     
    goto Main
    now I'm sure that's ugly to those who program regularly ....I'm a self confessed 'kludger', but it works (what I found was that simply increasing the duty linearly didn't result in a linear fade .....in particular the lowest 20 of the 8 bit resolution has the most dramatic change in brightness, hence the longer pauses as the duty value approaches zero)

    There's no flickering of the LEDS ...but then again I'm not sure there was using HPWM command...this was a mini project to mainly wrap my head around the HPWM registers as I had an inkling that using the HPWM command was doing far more 'under the covers' each time I called the command than I really wanted)
    Last edited by HankMcSpank; - 24th April 2011 at 23:26.

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