ProblemwithPWMfrequency


Closed Thread
Results 1 to 38 of 38

Hybrid View

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


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    2) I mean something simple like this:
    Code:
    Main:
      Temp = 40
      GOSUB UpdateDuty
      Pause 500
      Temp = 400
      GOSUB UpdateDuty
      Pause 500
    GOTO Main
    
    UpdateDuty:
      CCP1CON.4 = Temp.0 ' bit 0
      CCP1CON.5 = Temp.1 ' bit 1       
      CCPR1L = Temp>>2  'Bit 2-7
    RETURN
    This should switch the dutycycle between '40' and '400' att 500ms intervals which should be clearly visible on the "scope". Make sure you can do that before you try to move the PWM stuff to the ISR. Since you now know that is interrupt is firing properly and you can control the frequency all you need is to to move it back into the ISR.

    You are making progress but the key is to take it slow and try to understand each step. When something doesn't work, solve one problem at a time and take it slow.

    /Henrik.

  2. #2
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Thankx HenrikOlsson for the comments, and explaination to me

    I have been worked on this code for the whole day but still I didi not get any output. The problem I faced is I don't get any output to the CCP1(TRISC<2>).I tryt to put led1 on main to measure the time I get it clear which is 1sec for each toggle which is true( 500+500)ms also I put led1 on UpdateDuty subroutine also I get clear a delay of 500ms to each toggle which is also true because UpdateDuty it is called aftter every 500ms. But I 'm confusing where is problem? And why is CCP1 does not output to (TRISC<2>)?.Here is the code.

    Code:
    PIC 16F877
    define OSC 4
    
    TRISC   = %11111011
    CCP1CON = %00001100
    T2CON   = %00000100
    PR2  = 199 for 5khz
    TRISB   = %11111101 
    TRISA   = %11111111
    LED1   VAR  PORTB.1
    temp var word
    Main:
      Temp = 40
      GOSUB UpdateDuty 
      Pause 500
      Temp = 400
      GOSUB UpdateDuty
      Pause 500
      TOGGLE LED1
    GOTO Main
    UpdateDuty:
      CCP1CON.4 = Temp.0 ' bit 0
      CCP1CON.5 = Temp.1 ' bit 1       
      CCPR1L = Temp>>2  'Bit 2-7
    RETURN
    end
    Help me to solve this problem thankx.

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


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    I've tried the above code here and it works just fine. I don't have a 16F877 so I tried it on a 18F25K20, the dutycylce of PWM-signal changes just as expected - no problem.

    I looked at the datasheet for the 16F877 and the CCP1 pin isn't multiplexed with any other functions so it should work. Have you tried this with real hardware or are you still messing around with the simulator? My guess is that you're measuring on the wrong pin or that you have that simulator of yours set up wrong or that the PWM module isn't simulated properly.

  4. #4
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Thankx HenrikOlsson

    True the problem was due to the simulator was not working properly .Now the code is working fine and I get the correct PWM frequency(5khz) after change the ISIS vasion Thankx for it. But I have the following problem of relating the dutycycle from the theory and that from picdatashetformural.

    From theory (dutycycle=(Time-ON/period) for my case
    case1: AS seen from the scope when I used the above fomural gives 1/2=0.5=50%

    case2: As seen from the scope when I used the above fomural gives 0.1/2=0.05=5%

    how these values(case1 and case2) can be related with 40 and 400 values

    from pic16f877 datasheet PWM_dutycycle= CCPR1L:CCP1CON<5:4>*TOSC*(TMR2 prscale value)

    I 'm confusing how can I relate the value from theory formular and that from datasheet to know that I get the correct results.

    Help me to solve this problems because always these two case confusing me.


    Thankx
    Attached Images Attached Images

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,621


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    I really hope you've learned something here....How much time have you (and I) wasted on that simulator by now? If you had put a PIC on a breadboard from the get go you'd be done by now.

    As you know by now the PWM period ends when TMR2=PR2. So if you set the CCPR1L value to whatever you have PR2 set to you'll get 100% dutycycle (this assumes 1:1 prescaler). So, if PR2 is 200 then setting CCPR1L to 200 will give you 100% dutycycle, setting it to 50 will give you 25% dutycycle and so on. The two lowest significant bits (CCP1CON<5:4>) adds 2 bits (or 4 times if you will ) worth of resolution. So if you prefer you could say that a DutyVal of PR2*4=100%.

    For example, DutyVal=800. Take the 2 low bits and stuff them CCP1CON5:4 and take the 8 high bits in stuff them in CCPR1L. If you take a close look at the 8 bits alone you'll see that it's the value 200.

    /Henrik.

  6. #6
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Thankx HenrikOlsson
    I really appreciate your effort on this forum.

    (1) sorry I understand you explaination very well on how dutycycle relate with value of PR2. one problem is that you statements below is not clear to me and why PR2*4=100%:
    the two lowest significant bits (CCP1CON<5:4>) adds 2 bits (or 4 times if you will ) worth of resolution. So if you prefer you could say that a DutyVal of PR2*4=100%.
    For example, DutyVal=800. Take the 2 low bits and stuff them CCP1CON5:4 and take the 8 high bits in stuff them in CCPR1L. If you take a close look at the 8 bits alone you'll see that it's the value 200.
    a

    (2)From what I know for 8bit resolution
    CCP1CON.4 = duty.0
    CCP1CON.5 = duty.1
    CCPR1L = DUTY >> 2
    that is means that 2bit (CCPICON<5:4>) and 6bit obtain after shifting right(divide by 4) duty value are combine to form 8bit resolution

    What I want to know is that, if I used 10 bit resolution is that code here correct?

    CCP1CON.4 = duty.0
    CCP1CON.5 = duty.1
    CCPR1L = DUTY
    that is 2bit(CCPICON<5:4>) are combine with 8bit (CCPR1L)from duty value to form 10bit resolution.
    thankx

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,621


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    I'm not sure how to explain this in any other way....
    If you have a WORD sized variable with a 10bit value stored in it you take the two lower bits and put them in CCP1CON5:4. Then you shift the value to the right twice and then load the value to CCPR1L.

    0000001100110010

    Above, the value 818 is shown in binary. The first thing that you do is take the two lower bits (the ones in green) and load them to CCP1CON.4 and CCP1CON.5. Then you shift the value to the right twice which makes the two green bits "dissappear" and two "zeros" shifted in at the high end. The value now looks like this:

    0000000011001100

    Now you load the value (204) to CCPR1L. The code is just as it always been
    Code:
    DutyVal = 818
    CCP1CON.4 = DutyVal.0   'Lowest significant bit
    CCP1CON.5 = DutyVal.1
    CCPR1L = DutyVal >> 2   ' Shift value to the right twice and move it to CCPR1L
    You may remember that an instruction cycle is 4 clock cycles. Ie, when running with a 20MHz crystal the "execution speed" is 5Mhz. This is because there's 4 clock cycles to each instruction cycle. Normally TMR2, which is used for the PWM generation, is clocked at the instruction cycle rate but in PWM mode it gets concatenated with the 2 bit internal Q clock used to "derive" the f/4 clock. So in PWM mode you could think of TMR2 is a 10bit timer operating at 20Mhz (in this case). The 8 most significant bits of the timer is the TMR2 register and the two low significant bits are the internal 2 bit Q clock.

    The value of this 10 bit TMR2 gets compared to the 10 bit value consisting of 8 bits in CCPR1L and 2 bits in CCP1CON.

    It's all in the datasheet:
    Name:  PWM block diagram.jpg
Views: 75083
Size:  46.0 KB

    Do you see the TMR2 register (8 bits) and the two bits of the Q clock? This forms the 10bit timer. Above that you have a comparator which compares the 10bit timer value with the 10 bit dutycycle value built up from CCPR1L and the two bits in CCP1CON. When there's a match the output goes low. CCPR1H buffers CCPR1L at the start of each cycle so that you can safely update CCPR1L at any time without disturbing the output.

    May I suggest you also take a look at the PIC Midrange manual and I'm sure there are multiple application notes on Microchips website describing the PWM generation in far more detail and far more accurately than I can.

    /Henrik.

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