16 bit PWM using CCP1


Closed Thread
Page 1 of 2 12 LastLast
Results 1 to 40 of 61
  1. #1
    Join Date
    Oct 2004
    Posts
    440

    Default 16 bit PWM using CCP1

    I am trying to do 16 bit PWM as per Tip#10 16 bit Resolution PWM page 40 (3-10) Microchip Tips 'n Tricks

    Basically when TM1 value equals the CCP1 (PWM duty) setting the CCP1 interrupt sets PORTC.2 low (works OK).
    When the free running TM1 interrupts it is supposed to set PORTC.2 high (doesn't).

    As a test CCP1 can be configured to toggle (this works OK as see in ISIS) but if configured
    to set low for PWM the pin cannot be set high again even though CCP1 int is cleared.

    The following code tries to set pin high in TM1 interrupt.

    Norm

    Code:
        'FL PIC18F4520 
        ; @ __CONFIG _CONFIG1H, _OSC_XT_1H 
         @ __CONFIG _CONFIG1H, _OSC_HSPLL_1H
         @ __CONFIG _CONFIG2L, _BOREN_ON_2L
         @ __CONFIG _CONFIG2H, _WDT_ON_2H
         @ __CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H
         @ __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L  
    
     
        DEFINE OSC 40  
    
        Clear 
    
        sSEROUT_PIN VAR PORTA.2
        sBAUD CON 16416  '16416 = 19200 BAUD 
    
        wsave VAR BYTE bankA system    ' Saves W
        ssave VAR BYTE bankA system    ' Saves STATUS 
        yTEMP VAR Byte 
        wDUTY VAR Word  
        wDUTY = 32768 '32768 = 50% DUTY PWM
    
        '********************
        '16 BIT CCP1 PWM
        Input PORTC.2       ' Disable the HPWM output while things are being setup 
        RCON.7 = 0          ' 0 DISABLES PRIORITY LEVELS ON INTERRUPTS (16F COMPATABILITY) 
        T1CON = %10110000   ' Turn off Timer1 with a Prescaler value of 1:8
        PIE1 = %00000101    ' enable CCP1,  TMR1 overflow interrupt 
        INTCON = %11000000  ' enable global and peripheral interrupts 
        Output PORTC.2      ' Set PORTC.2 (CCP1) to output
    
    '    CCP1CON = %00000010   'TOGGLE PORTC.2 ON MATCH TM1 WITH DUTY ********** OK ************  
        CCP1CON = %00001001   'LOW PORTC.2 ON MATCH TM1 WITH DUTY ?????????? NOT OK ???????????????  
    
        T3CON = %00000000
    
    '    CCPR1L = wDUTY.LOWBYTE
        CCPR1H = wDUTY.HighByte
        CCPR1L = wDUTY.LowByte
    
    
        DEFINE  INTHAND myint 
    
        Goto START    'Jump over the subroutines
    
     
      '**** ASSEMBLY INTURRUPT ROUTINE ****  
      Asm
    myint    ;KEEP LEFT
      ; Save the state of critical registers 
          movwf    wsave            ; Save W
          swapf    STATUS, W        ; Swap STATUS To W (swap avoids changing STATUS)
          clrf    STATUS            ; Clear STATUS
          movwf    ssave            ; Save swapped STATUS
      EndAsm
    
    '     yTEMP = yTEMP +1 
    '     SerOut2 sSEROUT_PIN,sBAUD,["INT ",DEC yTEMP,13]  
    
        PIR1.2 = 0 ' CLEAR THE CCP1 INT FLAG
        High PORTC.2          '???????????????? DOES NOT SET HIGH ?????????????????
    
      Asm
            bcf     PIR1, 0            ; Clear interrupt flag
    
          swapf    ssave, W        ; Retrieve the swapped STATUS value (swap To avoid changing STATUS)
          movwf    STATUS            ; Restore it To STATUS
          swapf    wsave, F        ; Swap the stored W value
          swapf    wsave, W        ; Restore it To W (swap To avoid changing STATUS)
          retfie                   ; Return from interrupt
      EndAsm
      '**** END ASSEMBLY INTURRUPT ROUTINE **** 
     
     
      
        '***********************************************
        '***********************************************
        START:
    
        PAUSE 800 
        SerOut2 sSEROUT_PIN,sBAUD,["START",13] 
    
        T1CON.0 = 1   'TMR1 ON
    
        MAIN:
    
        yTEMP = yTEMP +1 
        SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13] 
        PAUSE 500
    
        Goto MAIN
    
        End

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


    Did you find this post helpful? Yes | No

    Default

    Hi Norm,

    To set the pin High, simply clear the CCP1CON register, then load it<sub>(Bruce)</sub> with the compare mode again %00001001 (9).

    And, only do it on a Timer1 interrupt. The CCP changes the pin low on its own, so you don't need to enable the CCP interrupt.

    A few other things are either not needed or can be done differently.
    Have a go at this ...
    Code:
        'FL PIC18F4520 
        ; @ __CONFIG _CONFIG1H, _OSC_XT_1H 
         @ __CONFIG _CONFIG1H, _OSC_HSPLL_1H
         @ __CONFIG _CONFIG2L, _BOREN_ON_2L
         @ __CONFIG _CONFIG2H, _WDT_ON_2H
         @ __CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H
         @ __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L  
    
     
        DEFINE OSC 40  
        DEFINE  INTHAND myint 
    
        Clear 
    
        sSEROUT_PIN VAR PORTA.2
        sBAUD CON 16416  '16416 = 19200 BAUD 
    
        yTEMP VAR Byte 
     
        wDUTY  VAR WORD EXT    ' map wDuty to CCPR1L:H as a word
        @wDUTY = CCPR1L
    
        '***********************************************
    START:
        ADCON1 = $0F           ' disable analog functions
        CMCON = 7              ' disable comparators
    
        '********************
        '16 BIT CCP1 PWM
        T1CON   = %00110000    ' Turn off Timer1 with a Prescaler value of 1:8
        PIE1    = %00000001    ' enable TMR1 overflow interrupt 
        INTCON  = %11000000    ' enable global and peripheral interrupts 
        CCP1CON = %00001001    ' LOW PORTC.2 ON MATCH TM1 WITH DUTY
        OUTPUT PORTC.2         ' Set PORTC.2 (CCP1) to output, starts High
        
        wDUTY = 32768          ' 32768 = 50% DUTY PWM
        T1CON.0 = 1            ' TMR1 ON
        
        PAUSE 800 
        SerOut2 sSEROUT_PIN,sBAUD,["START",13] 
    
        '***********************************************
    
    MAIN:
        yTEMP = yTEMP +1 
        SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13] 
        PAUSE 500
    Goto MAIN
    
    
      '**** ASSEMBLY INTERRUPT ROUTINE ****  
      Asm
    myint
        movlw     9                  ; %00001001 compare mode, low on match
        clrf      CCP1CON            ; clrf added per Bruce's suggestion
        movwf     CCP1CON            ; Set Pin to default state (High)
        bcf       PIR1,0             ; Clear Timer Int Flag
        retfie    FAST               ; Return from interrupt with shadow regs
      EndAsm
      '**** END ASSEMBLY INTURRUPT ROUTINE **** 
     
    
    End
    P.S. Using both CCP's with this method would make a great 2 channel hardware driven servo driver.
    Dutycycles between 2500-5000 would give pulses between 1-2ms at ~40hz.
    Last edited by Darrel Taylor; - 14th December 2009 at 04:00. Reason: Servo's + Bruce's Fix
    DT

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


    Did you find this post helpful? Yes | No

    Default 2-CH Hardware Servo Driver

    And since you made me think of it ...

    Here's a 2 channel Hardware Servo Driver, that uses Timer1 and both CCP modules in Compare mode.
    With an 18F.

    Servo outputs are the CCP? pins.
    Pulses will be continuous at ~40hz, regardless of MainLoop activity.

    Cheers ...
    Code:
    '***************************************************************************
    '*  Name    : 2CH_Servo.pbp
    '*  Author  : Darrel Taylor
    '*  Date    : 12/13/2009
    '*  Notes   : 18F's only
    '***************************************************************************
    @ __CONFIG _CONFIG1H, _OSC_HSPLL_1H
    @ __CONFIG _CONFIG2L, _BOREN_OFF_2L
    @ __CONFIG _CONFIG2H, _WDT_OFF_2H
    @ __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L  
    
    CLEAR
     
    DEFINE OSC 40  
    DEFINE  INTHAND myint 
         
    ;----[User Selections]------------------------------------------------------    
    MoveSpeed CON 3                      ' movement speed smaller = faster
    PosRange  CON 900                    ' position is 0-900, 0.0-90.0 degrees
                                         '             450 is Center
    CCP1pin   VAR PORTC.2                ' Specify the pin that CCP1 uses
    CCP2pin   VAR PORTC.1                ' Specify the pin that CCP2 uses
    
    ;----[Variables and Aliases]------------------------------------------------    
    Servo1    VAR WORD                   ' Position for Servo1
    Servo2    VAR WORD                   ' Position for Servo2
    DutyHold1 VAR WORD BANK0 SYSTEM      ' holds next dutycycle, synch with PWM 
    DutyHold2 VAR WORD BANK0 SYSTEM      '
    TempW     VAR WORD                   ' temporary variable
    POS       VAR WORD                   ' loop counter variable
    
    TMR1IE    VAR PIE1.0                 ' Timer1 Interrupt Enable
    TMR1IF    VAR PIR1.0                 ' Timer1 Interrupt Flag
    TMR1ON    VAR T1CON.0                ' Timer1 ON bit
    GIE       VAR INTCON.7               ' Global Interrupt Enable
    PEIE      VAR INTCON.6               ' Peripheral Interrupt Enable
        
    ;----[Initialization]-------------------------------------------------------
    Init:
        T1CON   = %00100000              ' Timer1 off, Prescaler 1:4 (40mhz)
                                         '          1:2 (20mhz), 1:1 (10mhz)
        TMR1IE  = 1                      ' Enable TMR1 overflow interrupt 
        TMR1IF  = 0                      ' Clear  TMR1 interrupt flag
        PEIE    = 1                      ' Enable peripheral interrupts
        GIE     = 1                      ' Enable global interrupts
        CCP1CON = 9                      ' Low on match TMR1 with DUTY1
        CCP2CON = 9                      ' Low on match TMR1 with DUTY2
        OUTPUT CCP1pin                   ' Set CCP1 pin to output, starts High
        OUTPUT CCP2pin                   ' Set CCP1 pin to output, starts High
        
        Servo1 = PosRange/2              ' Start at Center Position
        Servo2 = PosRange/2
        GOSUB SetServos
        TMR1ON = 1                       ' turn ON TMR1
        PAUSE 2000                       ' allow time for servo to Home
    
    
    ;----[Main Program Loop]----------------------------------------------------
    Main:
        FOR POS = 0 TO PosRange          ' move both from one end to the other
            Servo1 = POS
            GOSUB SetServo1              ' Set servo1's position
            Servo2 = POS
            GOSUB SetServo2              ' Set servo2's position
            PAUSE MoveSpeed              ' movement speed
        NEXT POS
        
        FOR POS = PosRange TO 0 STEP -1  ' move servo1 back to home
            Servo1 = POS
            GOSUB SetServo1
            PAUSE MoveSpeed
        NEXT POS
        
        FOR POS = PosRange TO 0 STEP -1  ' move servo2 back to home
            Servo2 = POS
            GOSUB SetServo2
            PAUSE MoveSpeed
        NEXT POS
    
        PAUSE 1000
    Goto Main                            ' rinse and repeat
    
    ;----[Convert Position in degrees to dutycycle]-----------------------------
    SetServos:                           ' Set both Servo's dutycycles
        GOSUB SetServo1
        
    SetServo2:                           ' scale Posistion to 2500 Dutycycle
        TempW = Servo2 * 2500
        TempW = DIV32 PosRange + 2500
        GIE = 0                          ' no ints during variable update
        DutyHold2 = TempW
        GIE = 1
    RETURN
    
    SetServo1:
        TempW = Servo1 * 2500            
        TempW = DIV32 PosRange + 2500
        GIE = 0
        DutyHold1 = TempW
        GIE = 1
    RETURN
       
    ;----[Dual Servo Driver - Interrupt Service]--------------------------------
    Asm
    myint
        movlw     9                  ; %00001001 compare mode, low on match
        clrf      CCP1CON            ; clrf added per Bruce's suggestion
        movwf     CCP1CON            ; Set Pins to default state (High)
        clrf      CCP2CON            ; clrf added per Bruce's suggestion
        movwf     CCP2CON
        movf      DutyHold1+1,W      ; update current position's dutycycle
        movwf     CCPR1H             ; for both servos
        movf      DutyHold1,W
        movwf     CCPR1L
        movf      DutyHold2+1,W
        movwf     CCPR2H 
        movf      DutyHold2,W
        movwf     CCPR2L
        bcf       PIR1,0             ; Clear Timer Int Flag
        retfie    FAST               ; Return from interrupt with shadow regs
    EndAsm
    Last edited by Darrel Taylor; - 14th December 2009 at 04:01. Reason: Bruce's Fix
    DT

  4. #4
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Hi Darrel,

    Pretty cool stuff. Have you tested this on other 18F parts? I don't have a 4520 to test
    with, but I couldn't get this to work without clearing CCP1CON before moving 9 to it on
    a 452 or 4431.

    Had to do this;
    Code:
    ASM
    MyInt                    
        clrf CCP1CON         ; 18F452 & 18F4431 require this before it changes CCP1 output
        movlw 9
        movwf CCP1CON
        bcf PIR1,TMR1IF      ; clear TMR1 int flag
        retfie FAST          ; use RETFIE FAST to restore WREG, STATUS & BSR
    ENDASM
    On an 18F452 or 18F4431, the above works fine, but only if I clear CCP1CON first.

    This works on a 452 & 4431 with CCP1 & TMR1 ints enabled on any output pin;
    Code:
    ASM
    MyInt                    
        btfss PIR1,TMR1IF    ; TMR1 interrupt?
        bra CCP              ; no - service CCP interrupt
        bcf PIR1,TMR1IF      ; yes - clear TMR1 int flag
        bsf LATB,0           ; set RB0 on TMR1 interrupt
        retfie FAST          ; return
    CCP
        bcf PIR1,CCP1IF      ; clear CCP1 int flag
        bcf LATB,0           ; clear RB0 on compare interrupt
        retfie FAST          ; use RETFIE FAST to restore WREG, STATUS & BSR
    ENDASM
    I was just wondering if this might be a fluke with the 4520 part - since none of the other
    18F parts I've tested will toggle CCP1 with just the movlw 9, movwf CCP1CON?
    Last edited by Bruce; - 14th December 2009 at 03:34. Reason: 2nd version uses CCP1CON = %00001010
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

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


    Did you find this post helpful? Yes | No

    Default

    Hmmm, very interesting.

    I had not tried it on any other chips, and with the 4520 you definitely don't have to clear it first.

    But I just tried an 18F452, and you are absolutely correct.
    It doesn't work unless you clear the CCPCON register first.

    Very interesting indeed,
    Thanks Bruce.
    <br>
    DT

  6. #6
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Thanks. I was just curious. I had fought with this one before on a servo driver, and just
    couldn't get it to work without both ints enabled, or clearing CCP1CON first.

    I'm thinking it may be due to the huge number of problems Mchip had (see erratas') on
    ECCP & CCP with this one?
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Bruce View Post
    I'm thinking it may be due to the huge number of problems Mchip had (see erratas') on ECCP & CCP with this one?
    No doubt!

    BTW, I like the any Output Pin variation too.
    <br>
    DT

  8. #8
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default

    Works good!
    Thanks Darrel

    Would it be correct to say the maximum PWM frequency for a 40 MHz PIC is 152 Hz?
    To slow for music.
    Know of any > 10 bit PWM PIC's?

    Norm

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


    Did you find this post helpful? Yes | No

    Default

    Yup, that's what mister-e's calculator says with 40mhz, 1:1, and 16-bit. 152 hz.

    The PIC18F2331/2431/4331/4431 series has a bunch of 14-bit PWM modules. But they are completely different from the CCP module.

    Bruce has done a few examples, but I don't think any of them were for music.

    best regards,
    DT

  10. #10
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default

    PIC18F2331/2431/4331/4431:

    FOSC 40 MHz
    MIPS 10
    PWM Resolution 14 bits
    PWM Frequency 2.4 kHz

    14 bit to slow for CD quality music.
    10 bit sounds good though.

    A dsPIC would be ideal.

    On my first post my code included saving the state of the critical registers.
    Would this be required in a longer program?

    Norm
    Last edited by Normnet; - 14th December 2009 at 06:57.

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


    Did you find this post helpful? Yes | No

    Default

    Maybe you'd be better off with an R2R network as a Digital to Analog Converter.

    Something like what Steven Wright did here (Not PBP).
    SDMMCWavPlayer
    http://www.sfcompiler.co.uk/wiki/pmw...SDMMCWavPlayer


    And no, you won't need to save STATUS, WREG and BSR, unless you start using Low Priority interrupts.
    The Shadow registers automatically save and restore them in hardware for High priority ints on 18F's.
    <br>
    DT

  12. #12
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default

    R2 ladder done here PIC iPod wav player

    Now would like to port to PBP a basic PWM low pin count low part count wave player.
    The code is 8,069 program bytes possibly less if optimized.
    Are their < 28 pin 18F PICs supported by compiler 2.50C?

    Norm

  13. #13
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    .... Pulses will be continuous at ~40hz ....
    How do you get ~40-Hz?

    <added>

    Oops! Sorry! I see it. Timer 1 rollover every 26.2144 msecs (38.14697265625 Hz)... I need another cup o' coffee (grin)...
    Last edited by Mike, K8LH; - 28th October 2010 at 17:13.

  14. #14
    Join Date
    Nov 2009
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Hi Everyone,
    Talat from Istanbul here. Please help wıth my PWM problem.
    My code is runnıng BUT I get only 1 or 2 output pulses from port B3 on startup then no output after that.
    What am ı doıng wrong?
    Thanks ın advance fo you help.
    Talat

    '************************************************* ***************
    '* Name : *
    '* Author : [select VIEW...EDITOR OPTIONS] *
    '* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
    '* : All Rights Reserved *
    '* Date : 09.08.2014 *
    '* Version : 1.0 *
    '* Notes : 16F1827 *
    '* : *
    '************************************************* ***************
    ' DEVİCE 16F1827

    ASM
    __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
    __config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
    ENDASM
    CLEAR
    DEFINE OSC 32
    OSCCON=%01110000 '32

    DEFINE INTHAND PWM_INT

    PWM_VAL VAR WORD BANK0 SYSTEM
    VALUE VAR WORD

    INIT:
    APFCON0 = 0 'SET PORTB.3 TO CCP1
    T1CON = %00100000 'Prescaler 1:4

    PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
    PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
    INTCON.7 = 1 'GIE Global Interrupt Enable
    INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
    CCP1CON = 9 'compare mode
    OUTPUT PORTB.3 'CCP PIN


    T1CON.0 = 1 'TMR1ON SET TMR1
    PAUSE 1000
    VALUE=1000

    MLOOP:
    VALUE=VALUE+1
    PWM_VAL = VALUE
    Goto MLOOP


    Asm
    PWM_INT
    movlw 9 ; compare mode
    clrf CCP1CON ; clear reg
    movwf CCP1CON ; Set reg
    movf PWM_VAL+1,W ; hb
    movwf CCPR1H ; put
    movf PWM_VAL,W ; lb
    movwf CCPR1L ; put
    bsf INTCON,7 ;GIE = 1
    bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
    bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
    bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag

    RETFIE ; Return from Interrupt
    EndAsm

    END

  15. #15
    Join Date
    Nov 2009
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Hi Darrel & Everyone,
    Talat from Istanbul here. Please help with my PWM problem.
    My code is running(?) BUT I get only 1 or 2 output pulses from port B3 on startup then no output after that.
    What am I doıng wrong?
    Thanks in advance fo you help.
    Talat

    '************************************************* ***************
    '* Name : *
    '* Author : [select VIEW...EDITOR OPTIONS] *
    '* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
    '* : All Rights Reserved *
    '* Date : 09.08.2014 *
    '* Version : 1.0 *
    '* Notes : 16F1827 *
    '* : *
    '************************************************* ***************
    ' DEVİCE 16F1827

    ASM
    __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
    __config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
    ENDASM
    CLEAR
    DEFINE OSC 32
    OSCCON=%01110000 '32

    DEFINE INTHAND PWM_INT

    PWM_VAL VAR WORD BANK0 SYSTEM
    VALUE VAR WORD

    INIT:
    APFCON0 = 0 'SET PORTB.3 TO CCP1
    T1CON = %00100000 'Prescaler 1:4

    PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
    PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
    INTCON.7 = 1 'GIE Global Interrupt Enable
    INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
    CCP1CON = 9 'compare mode
    OUTPUT PORTB.3 'CCP PIN


    T1CON.0 = 1 'TMR1ON SET TMR1
    PAUSE 1000
    VALUE=1000

    MLOOP:
    VALUE=VALUE+1
    PWM_VAL = VALUE
    Goto MLOOP


    Asm
    PWM_INT
    movlw 9 ; compare mode
    clrf CCP1CON ; clear reg
    movwf CCP1CON ; Set reg
    movf PWM_VAL+1,W ; hb
    movwf CCPR1H ; put
    movf PWM_VAL,W ; lb
    movwf CCPR1L ; put
    bsf INTCON,7 ;GIE = 1
    bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
    bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
    bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag

    RETFIE ; Return from Interrupt
    EndAsm

    END
    Last edited by talatsahim; - 20th August 2014 at 21:42.

  16. #16
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,611


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Hi, Talatsahim

    First have a look to how PBP shares its variables with asm ...

    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 " !!!
    *****************************************

  17. #17
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Quote Originally Posted by Acetronics2 View Post
    Hi, Talatsahim

    First have a look to how PBP shares its variables with asm ...

    Alain
    _WhatsThat ?
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  18. #18
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    For starters, There is NO 16 bit compare register for PWM use. The upper byte is shared with a few other bits of config. There is ONLY 10 bit's available for PWM use in hardware. Read the data sheet for the processor you are using.
    Dave Purola,
    N8NTA
    EN82fn

  19. #19
    Join Date
    Nov 2009
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Hi, Acetronics2

    This is part of code. Variable sharing, what is wrong?

    Thanx

  20. #20
    Join Date
    Nov 2009
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Thanx Dave,

    I use 10 bit hardware PWM. But I need more resulation. I such a little trick

    Talat

  21. #21
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    What Acetronics2 is trying to say is, when accessing PBP variables inside of an ASM routine you need to prefix an underscore before the variable name such as "movf _PWM_VAL,W ; lb"
    As far as getting more resolution from the PIC processor, Your out of luck. You can always build your own digital pwm circuit with hardware if you are so inclined.
    Last edited by Dave; - 22nd August 2014 at 12:55.
    Dave Purola,
    N8NTA
    EN82fn

  22. #22
    Join Date
    Nov 2009
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Hi Dave,
    This is just copy-paste error..
    What's interesting is that, these codes do not work to as 8-bit (10 bit too)
    Thanx

  23. #23
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Hi,
    As far as getting more resolution from the PIC processor, Your out of luck.
    So, Microchip themselves and previous posters in the this thread (Darrel, Bruce, Norm) are wrong then, what am I missing?

    When using the CCP module in PWM mode it's limited to 10bits resolution. But if you use it in compare mode, the way that the application note describes you can get 16bit resolution but:
    1) You won't be able to get 100% dutycycle
    2) The maximum output frequency will be limited to ~122Hz @32MHz.
    3) You'll get some CPU load from the interrupt processing.
    4) You need to deal with assembly code in the ISR (or deal with more "CPU load" if using DT-Ints)

    /Henrik.

  24. #24
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Quote Originally Posted by Dave View Post
    What Acetronics2 is trying to say is, when accessing PBP variables inside of an ASM routine you need to prefix an underscore before the variable name such as "movf _PWM_VAL,W ; lb"
    As far as getting more resolution from the PIC processor, Your out of luck. You can always build your own digital pwm circuit with hardware if you are so inclined.
    But Darrel did not do this in his code, prefix with "_". Also as Talat has said he is following Darel's example for "16 bit PWM using CCP1" which obviously worked for Darrel, Bruce and Norm.

    So Talat 16 bit PWM is possible. I have read the whole thread and the datasheets for the 18F452 and the chip you are using 16F1827.

    The first possible issue Darell said his code was for 18F's only in post 3 does anyone know why not 16F's? The 16F has CCPx compare mode.
    With regard to the 16F1827 I think CCP4 has the required features needed and CCP1 does not but I need more time to re-read the datasheet but in the meantime it would be helpful if some one could confirm which CCPx should be used.

  25. #25
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    in dt's code the var is declared in a asm routine and as EXT in pbp

    wDUTY VAR WORD EXT ' map wDuty to CCPR1L:H as a word
    @wDUTY = CCPR1L
    if you declare a var in pbp and wish to refer to it in asm it must be prefixed with an underscore as others have stated
    Last edited by richard; - 23rd August 2014 at 08:33. Reason: still can't spell

  26. #26
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Quote Originally Posted by richard View Post
    in dt's code the var is declared in a asm routine and as EXT in pbp


    if you declare a var in pbp and wish to refer to it in asm it must be prefixed with an underscore as others have stated
    That is from post #1 but in #3 which Talat is using
    Code:
    DutyHold1 VAR WORD BANK0 SYSTEM      ' holds next dutycycle, synch with PWM 
    DutyHold2 VAR WORD BANK0 SYSTEM      '
    is the way they are declared and again "_" is not used.

  27. #27
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Found the answer in the manual of all places!
    Modifiers can be used to specify certain attributes of the variable when created:
    address A numeric address may be used as a modifier. This instructs PBP where to locate the variable in RAM.
    BANKx Instructs PBP to locate the variable in a specific bank of RAM.
    SYSTEM The default behavior of PBP is to append a prefix underscore character when creating the variable in Assembly Language. The SYSTEM modifier inhibits this behavior so that the variable name will be identical in PBP code and Assembly code.
    Does anyone read the manual, me included obviously?

  28. #28
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    when all else fails

  29. #29
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Quote Originally Posted by EarlyBird2 View Post
    The first possible issue Darell said his code was for 18F's only in post 3 does anyone know why not 16F's? The 16F has CCPx compare mode.
    With regard to the 16F1827 I think CCP4 has the required features needed and CCP1 does not but I need more time to re-read the datasheet but in the meantime it would be helpful if some one could confirm which CCPx should be used.
    Having dealt with the "_", wild goose chase, which had nothing to do with the problem any ideas?

  30. #30
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    I'm trying to get this idea to fly on a 16f1825
    the code when converted to C works fine (I get a nice pwm waveform at 60.85 hz)
    but it won't fly with pbp3 yet


    Code:
    /*
     * File:   newmain.c
     * Author: richard
     *
     * Created on 23 August 2014, 7:25 PM
     */
    
    
    #include <xc.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.
    
    // CONFIG1
    #pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
    #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
    #pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
    #pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
    #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
    #pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
    #pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
    #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
    #pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
    #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
    
    // CONFIG2
    #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    #pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
    #pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
    #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    #pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
    
    typedef unsigned char byte;
    #define bit_time 100    //   9600 ok @8mhz
    #define serout_pin PORTAbits.RA0
    
    #define _XTAL_FREQ 32000000
    
    
    
    void send_serial( char data);
    void ser_str(char *buff);
    byte prnb[20]; 
    uint16_t duty;
    
    void main(void) {
    
       OSCCON=0X70;
       ANSELA=0;
       ANSELC=0;
     
       TRISA = 0b001110;
       TRISC=0b11111001;
       PORTA=255;
        __delay_ms(2000);
       T1CON   = 0b00000000 ;
        PIE1    = 0b00000001;
         INTCON  = 0b11000000;
        CCP4CON = 0b00001001;
           
        duty = 32768 ;
        CCPR4H=duty>>8;
         CCPR4L=duty;
         
                T1CONbits.TMR1ON=1;
        
        
        
    
       strcpy(prnb,"ready");
    ser_str(prnb);
     
    INTCON=0xc0;
    while(1){
     
       strcpy(prnb," loop ");
       ser_str(prnb);
       sprintf(prnb,"%4x",duty) ;
       duty+=200;
       ser_str(prnb);
       CCPR4H=duty>>8;
       CCPR4L=duty;
       __delay_ms(2000);
    
    
      }
    
    
    
    
        return;
    }
    
    
    void interrupt ISR (void) {
        CCP4CON=0;
        CCP4CON=9;
             
        PIR1bits.TMR1IF=0;
        PORTCbits.RC2=!PORTCbits.RC2; // just to check interrupt
    
     
    }
    
    
    
    
    
    
    
    void send_serial( char data){  // bit_time 200us 4800 baud ,100 us 9600 ,400us 2400 (NOT INVERTED)
      uint8_t i;
    
      i=8;                            // 8 data bits to send
     // di();
      serout_pin = 0;                // make start bit
       __delay_us(bit_time);
      while(i)                        // send 8 serial bits, LSB first
      {
        if(data&1) serout_pin = 1;  // invert and send data bit
        else   serout_pin  = 0;
    
        data >>=1 ;//(data >> 1);           // rotate right to get next bit
        i--;
           __delay_us(bit_time);           // wait for baud
      }
    
      serout_pin  = 1;                // make stop bit
      // ei();
       __delay_us(bit_time);
    
    }
    void ser_str(char *buff){
     char k = strlen(buff);
           for (int j=0;j< k;j++){
           send_serial(buff[j]);
           }
    }

  31. #31
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    A pbp version
    Code:
    '****************************************************************
    '*  Name    : PWM16.BAS                                      *
    '*  Author  : RICHARD                    *
    '*  Notice  : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 8/23/2014                                         *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
      
    #CONFIG
                 __config        _CONFIG1,    _FOSC_INTOSC & _CP_OFF & _WDTE_ON  &  _PWRTE_ON  &  _MCLRE_ON  & _CLKOUTEN_OFF
                  __config      _CONFIG2, _PLLEN_ON & _LVP_OFF
    #ENDCONFIG
    
    
     
      include "dt_ints-14.bas"
      
    
    asm
    INT_LIST macro
          
         
         
         
          INT_HANDLER TMR1_INT, _Tm1, asm,yes
          endm
           INT_CREATE
           
         
           
    ENDASM   
    
     
        DEFINE OSC 32 
        
    
         
    
        sSEROUT_PIN VAR PORTA.0
        sBAUD CON 84  '16416 = 19200 BAUD 
    
        yTEMP VAR Byte 
     
        wDUTY  VAR WORD       
        
    
        '***********************************************
    START:
           ' disable analog functions
       OSCCON=$70
       ANSELA=0
       ANSELC=0
    
        '********************
        '16 BIT CCP1 PWM
        T1CON   = 0   ' Turn off Timer1 with a Prescaler value of 1:8
        PIE1    = %00000001    ' enable TMR1 overflow interrupt 
        INTCON  = %11000000    ' enable global and peripheral interrupts 
         ' LOW PORTC.2 ON MATCH TM1 WITH DUTY
        ccp4con=0
        wDUTY = 32768          ' 32768 = 50% DUTY PWM
        T1CON.0 = 1            ' TMR1 ON
        CCPR4H=$80;
        CCPR4L=0;
        PAUSE 800 
        SerOut2 sSEROUT_PIN,sBAUD,["START",13] 
         trisc = %11111001
        '***********************************************
          CCP4CON = %00001001  
    MAIN:
        yTEMP = yTEMP +1 
        SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13] 
        PAUSE 500
    Goto MAIN
    
    
      '**** ASSEMBLY INTERRUPT ROUTINE ****  
    Tm1: 
      Asm
        bsf PORTC  ,2
        CHK?RP   CCP4CON                  
        clrf      CCP4CON 
        movlw     9            
        movwf     CCP4CON            
          banksel 0 
        bcf      PORTC  ,2
        
      EndAsm
      '**** END ASSEMBLY INTURRUPT ROUTINE **** 
    @ INT_RETURN 
    End

  32. #32
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Quote Originally Posted by richard View Post
    A pbp version
    Code:
    '****************************************************************
    '*  Name    : PWM16.BAS                                      *
    '*  Author  : RICHARD                    *
    '*  Notice  : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 8/23/2014                                         *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
      
    #CONFIG
                 __config        _CONFIG1,    _FOSC_INTOSC & _CP_OFF & _WDTE_ON  &  _PWRTE_ON  &  _MCLRE_ON  & _CLKOUTEN_OFF
                  __config      _CONFIG2, _PLLEN_ON & _LVP_OFF
    #ENDCONFIG
    
    
     
      include "dt_ints-14.bas"
      
    
    asm
    INT_LIST macro
          
         
         
         
          INT_HANDLER TMR1_INT, _Tm1, asm,yes
          endm
           INT_CREATE
           
         
           
    ENDASM   
    
     
        DEFINE OSC 32 
        
    
         
    
        sSEROUT_PIN VAR PORTA.0
        sBAUD CON 84  '16416 = 19200 BAUD 
    
        yTEMP VAR Byte 
     
        wDUTY  VAR WORD       
        
    
        '***********************************************
    START:
           ' disable analog functions
       OSCCON=$70
       ANSELA=0
       ANSELC=0
    
        '********************
        '16 BIT CCP1 PWM
        T1CON   = 0   ' Turn off Timer1 with a Prescaler value of 1:8
        PIE1    = %00000001    ' enable TMR1 overflow interrupt 
        INTCON  = %11000000    ' enable global and peripheral interrupts 
         ' LOW PORTC.2 ON MATCH TM1 WITH DUTY
        ccp4con=0
        wDUTY = 32768          ' 32768 = 50% DUTY PWM
        T1CON.0 = 1            ' TMR1 ON
        CCPR4H=$80;
        CCPR4L=0;
        PAUSE 800 
        SerOut2 sSEROUT_PIN,sBAUD,["START",13] 
         trisc = %11111001
        '***********************************************
          CCP4CON = %00001001  
    MAIN:
        yTEMP = yTEMP +1 
        SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13] 
        PAUSE 500
    Goto MAIN
    
    
      '**** ASSEMBLY INTERRUPT ROUTINE ****  
    Tm1: 
      Asm
        bsf PORTC  ,2
        CHK?RP   CCP4CON                  
        clrf      CCP4CON 
        movlw     9            
        movwf     CCP4CON            
          banksel 0 
        bcf      PORTC  ,2
        
      EndAsm
      '**** END ASSEMBLY INTURRUPT ROUTINE **** 
    @ INT_RETURN 
    End
    Impressive Richard!

    What was the difference CCP4?

  33. #33
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    no any ccp will work I tested it on 2,3 and 4 , the issue was the Bank selection a pic18 doesn't need it a pic16 will die without it

  34. #34
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Code:
    '************************************************* ***************
    '* Name : *
    '* Author : [select VIEW...EDITOR OPTIONS] *
    '* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
    '* : All Rights Reserved *
    '* Date : 09.08.2014 *
    '* Version : 1.0 *
    '* Notes : 16F1827 *
    '* : *
    '************************************************* ***************
    ' DEVİCE 16F1827
    
    ASM
    __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
    __config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
    ENDASM
    CLEAR
    DEFINE OSC 32
    OSCCON=%01110000 '32
    
    DEFINE INTHAND PWM_INT
    
    PWM_VAL VAR WORD BANK0 SYSTEM
    VALUE VAR WORD
    
    INIT:
    APFCON0 = 0 'SET PORTB.3 TO CCP1
    T1CON = %00100000 'Prescaler 1:4
    
    PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
    PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
    INTCON.7 = 1 'GIE Global Interrupt Enable
    INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
    CCP1CON = 9 'compare mode
    OUTPUT PORTB.3 'CCP PIN
    
    
    T1CON.0 = 1 'TMR1ON SET TMR1
    PAUSE 1000
    VALUE=1000
    
    MLOOP:
    VALUE=VALUE+1
    PWM_VAL = VALUE
    Goto MLOOP
    
    
    Asm
    PWM_INT
    movlw 9 ; compare mode
    clrf CCP1CON ; clear reg
    movwf CCP1CON ; Set reg
    movf PWM_VAL+1,W ; hb
    movwf CCPR1H ; put
    movf PWM_VAL,W ; lb
    movwf CCPR1L ; put
    bsf INTCON,7 ;GIE = 1
    bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
    bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
    bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag
    
    RETFIE ; Return from Interrupt
    EndAsm
    
    END
    Now we know that what you want to do is possible, thanks to Richard. Can anyone work out what is wrong with Talat's code?

  35. #35
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    I didn't pickup what ver of pbp talat was using , and I'm not sure if the chk?rp macro exists in early versions


    but try
    Code:
    Asm
    PWM_INT
    CHK?RP   CCP1CON
    movlw 9 ; compare mode
    clrf CCP1CON ; clear reg
    movwf CCP1CON ; Set reg
    CHK?RP  PWM_VAL
    movf PWM_VAL+1,W ; hb
    CHK?RP   CCPRIL
    movwf CCPR1H ; put
    CHK?RP  PWM_VAL
    movf PWM_VAL,W ; lb
    CHK?RP   CCPRIL
    movwf CCPR1L ; put
    banksel 0
    bsf INTCON,7 ;GIE = 1
    bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
    bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
    bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag
    
    RETFIE ; Return from Interrupt
    EndAsm
    if that fails try

    banksel CCP1CON OR WHATERVER SFR

    OR
    read data sheet and find what bank each sfr is in


    with all that bank switching the effort may be pointless

  36. #36
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    a warning to anybody trying to use this idea , its not fool proof and apart from the limitations as described by henrik its a bit risky too.

    if you try to set the pwm duty below the number of timer ticks taken up during the interrupt latency the pwm pin will be driven high and may cause unexpected results
    my tests indicate a minimum pwm duty of 30
    caveat emptor

  37. #37
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    post 35 is wrong pie1 is not in bank0 either

    Code:
    Asm
    PWM_INT
    CHK?RP   CCP1CON
    movlw 9 ; compare mode
    clrf CCP1CON ; clear reg
    movwf CCP1CON ; Set reg
    CHK?RP  PWM_VAL
    movf PWM_VAL+1,W ; hb
    CHK?RP   CCPRIL
    movwf CCPR1H ; put
    CHK?RP  PWM_VAL
    movf PWM_VAL,W ; lb
    CHK?RP   CCPRIL
    movwf CCPR1L ; put
    banksel 0
    bsf INTCON,7 ;GIE = 1
    bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
    CHK?RP   PIE1
    bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
    BANKSEL 0
    bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag
    
    RETFIE ; Return from Interrupt
    EndAsm

    it just gets worse

  38. #38
    Join Date
    Nov 2009
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Richard and EarlyBird,
    Thank you very much for your generosity and support.
    I'm using version 3.0.1.4.


    Talat

  39. #39
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    Talat

    I do not understand why you included the lines in red in you ISR

    Code:
    '************************************************* ***************
    '* Name : *
    '* Author : [select VIEW...EDITOR OPTIONS] *
    '* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
    '* : All Rights Reserved *
    '* Date : 09.08.2014 *
    '* Version : 1.0 *
    '* Notes : 16F1827 *
    '* : *
    '************************************************* ***************
    ' DEVİCE 16F1827
    
    ASM
    __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
    __config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
    ENDASM
    CLEAR
    DEFINE OSC 32
    OSCCON=%01110000 '32
    
    DEFINE INTHAND PWM_INT
    
    PWM_VAL VAR WORD BANK0 SYSTEM
    VALUE VAR WORD
    
    INIT:
    APFCON0 = 0 'SET PORTB.3 TO CCP1
    T1CON = %00100000 'Prescaler 1:4
    
    PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
    PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
    INTCON.7 = 1 'GIE Global Interrupt Enable
    INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
    CCP1CON = 9 'compare mode
    OUTPUT PORTB.3 'CCP PIN
    
    
    T1CON.0 = 1 'TMR1ON SET TMR1
    PAUSE 1000
    VALUE=1000
    
    MLOOP:
    VALUE=VALUE+1
    PWM_VAL = VALUE
    Goto MLOOP
    
    
    Asm
    PWM_INT
    movlw 9 ; compare mode
    clrf CCP1CON ; clear reg
    movwf CCP1CON ; Set reg
    movf PWM_VAL+1,W ; hb
    movwf CCPR1H ; put
    movf PWM_VAL,W ; lb
    movwf CCPR1L ; put
    bsf INTCON,7 ;GIE = 1
    bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
    bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
    bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag
    
    RETFIE ; Return from Interrupt
    EndAsm
    
    END
    As I do not have a 16F1827 I can not do any testing. But after some thought I used an 18F452 to test your code and it did not work. I then compared data sheets for the 16F1827 and 18F452 and finding no reason for the lines in red I commented them out reprogramed the 18F452 and it ran. But I had to add a pause 10 in the main loop so my voltmeter could display the readings.

    Here is my version

    Code:
    '************************************************* ***************
    '* Name : *
    '* Author : [select VIEW...EDITOR OPTIONS] *
    '* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
    '* : All Rights Reserved *
    '* Date : 09.08.2014 *
    '* Version : 1.0 *
    '* Notes : 16F1827 *
    '* : *
    '************************************************* ***************
    ' DEVİCE 16F1827
    
    ASM
    __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
    __config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
    ENDASM
    CLEAR
    DEFINE OSC 32
    OSCCON=%01110000 '32
    
    DEFINE INTHAND PWM_INT
    
    PWM_VAL VAR WORD BANK0 SYSTEM
    
    
    INIT:
    APFCON0 = 0 'SET PORTB.3 TO CCP1
    T1CON = %00100000 'Prescaler 1:4
    
    PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
    PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
    INTCON.7 = 1 'GIE Global Interrupt Enable
    INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
    CCP1CON = 9 'compare mode
    OUTPUT PORTB.3 'CCP PIN
    
    
    T1CON.0 = 1 'TMR1ON SET TMR1
    PAUSE 1000
    
    
    MLOOP:
    PWM_VAL = PWM_VAL+1
    PAUSE 10
    Goto MLOOP
    
    
    Asm
    PWM_INT
    movlw 9 ; compare mode
    clrf CCP1CON ; clear reg
    movwf CCP1CON ; Set reg
    movf PWM_VAL+1,W ; hb
    movwf CCPR1H ; put
    movf PWM_VAL,W ; lb
    movwf CCPR1L ; put
    bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag
    
    RETFIE ; Return from Interrupt
    EndAsm
    
    END
    I am very interested to know if my version works on the 16F1827 that you have.

  40. #40
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: 16 bit PWM using CCP1

    your version cannot work since CCP1CON and CCPR1H are not in bank 0

    and yes the code you marked red serves no purpose in the given example

Similar Threads

  1. Bits, Bytes Words and Arrays
    By Melanie in forum FAQ - Frequently Asked Questions
    Replies: 24
    Last Post: - 14th June 2016, 08:55
  2. Half-bridge PWM with a 16F684 ?
    By Byte_Butcher in forum General
    Replies: 7
    Last Post: - 17th January 2010, 23:18
  3. PICBasic newbie problem
    By ELCouz in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 12th February 2008, 01:55
  4. How to tell which PICs can handle 16 bit variables?
    By MikeTamu in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 31st August 2005, 09:44
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 02:07

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