ProblemwithPWMfrequency


Closed Thread
Results 1 to 38 of 38
  1. #1
    Join Date
    Oct 2011
    Posts
    52

    Default ProblemwithPWMfrequency

    Hi to every one
    My aim is to generate 5kHZ SPWM so that when filtered will give sine waves(50hz). I havebeen reading different application manual and PIC16877 and Pic16f777 datashets for almost two days but I 'm still in darkness the problem comes for that frequency my duty cycle will have 10bit resolution. here are the question I have and the code I wrote, any one can help me.

    (1) I simulate it using pic16f877 but I dont see any output

    Code:
    define OSC 4
    Wsave var byte   $70system
    Wsave1 var byte  $A0system
    Wsave2 var byte  $120system
    Wsave3 var byte  $1A0system
    
    
        'pointer for phase one in sinearray
                    'pointer for phase two  in sine array
    ADCON0 = %00000000
    ADCON1 = %00000000
    LED1   VAR  PORTB.1
    
    TRISB = %11111101
    TRISC = %11111001  'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    PR2 =  199   'set for 5Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100  'TIMER2ON and prescale of 1:1 
    index var byte
    temp var word
    timerone var word 
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System          emp 
    ASM
     
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _test,   ASM,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    T1CON = 000001                 ; Prescaler = 1;1, TMR1 ON
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts 
     
    timerone = 64980 ;gives about 50 htz sine  
                       
    test: 
     T1CON = 000000 'stop the timer
        TMR1L = timerone.byte0  'reload the timer
        TMR1H = timerone.byte1
        T1CON = 000001          ' start the timer
        gosub display
        CCP1CON.4 = Temp.0 ' bit 0
        CCP1CON.5 = Temp.1 ' bit 1       
        CCPR1L = Temp>>2  'Bit 2-7 
        
      display:
    lookup2 index[115,102,90,79,70,62,57,53,52,53,57,62,70,79,90,102,115,128,141,154,166,177,186,194,199,203,204,203,199,194,186,177,166,154,141,128],temp
      return          
       
       index=index+1
        if index =36 then index =0      
     @    INT_RETURN
    please any one one help me to solve this problem

    thankx

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


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    Several things.
    1) There is no "main loop" in the program so the execution falls thru into the interrtupt handler and then it hits the @INT RETURN macro which makes it return to what?

    2) You have the display subroutine located in the middle of your code. When you're using subroutines you need to make sure that the program can't "reach" them without actually being called by a GOSUB. In your program the display subroutine gets exectued one time when called by the GOSUB (which is all OK) but then it gets executed again after you've loaded the CCP1 registers and since there's a RETURN at the end of the subroutine it jumps to somewhere it shouldn't.

    3) You have the interrupt handler declared as ASM even though you're using PBP statements in the handler. I've said this to you in one of your other threads covering the same topic: Do NOT do that if you don't know what you're doing. If you don't understand WHY you can either read up on it here on the forum but if you don't care about the details simply follow the rules given: If the handler is in PBP then declare it as type PBP - not ASM.

    /Henrik.

  3. #3
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi every one

    Thanks HenrikOlsson for your coments on this code. I worked on your coments and do some monifications, here is challenge I faced
    (1) I declare my handler as PBP type when I compile the code gives the following error WARNING: Unable to open INCLUDE file REENTERPBP-14.BAS although I include that file in the compilation folder why is this error?

    (2) I'm confusing why the program declared as ASM type having PBP statement and the Label does not have an underscore before it gives error while that declared as ASM type having PBP statement and the Label have an underscore before it gives gives NO error.But accorgni to Darrel PBP type label should have un underscore before it.

    code
    Code:
    define OSC 4
    Wsave var byte   $70system
    Wsave1 var byte  $A0system
    Wsave2 var byte  $120system
    Wsave3 var byte  $1A0system
    
    
        'pointer for phase one in sinearray
                    'pointer for phase two  in sine array
    ADCON0 = %00000000
    ADCON1 = %00000000
    LED1   VAR  PORTB.1
    
    TRISB = %11111101
    TRISC = %11111001  'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    PR2 =  199   'set for 5Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100  'TIMER2ON and prescale of 1:1 
    index var byte
    temp var word
    timerone var word 
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System          emp
    INCLUDE "ReEnterPBP-14.bas"  
    ASM
     
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _TEST,  PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    T1CON = 000001                 ; Prescaler = 1;1, TMR1 ON
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts 
     
    timerone = 64980 ;gives about 50 htz sine 
    Main:
           PAUSE 5
     
    GOTO Main
    TEST: 
     T1CON = 000000 'stop the timer
        TMR1L = timerone.byte0  'reload the timer
        TMR1H = timerone.byte1
        T1CON = 000001          ' start the timer
        gosub display
        CCP1CON.4 = Temp.0 ' bit 0
        CCP1CON.5 = Temp.1 ' bit 1       
        CCPR1L = Temp>>2  'Bit 2-7 
        index=index+1
      if index =36 then index =0 
         
     @    INT_RETURN
     
     display:
      lookup index,[115,102,90,79,70,62,57,53,52,53,57,62,70,79,90,102,115,128,141,154,166,177,186,194,199,203,204,203,199,194,186,177,166,154,141,128],temp
        
      return    'return to the subroutine 
      return    'return to the original GOSUB
    thankx

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


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    1) As far as I can see the file is called ReEnterPBP.bas. For some reason you're trying to include ReEnterPBP-14.bas.

    2) The compiler (PBP) adds an underscore in front of all variables and labels so the label Test becomes _Test in the compiled program. This is so that any variables and labels you create does not interfere with whatever system variables PBP creates internally. The interrupt declaration, ie this part...
    Code:
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _TEST,  PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    ...is, as you can see by ASM/ENDASM directives assembly code which is passed directly to the assembler. So the label needs (_test) needs to have the underscore infront of it here because once the assembler is invoked your Test: label is called _Test. I hope that makes sense.

  5. #5
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    thankx for the explaination about underscore I understood it very well why under score. But your statement below is not clear to me
    "As far as I can see the file is called ReEnterPBP.bas. For some reason you're trying to include ReEnterPBP-14.bas".
    thankx

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


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    If you go to Darrel's website and download the .zip file for DT_INTS-14 you get two (2) files. One is called DT_INTS-14.bas and the other is called ReEnterPBP.bas. In your program you are correctly icluding DT_INTS-14.bas but you are, incorrectly trying to include a file called ReEnterPBP-14.bas - your code:
    Code:
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System          emp
    INCLUDE "ReEnterPBP-14.bas"   '<-----Here, you have the wrong filename.
    See, the file your're TRYING to include is ReEnterPBP-14.bas but the file is called ReEnterPBP.bas (if you haven't renamed it in which case I don't what the problem is).

    /Henrik.

  7. #7
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Thankx it compile fine but the output is stationary. I 'm confusing why is it.I attach simulation of the output as seen from ISIS

    [CODE]
    define OSC 4
    Wsave var byte $70system
    Wsave1 var byte $A0system
    Wsave2 var byte $120system
    Wsave3 var byte $1A0system
    ADCON0 = %00000000
    ADCON1 = %00000000
    LED1 VAR PORTB.1

    TRISB = %11111101
    TRISC = %11111001 'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    PR2 = 199 'set for 5Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100 'TIMER2ON and prescale of 1:1
    index var byte
    temp var word
    timerone var word
    INCLUDE "DT_INTS-14.bas"
    INCLUDE "ReEnterPBP.bas"
    ASM

    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
    INT_Handler TMR1_INT, _TEST, PBP, yes
    endm
    INT_CREATE ; Creates the interrupt processor
    ENDASM

    T1CON = 000001 ; Prescaler = 1;1, TMR1 ON
    @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts

    timerone = 64980 ;gives about 50 htz sine
    Main:
    PAUSE 5

    GOTO Main
    TEST:
    T1CON = 000000 'stop the timer
    TMR1L = timerone.byte0 'reload the timer
    TMR1H = timerone.byte1
    T1CON = 000001 ' start the timer
    gosub display
    CCP1CON.4 = Temp.0 ' bit 0
    CCP1CON.5 = Temp.1 ' bit 1
    CCPR1L = Temp>>2 'Bit 2-7
    index=index+1
    if index =36 then index =0

    @ INT_RETURN
    Code:
     
     display:
      lookup index,[115,102,90,79,70,62,57,53,52,53,57,62,70,79,90,102,115,128,141,154,166,177,186,194,199,203,204,203,199,194,186,177,166,154,141,128],temp
        
      return    'return to the subroutine 
      return    'return to the original GOSUB
    Attached Images Attached Images

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    Not that I think it's a problem but why TWO returns in the subroutine? The execution will never get to the second one.

    Are you sure that the output really IS "stationary", it's not just that you have the horisontal sweep set to fast?
    Wrap the ISR in a LED1 = 1 and LED1 = 0 and sample PortB.1 too with your "scope", that way you'll see IF and and what frequency the interrupt ACTUALLY runs as well as how long it takes to execute.
    With 4MHz crystal, PR2 set to 199 and prescaler set to 1:1 you should be getting 5kHz PWM but your "scope" (if I read it correctly) shows a period of 400us which means a PWM frequency is 2.5kHz, why is that?

  9. #9
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Thankx HenrikOlsson for the comments I worked on on them

    For what I know the gosub coment within subroutine takes two return. The first return will bring you back to the subroutine(TEST) and the second return will bring you to the original gosub comand if I'm not wrong.

    I havebeen worked on the code for almost whole day I'm still getting the same output and I try know my interrupt frequency by Toggling PortB.1 the problem comes I cant see the square wave comes from that pin. here is code and output from ISIS.

    Code:
    define OSC 4
    Wsave var byte   $70system
    Wsave1 var byte  $A0system
    Wsave2 var byte  $120system
    Wsave3 var byte  $1A0system
    ADCON0 = %00000000
    ADCON1 = %00000000
    LED1   VAR  PORTB.1
    
    TRISB = %11111101
    TRISC = %11111001  'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    PR2 =  199   'set for 5Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100  'TIMER2ON and prescale of 1:1 
    index var byte
    temp var word
    timerone var word 
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System          
    INCLUDE "ReEnterPBP.bas"  
    ASM
     
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _TEST,  PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    T1CON = 000001                 ; Prescaler = 1;1, TMR1 ON
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts 
     
    timerone = 64980 ;gives about 50 htz sine 
    Main:
           PAUSE 5
     
    GOTO Main
    
    TEST: 
        T1CON = 000000 'stop the timer
        TMR1L = timerone.byte0  'reload the timer
        TMR1H = timerone.byte1
        T1CON = 000001          ' start the timer
        gosub display
        CCP1CON.4 = Temp.0 ' bit 0
        CCP1CON.5 = Temp.1 ' bit 1       
        CCPR1L = Temp>>2  'Bit 2-7
        TOGGLE LED1  
        index=index+1
      if index =36 then index =0
       
         
     @    INT_RETURN
     
     display:
      lookup index,[115,102,90,79,70,62,57,53,52,53,57,62,70,79,90,102,115,128,141,154,166,177,186,194,199,203,204,203,199,194,186,177,166,154,141,128],temp
        
      return    'return to the subroutine 
      return    'return to the original GOSUB
    I don't understand why the output is 2.5Kh instead of 5khz

    help me on that problems
    thankx
    Attached Images Attached Images

  10. #10
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    No you need one RETURN at the end of the subroutine. That RETURN makes the code return to line after the GOSUB, the @INT_RETURN makes it return from the interrupt handler.

    Are you sure you have the scope connected to the correct output?


    The first thing you need to do i make sure that the PIC and that simulator of yours is running properly and that you're using it properly. Remove all the interrupt and PWM stuff and then make a simple program that just toggles that LED1 output. Connect your "scope" and make sure you can see the output toggle on the scope.

    When and only when you have that working put the interrupt stuff back in but move the TOGGLE command to the interrupt handler - EXACTLY as shown here. Don't try to add all your PWM stuff.

    When and only when you can see that LED1 output toggling on the scope try adjusting the interrupt frequency and see if that works the way you want.

    EDIT: Now make sure that you can setup and control the dutycycle of the PWM module in the main loop (still no interrupts). Just toggle the dutycycle between two values and make sure you can see that on the scope.

    Now, when you have THAT working you are ready to start adding the PWM stuff.

    Don't try to skip a step until you have the previous one working and understand why and how.
    Last edited by HenrikOlsson; - 29th February 2012 at 18:31.

  11. #11
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi HenrikOlsson

    (1) Thankx. I worked on the steps you told me and I manage to control my interrupt frequency which is (50*36=1800) for this frequency the time1 will be loaded with 64980 this value gives me (1667hz) which is the lowest frequency but the value 65080 gives me the frequency 1818. I think as you told me early the PBP tpyes take longer time compared to ASM types ,thankx for it and I deside to use the value which gives (1818hz).

    (2)But sorry you are stastment below is not clear to me.
    EDIT: Now make sure that you can setup and control the dutycycle of the PWM module in the main loop (still no interrupts). Just toggle the dutycycle between two values and make sure you can see that on the scope.

    Thankx

  12. #12
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    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.

  13. #13
    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.

  14. #14
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    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.

  15. #15
    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

  16. #16
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    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.

  17. #17
    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

  18. #18
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    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: 1111
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.

  19. #19
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi HenrikOlsson
    I have manage to combine the code,compile it successfully and get the correct PWM frequency(5khz) thanks for all.
    (a) As you told me early the DutyVal of PR2*4=100% that means that my value of PR2=199 the DutyVal can vary within (0-796).One problem I have is in my lookup table the there is value greater than 796.What happen to this values greater than 796?

    (b) Also I have read PIC Midrange manual(http://ww1.microchip.com/downloads/e...doc/33023a.pdf) page 211 and 212 it says
    (1) " If the PWM duty cycle value is longer than the PWM period, the CCPx pin will not be cleared. This allows a duty cycle of 100%".
    (2) " Any value greater than 255 will result in a 100% duty cycle".
    is this two reason cause some part of my wave form not to have a PWM frequency of 5khz? having a long off time
    here is code and two phase PWM output

    Code:
    STEPCOUNT var byte
    STEPCOUNT1 var byte
    
    LED1  VAR  PORTB.1
    
    STEPCOUNT = 0   'pointer for phase one in sinearray
    STEPCOUNT1 = 12 'pointer for phase two  in sine array
    ADCON0 = %00000000
    ADCON1 = %00000000
    
    TRISB = %11111101
    TRISC = %11111001  'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    TMR2 = 0
    PR2 = 199 'generate 5khz  'set for 18Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100  'TIMER2ON and prescale of 1:1 
    
    sineval var byte[36]
    sineval[0] = 512    
    sineval[1] = 583   
    sineval[2] = 652
    sineval[3] = 717
    sineval[4] = 775
    sineval[5] = 825
    sineval[6] = 866
    sineval[7] = 896
    sineval[8] = 915
    sineval[9] = 921   
    sineval[10] =915
    sineval[11] =896
    sineval[12] =866   
    sineval[13] =825
    sineval[14] =775
    sineval[15] =716
    sineval[16] =652
    sineval[17] =583
    sineval[18] =512   
    sineval[19] = 441
    sineval[20] = 372
    sineval[21] = 308 
    sineval[22] = 249
    sineval[23] = 199
    sineval[24] = 158
    sineval[25] = 128
    sineval[26] = 109
    sineval[27] = 103
    sineval[28] = 109 
    sineval[29] = 128
    sineval[30] = 158
    sineval[31] = 199
    sineval[32] = 249
    sineval[33] = 308
    sineval[34] = 441
    sineval[35] = 512
    
    timerone var word 
    Temp var byte
    Temp1 var byte
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System          emp
    INCLUDE "ReEnterPBP.bas" 
     
    ASM
     
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _sine,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    T1CON = 000001                 ; Prescaler = 1;1, TMR1 ON
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts 
     
    timerone =  65080' gives1818hz interruptfrequency or about 50 htz sine 
    Main:
           PAUSE 5
     
    GOTO Main
     
    '---[TMR1_INT - interrupt handler]------------------------------------------
    
    sine:
         T1CON = 000000 'stop the timer
    
        TMR1L = timerone.byte0  'reload the timer
        TMR1H = timerone.byte1
        T1CON = 000001          ' start the timer
        
        
        TeMP = sineval[STEPCOUNT]
        CCP1CON.4 = Temp.0 ' bit 0
        CCP1CON.5 = Temp.1 ' bit 1       
        CCPR1L = Temp >>2  'Bit 2-7 
        
        TeMP1 = sineval[STEPCOUNT1]
        CCP2CON.4 = Temp1.0 ' bit 0
        CCP2CON.5 = Temp1.1 ' bit 1       
        CCPR2L = Temp1 >>2  'Bit 2-7
        TOGGLE LED1 
        stepcount =  stepcount +1
        stepcount1 =  stepcount1 +1
        
        if stepcount =36 then stepcount =0
        if stepcount1 =36 then stepcount1 =12
         
     
    @    INT_RETURN
    Help to help me to solve this problems
    thanks
    Attached Images Attached Images

  20. #20
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    One problem I have is in my lookup table the there is value greater than 796.What happen to this values greater than 796?
    You answered your own question in (1) from the Midrange manual:
    (1) " If the PWM duty cycle value is longer than the PWM period, the CCPx pin will not be cleared. This allows a duty cycle of 100%".
    Any dutycycle value above 796 will result in 100% dutycycle. In other words your SIN-output will be distorted/clipped.

    is this two reason cause some part of my wave form not to have a PWM frequency of 5khz? having a long off time
    Don't think so, I'd expect it to stay at 100% but I may be wrong. However this isn't correct:
    Code:
        if stepcount =36 then stepcount =0
        if stepcount1 =36 then stepcount1 =12
    You can't restart at the 12th byte, that will make the second output miss 1/3 of the cycle. You start at the 12th byte to get the correct phase angle offset but you must restart at 0 once it reaches 36.

    /Henrik.

  21. #21
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Thanks HenrikOlsson for your information.But this look like is not clear to me. From what I now when stepcount1 =36 for 2nd phase then stepcount1=12 so as it start to the 12thbyte again because initially is declared as stepcount1=12.What confusing me is that initially in my declaration of variable stepcount1=12 why after one cylecle stepcount1 should declared as stepcount1=0.How can I archieve phase difference of 120 if stepcount=0 after one cylecle.

  22. #22
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    You have 36 values in you SIN table. To get a correct output you need each phase to cycle thru these 36 values. You get the phase difference by starting each phase 120° apart in the lookup table but from that point they will keep that phase difference if you reset the index pointer to 0 when they reach 36:
    Name:  SIN_PWM_2.JPG
Views: 1006
Size:  39.3 KB

    If you don't reset it to 0 but instead keep restarting the second phase at the 12th value (like you're currently doing) the output will look something like this:

    Name:  SIN_PWM_3.JPG
Views: 927
Size:  46.6 KB

    Why? Because the second phase never "gets" the first 12 values of the lookup table so the output gets A) distorted and B) of another frequency since it doesn't contain the same number of "samples" as the the first phase.

    Thinking even further and adding the third phase, starting at the 24th value keep restarting at 24 the output would look something like:
    Name:  SIN_PWM_4.JPG
Views: 955
Size:  43.9 KB

    I hope you see that the above is not correct and that you understand WHY it's not correct.



    Using your lookup table, starting the pointers at 0, 12 and 24 and restarting them all at 0 when they reach 36 the output looks like:
    Name:  SIN_PWM_5.JPG
Views: 942
Size:  45.6 KB
    Which I think is more inline with what you're after, isn't it?

    Now, the waveform is distorted because you have the value 512 as the first AND as the last the value in the table which means that you'll get a dutycycle of 512 for two "samples" in a row. That is where th flat spot in the wave form is comming from.

    /Henrik.

  23. #23
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi HenrikOlsson

    Now Inderstand why stepcount1 should restart to zero.
    (1) But I have been working on the code and and modify my look up table as you told me about the first value and the last value, but the problem of flat spot still remaing I didn't understand why is this?
    (2)If I want to make acertain value of dutycylecle maximum (specific range of variation) let say(0- 80)% or (0-75%) should I do in the look up table or modify the formular?
    formular : ((sin(degree*pi/180)+1) /2)*1023 for 10 bit resolution.


    help me to solve this problems

    Thanks

  24. #24
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    1) Can't help without seeing the values.
    2) Not sure I understand what the problem is.... If you want a certain maximum dutycycle then simply rescale the values before storing them in the lookuptable (change the formula to produce a table with lower values). If you want to rescale at runtime then you need to perform the math in the PIC. Retrieve the "original" value, rescale, and output.

    /Henrik.

  25. #25
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi HenrikOlsson
    1) Can't help without seeing the values.
    Here is the values
    Code:
    Wsave var byte   $70system
    Wsave1 var byte  $A0system
    Wsave2 var byte  $120system
    Wsave3 var byte  $1A0system
    
    STEPCOUNT var byte
    STEPCOUNT1 var byte
    
    LED1   VAR  PORTB.1
    
    STEPCOUNT = 0   'pointer for phase one in sinearray
    STEPCOUNT1 = 12 'pointer for phase two  in sine array
    ADCON0 = %00000000
    ADCON1 = %00000000
    
    TRISB = %11111101
    TRISC = %11111001  'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    TMR2 = 0
    PR2 = 199 'generate 5khz  'set for 18Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100  'TIMER2ON and prescale of 1:1 
    
    sineval var byte[36]
    sineval[0] = 512    
    sineval[1] = 583   
    sineval[2] = 652
    sineval[3] = 717
    sineval[4] = 775
    sineval[5] = 825
    sineval[6] = 866
    sineval[7] = 896
    sineval[8] = 915
    sineval[9] = 921   
    sineval[10] =915
    sineval[11] =896
    sineval[12] =866   
    sineval[13] =825
    sineval[14] =775
    sineval[15] =716
    sineval[16] =652
    sineval[17] =583
    sineval[18] =512   
    sineval[19] = 441
    sineval[20] = 372
    sineval[21] = 308 
    sineval[22] = 249
    sineval[23] = 199
    sineval[24] = 158
    sineval[25] = 128
    sineval[26] = 109
    sineval[27] = 103
    sineval[28] = 109 
    sineval[29] = 128
    sineval[30] = 158
    sineval[31] = 199
    sineval[32] = 249
    sineval[33] = 308
    sineval[34] = 372
    sineval[35] = 441
    
    timerone var word 
    Temp var byte
    Temp1 var byte
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System          emp
    'INCLUDE "ReEnterPBP.bas" 
     
    ASM
     
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _sine,   ASM,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    T1CON = 000001                 ; Prescaler = 1;1, TMR1 ON
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts 
     
    timerone =  65080' gives1818hz nterruptfrequency or about 50 htz sine 
    Main:
           PAUSE 5
     
    GOTO Main
     
    '---[TMR1_INT - interrupt handler]------------------------------------------
    
    sine:
         T1CON = 000000 'stop the timer
    
        TMR1L = timerone.byte0  'reload the timer
        TMR1H = timerone.byte1
        T1CON = 000001          ' start the timer
        
        
        TeMP = sineval[STEPCOUNT]
        CCP1CON.4 = Temp.0 ' bit 0
        CCP1CON.5 = Temp.1 ' bit 1       
        CCPR1L = Temp >>2  'Bit 2-7 
        
        TeMP1 = sineval[STEPCOUNT1]
        CCP2CON.4 = Temp1.0 ' bit 0
        CCP2CON.5 = Temp1.1 ' bit 1       
        CCPR2L = Temp1 >>2  'Bit 2-7
        TOGGLE LED1 
        stepcount =  stepcount +1
        stepcount1 =  stepcount1 +1
        
        if stepcount =36 then stepcount =0
        if stepcount1 =36 then stepcount1 =0
         
     
    @    INT_RETURN

  26. #26
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,
    Here's three cycles with the values from you last post.
    Name:  SIN_PWM_6.GIF
Views: 926
Size:  7.0 KB

    What is that you think is wrong with it? I don't see it...

  27. #27
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    He checks for 36, shouldn't it be 35?

    Robert

  28. #28
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Quote Originally Posted by Demon View Post
    He checks for 36, shouldn't it be 35?
    No, after completing step 35, it increments, then it does a = 36 check. If it = 36, it goes back to step 0.
    http://www.scalerobotics.com

  29. #29
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Right, I forgot to check when the step was incremented, argh, and that's basic debugging procedure too (must be going senile).

  30. #30
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Could the length of PAUSE be an issue?

    http://www.picbasic.co.uk/forum/showthread.php?t=1853

    Would placing PAUSE 1 within a loop make a difference?

    What about using microseconds instead of milliseconds?

    There's a minimum delay in microseconds in the PBP manual, but I don't see oscillator setting in that last code.

    Robert

  31. #31
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    No change even if the pause 1, what I want to ask is the values in the look table greater than 255 may affect the sinwave and cause the signal to be distorted?. Can any one simulates the code and see the effect. Why the output look like this because I have try to eliminate the problem of flat spot for almost 4days but the problem still exit even although I try to edit my look table as HenrikOlsson told me about the value 512 ).

    Code:
    define OSC 4
    Wsave var byte   $70system
    Wsave1 var byte  $A0system
    Wsave2 var byte  $120system
    Wsave3 var byte  $1A0system
    
    STEPCOUNT var byte
    STEPCOUNT1 var byte
    
    LED1   VAR  PORTB.1
    
    STEPCOUNT = 0   'pointer for phase one in sinearray
    STEPCOUNT1 = 12 'pointer for phase two  in sine array
    ADCON0 = %00000000
    ADCON1 = %00000000
    
    TRISB = %11111101
    TRISC = %11111001  'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    TMR2 = 0
    PR2 = 199 'generate 5khz  'set for 18Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100  'TIMER2ON and prescale of 1:1 
    
    sineval var byte[36]
    sineval[0] = 512    
    sineval[1] = 583   
    sineval[2] = 652
    sineval[3] = 717
    sineval[4] = 775
    sineval[5] = 825
    sineval[6] = 866
    sineval[7] = 896
    sineval[8] = 915
    sineval[9] = 921   
    sineval[10] =915
    sineval[11] =896
    sineval[12] =866   
    sineval[13] =825
    sineval[14] =775
    sineval[15] =716
    sineval[16] =652
    sineval[17] =583
    sineval[18] =512   
    sineval[19] = 441
    sineval[20] = 372
    sineval[21] = 308 
    sineval[22] = 249
    sineval[23] = 199
    sineval[24] = 158
    sineval[25] = 128
    sineval[26] = 109
    sineval[27] = 103
    sineval[28] = 109 
    sineval[29] = 128
    sineval[30] = 158
    sineval[31] = 199
    sineval[32] = 249
    sineval[33] = 308
    sineval[34] = 372
    sineval[35] = 441
    
    timerone var word 
    Temp var byte
    Temp1 var byte
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System          emp
    'INCLUDE "ReEnterPBP.bas" 
     
    ASM
     
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _sine,   ASM,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    T1CON = 000001                 ; Prescaler = 1;1, TMR1 ON
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts 
     
    timerone =  65080' gives1818hz nterruptfrequency or about 50 htz sine 
    Main:
           PAUSE 1
     
    GOTO Main
     
    '---[TMR1_INT - interrupt handler]------------------------------------------
    
    sine:
         T1CON = 000000 'stop the timer
    
        TMR1L = timerone.byte0  'reload the timer
        TMR1H = timerone.byte1
        T1CON = 000001          ' start the timer
        
        
        TeMP = sineval[STEPCOUNT]
        CCP1CON.4 = Temp.0 ' bit 0
        CCP1CON.5 = Temp.1 ' bit 1       
        CCPR1L = Temp >>2  'Bit 2-7 
        
        TeMP1 = sineval[STEPCOUNT1]
        CCP2CON.4 = Temp1.0 ' bit 0
        CCP2CON.5 = Temp1.1 ' bit 1       
        CCPR2L = Temp1 >>2  'Bit 2-7
        TOGGLE LED1 
        stepcount =  stepcount +1
        stepcount1 =  stepcount1 +1
        
        if stepcount =36 then stepcount =0
        if stepcount1 =36 then stepcount1 =0
         
     
    @    INT_RETURN
    Attached Images Attached Images

  32. #32
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,614


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi,

    Do not trust in Proteus/Isis ...

    I sometimes have some VERY funny results when it perfectly works in real life ...

    " lots of examples available " ... especially when schemes are mixing analogic and digital !!!

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  33. #33
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Code:
    sineval var byte[36]
    sineval[0] = 512    
    sineval[1] = 583
    ...
    The array should be of WORDs if you want it to hold values greater than 255.

    PROTEUS Rules!!
    DT

  34. #34
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,519


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    What Darrel said.

    AND

    In a post made March 13th:
    You answered your own question in (1) from the Midrange manual:
    (1) " If the PWM duty cycle value is longer than the PWM period, the CCPx pin will not be cleared. This allows a duty cycle of 100%".

    Any dutycycle value above 796 will result in 100% dutycycle. In other words your SIN-output will be distorted/clipped.
    You have several values larger than 796 (4*199 (which is what you have PR2 set to, remember we've been thru this)) in your lookuptable so you are "overdriving" the dutycycle register and "clipping" will occur.

    /Henrik.

  35. #35
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi to all
    I tried to modify the code according to Darrel Taylor and HenrikOlsson comments but the problem still exits, let me put in real hardware and see what happen.
    And here is modified code but the output is still like that posted in the previous post.
    Code:
    define OSC 4
    Wsave var byte   $70system
    Wsave1 var byte  $A0system
    Wsave2 var byte  $120system
    Wsave3 var byte  $1A0system
    
    STEPCOUNT var byte
    STEPCOUNT1 var byte
    
    LED1   VAR  PORTB.1
    
    STEPCOUNT = 0   'pointer for phase one in sinearray
    STEPCOUNT1 = 12 'pointer for phase two  in sine array
    ADCON0 = %00000000
    ADCON1 = %00000000
    
    TRISB = %11111101
    TRISC = %11111001  'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    TMR2 = 0
    PR2 = 199 'generate 5khz  'set for 18Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100  'TIMER2ON and prescale of 1:1 
    
    sineval var word[36]
    sineval[0] = 512    
    sineval[1] = 556   
    sineval[2] = 599
    sineval[3] = 640
    sineval[4] = 676
    sineval[5] = 707
    sineval[6] = 733
    sineval[7] = 752
    sineval[8] = 763
    sineval[9] = 767  
    sineval[10] =763
    sineval[11] =752
    sineval[12] =733   
    sineval[13] =707
    sineval[14] =676
    sineval[15] =640
    sineval[16] =599
    sineval[17] =556
    sineval[18] =512   
    sineval[19] =468
    sineval[20] =425
    sineval[21] =385 
    sineval[22] =348
    sineval[23] =317
    sineval[24] =291
    sineval[25] =272
    sineval[26] =261
    sineval[27] =257
    sineval[28] =261 
    sineval[29] =272
    sineval[30] = 291
    sineval[31] = 317
    sineval[32] = 348
    sineval[33] = 385
    sineval[34] = 425
    sineval[35] = 468
    
    timerone var word 
    Temp var byte
    Temp1 var byte
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System          emp
    'INCLUDE "ReEnterPBP.bas" 
     
    ASM
     
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _sine,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    T1CON = 000001                 ; Prescaler = 1;1, TMR1 ON
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts 
     
    timerone =  65080' gives1818hz nterruptfrequency or about 50 htz sine 
    Main:
           PAUSE 5
     
    GOTO Main
     
    '---[TMR1_INT - interrupt handler]------------------------------------------
    
    sine:
         T1CON = 000000 'stop the timer
    
        TMR1L = timerone.byte0  'reload the timer
        TMR1H = timerone.byte1
        T1CON = 000001          ' start the timer
        
        
        TeMP = sineval[STEPCOUNT]
        CCP1CON.4 = Temp.0 ' bit 0
        CCP1CON.5 = Temp.1 ' bit 1       
        CCPR1L = Temp >>2  'Bit 2-7 
        
        TeMP1 = sineval[STEPCOUNT1]
        CCP2CON.4 = Temp1.0 ' bit 0
        CCP2CON.5 = Temp1.1 ' bit 1       
        CCPR2L = Temp1 >>2  'Bit 2-7
        TOGGLE LED1 
        stepcount =  stepcount +1
        stepcount1 =  stepcount1 +1
        
        if stepcount =36 then stepcount =0
        if stepcount1 =36 then stepcount1 =0
         
     
    @    INT_RETURN
    Thanks.

  36. #36
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi to all
    I try to download my program from my computer(wind7)using PIC16f877 development board and ET-CAB10PIN V2 interfacing cable but WHEN I try to run winpic800 software.
    the following problems arise.
    (1)failed to import Smport.sys
    (2)when I check the hardware it say hardware not responding

    any one can help me how to solve this problems
    thanks

  37. #37
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Last edited by Demon; - 30th March 2012 at 17:25.

  38. #38
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: ProblemwithPWMfrequency

    Hi every one
    (1) Previous I thought that the problem of flat spot on my SPWM signal was due to the simulator(ISIS) but I was wrong because I implement it on the actual hardware using PIC16F877V1-V2 DEVELOPMENT BOARD board and DLIS40L oscilloscope but the problem still remain now I'm totally confused what cause that problem of flat spot to my wave form. I try to scale my look up table so that my dutycycle lie on the range of (0 to 4*199) but nothing was change to my signal
    when viewed.
    (2)ARE the ten bit look table is not working on 8bit chip like 16F877 0R 16F777 ? I think those values greater than 255 is one cause that problems


    Code:
    define OSC 4
    Wsave var byte   $70system
    Wsave1 var byte  $A0system
    Wsave2 var byte  $120system
    Wsave3 var byte  $1A0system
     
    STEPCOUNT var byte
    STEPCOUNT1 var byte
     
    LED1   VAR  PORTB.1
     
    STEPCOUNT = 0   'pointer for phase one in sinearray
    STEPCOUNT1 = 12 'pointer for phase two  in sine array
    ADCON0 = %00000000
    ADCON1 = %00000000
     
    TRISB = %11111101
    TRISC = %11111001  'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    TMR2 = 0
    PR2 = 199 'generate 5khz  'set for 18Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100  'TIMER2ON and prescale of 1:1
     
    sineval var word[36]
    sineval[0] = 512   
    sineval[1] = 556  
    sineval[2] = 599
    sineval[3] = 640
    sineval[4] = 676
    sineval[5] = 707
    sineval[6] = 733
    sineval[7] = 752
    sineval[8] = 763
    sineval[9] = 767 
    sineval[10] =763
    sineval[11] =752
    sineval[12] =733  
    sineval[13] =707
    sineval[14] =676
    sineval[15] =640
    sineval[16] =599
    sineval[17] =556
    sineval[18] =512  
    sineval[19] =468
    sineval[20] =425
    sineval[21] =385
    sineval[22] =348
    sineval[23] =317
    sineval[24] =291
    sineval[25] =272
    sineval[26] =261
    sineval[27] =257
    sineval[28] =261
    sineval[29] =272
    sineval[30] = 291
    sineval[31] = 317
    sineval[32] = 348
    sineval[33] = 385
    sineval[34] = 425
    sineval[35] = 468
     
    timerone var word
    Temp var byte
    Temp1 var byte
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System          emp
    INCLUDE "ReEnterPBP.bas"
     
    ASM
     
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _sine,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    T1CON = 000001                 ; Prescaler = 1;1, TMR1 ON
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts
     
    timerone =  65080' gives1818hz nterruptfrequency or about 50 htz sine
    Main:
           PAUSE 5
     
    GOTO Main
     
    '---[TMR1_INT - interrupt handler]------------------------------------------
     
    sine:
         T1CON = 000000
     
        TMR1L = timerone.byte0 
        TMR1H = timerone.byte1
        T1CON = 000001         
       
       
        TeMP = sineval[STEPCOUNT]
        CCP1CON.4 = Temp.0 ' bit 0
        CCP1CON.5 = Temp.1 ' bit 1      
        CCPR1L = Temp >>2  'Bit 2-7
       
        TeMP1 = sineval[STEPCOUNT1]
        CCP2CON.4 = Temp1.0 ' bit 0
        CCP2CON.5 = Temp1.1 ' bit 1      
        CCPR2L = Temp1 >>2  'Bit 2-7
        TOGGLE LED1
        stepcount =  stepcount +1
        stepcount1 =  stepcount1 +1
       
        if stepcount =36 then stepcount =0
        if stepcount1 =36 then stepcount1 =0
        
     
    @    INT_RETURN
    (3) I'm not clear on the WINPIC800V358 software parameter on the attachment.



    Any one can help me to solve these problems
    Thankx
    Attached Images Attached Images

Members who have read this thread : 1

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