16 bit PWM using CCP1


Results 1 to 40 of 61

Threaded View

  1. #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 03:00. Reason: Servo's + Bruce's Fix
    DT

Similar Threads

  1. Bits, Bytes Words and Arrays
    By Melanie in forum FAQ - Frequently Asked Questions
    Replies: 24
    Last Post: - 14th June 2016, 07:55
  2. Half-bridge PWM with a 16F684 ?
    By Byte_Butcher in forum General
    Replies: 7
    Last Post: - 17th January 2010, 22:18
  3. PICBasic newbie problem
    By ELCouz in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 12th February 2008, 00: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, 08:44
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

Members who have read this thread : 2

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