CCP and timers to capture frequency


+ Reply to Thread
Results 1 to 4 of 4
  1. #1
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    227

    Default CCP and timers to capture frequency

    Related to , but different aspect, of "PPS understanding on 16F15313"http://www.picbasic.co.uk/forum/showthread.php?t=24129. Figured a new thread naming the issue would be better.

    This system receives pulses between 0 and 250Hz. I need to distinguish when it crosses above 45Hz and derive a count that I can use to generate a PWM based on the measured frequency. I don't need to measure below that frequency, just set a flag, so that the Main can still pulse when it has a capture. Basically, it monitors ECU tach pulses and each pulse generates a pulse out, no matter the frequency. Above 45Hz, it synthesizes an output that is related to pulse speed, but is not linear, so it must be generated.

    Still not understanding of why I'm getting quite an unstable timer capture.

    The thought is to let TMR1 roll over and check those (Overflow) and grab the remainder. If the preload is set so that it overflows below 45Hz, I can just ignore anything that overflows, and if no overflow, use the remainder to determine frequency in. I have not applied the preload of 22063 yet to TMR1 (1:1) as I can't even get it to read with any stability yet. Getting 0-2 overflows @45Hz and remainder all over the place. If this is this fragile in the striped down form, there's no way I'm going to be able to add needed code for the rest of it.

    If you eagle-eyed members can see my error, or have a different way of doing this, I'd love to hear it.
    Thank you
    bo

    Code:
    '****************************************************************
    '*  Name    : 324_CCP1_Test.pbp                                 *
    '*  Date    : 09/30/20                                          *  
    '*  Notes   : TEST  using PPS and CCP1                          *
    '****************************************************************
    '*THIS REV:  timing erratic
    
    INCLUDE "DT_INTS-16F18xx.bas"  ; v1.20 Modified for 16F183xx: IOC INTs added for each pin.
    INCLUDE "ReEnterPBP.pbp"    ; Include for DT_INTS.  ver 3.4
    
    DEFINE OSC 8
    PulseIn     var PORTC.5  ' Monitor ECM tachometer signal 
    PulseFlag   var byte       ' register if CAPTURE Int was entered
    Overflows   VAR word    ' count the times TMR1 overflows
    Remainder   VAR word    ' remaining TMR1 ticks after last overflow
    ANSELA = 0                  ' Set all digital 
    ANSELC = 0
    CCP1CON = %10000101     ' On, Capture every + edge
    CCP1PPS = 00010101         ' set CCP1 input to RC5
    'CCPTMRS = %01010101     ' ALL CCPS using TMR1 (already default)
    'INTCON = %11000001
    OSCEN  = %01000000       ' HFINTOSC ENABLED
    OSCFRQ = %00000100      '  100:8mhZ, 101:12MHz, 110:16MHz
    PORTA  = %00000000        ' Outputs 
    PORTC  = %00100000       ' Outputs except RC5 for Tach In input
    TRISA  = %00000000        ' Pins output
    TRISC  = %00100000        ' Outputs except RC5 for Tach In input 
    T1CON  = %00000001       ' 1:1 prescale, clock=Fosc/4, TMR1=on 
    T2CON  = %00000100       ' 1:1 PRE and POST, ON 
    '********* USART  ****************************************************
    DEFINE HSER_RCSTA 90h   ' Set receive register to receiver enabled
    DEFINE HSER_TXSTA 20h   ' Set transmit register to transmitter enabled
    DEFINE HSER_BAUD 9600   ' Set baud rate
    DEFINE HSER_SPBRG 25    ' Set SPBRG directly
    HSEROUT ["324_CCP1_test",10,13]
    pause 2000
    ;----[Interrupts]----------------------------------------
    ASM
    INT_LIST  macro    ; IntSource,   Label,   Type, ResetFlag?
            INT_Handler   CCP1_INT, _Capture,   PBP,  yes        ; WORKS
            INT_Handler   TMR1_INT,  _Timer1,    PBP,  yes
        endm
        INT_CREATE               ; Creates the High Priority interrupt processor
    ENDASM
    @    INT_ENABLE  CCP1_INT    ; enable Capture interrupts
    @    INT_ENABLE  TMR1_INT    ; enable Timer 1 interrupts
    Main:
      IF PulseFlag = 1 THEN
    '     PULSOUT tachdrv, 50      ' 
         HSEROUT ["OF= ",DEC Overflows,"  ,Ticks= ",DEC Remainder, 13,10]
         PulseFlag = 0
         Overflows = 0
         PIR1.0 = 0               ' clear TMR1IF
      ELSE 
        HSEROUT ["NoFlag", 13,10]  
      ENDIF 
    GOTO Main
    '---[CCP1 - interrupt handler]------------------------------------------
    Capture:  ' Enter here with input Pulse  (CCP1) 
        Remainder = TMR1
        PulseFlag = 1           ' set flag to pulse out @ each +capture
        PIR4.0 = 0              ' clear CCP1IF
    @ INT_RETURN
    ''**** TMR *********
    Timer1:
        Overflows = Overflows + 1
    @ INT_RETURN    
    END

  2. #2
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    227

    Default Re: CCP and timers to capture frequency

    I'm trying to base this on Tip #1 from http://ww1.microchip.com/downloads/e...Doc/41214a.pdf, but evidently I'm not turning the suggested steps into code very well.

  3. #3
    Join Date
    May 2013
    Location
    australia
    Posts
    1,731

    Default Re: CCP and timers to capture frequency

    my old proteus can't sim that chip but a 16f1825 is ok

    done like this the "remainder" is time between pulses in uS provided overflow is < 2







    Code:
    '****************************************************************
    '*  Name    : 324_CCP1_Test.pbp                                 *
    '*  Date    : 09/30/20                                          *  
    '*  Notes   : TEST  using    16F1825                            *
    '****************************************************************
    '*THIS REV:  timing perfect
    #CONFIG
      __config  _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
      __config  _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_19 & _LVP_OFF
    #ENDCONFIG
    
    INCLUDE "DT_INTS-14.bas"  ; 
    INCLUDE "ReEnterPBP.bas"    ; Include for DT_INTS.  ver 3.4
    
    DEFINE OSC 8
    PulseIn     var PORTC.5  ' Monitor ECM tachometer signal 
    PulseFlag   var byte       ' register if CAPTURE Int was entered
    Overflows   VAR word    ' count the times TMR1 overflows
    Remainder   VAR word    ' remaining TMR1 ticks after last overflow
    lastcount   VAR word
    ANSELA = 0                  ' Set all digital 
    ANSELC = 0
    CCP1CON = %00000101     ' On, Capture every + edge
    
    'CCPTMRS = %01010101     ' ALL CCPS using TMR1 (already default)
    'INTCON = %11000001
    
    OSCCON=$70
    
    
    T1CON  = %00010001       ' 1:1 prescale, clock=Fosc/4, TMR1=on 
    T2CON  = %00000100       ' 1:1 PRE and POST, ON 
    '********* USART  ****************************************************
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_SPBRG 51  ' 9600 Baud @ 8MHz, 0.16%
    SPBRGH = 0
    BAUDCON.3 = 1         ' Enable 16 bit baudrate generator
    
    HSEROUT ["324_CCP1_test",10,13]
    pause 2000
    ;----[Interrupts]----------------------------------------
    ASM
    INT_LIST  macro    ; IntSource,   Label,   Type, ResetFlag?
            INT_Handler   CCP1_INT, _Capture,   PBP,  yes        ; WORKS
            INT_Handler   TMR1_INT,  _Timer1,    PBP,  yes
        endm
        INT_CREATE               ; Creates the High Priority interrupt processor
    ENDASM
    @    INT_ENABLE  CCP1_INT    ; enable Capture interrupts
    @    INT_ENABLE  TMR1_INT    ; enable Timer 1 interrupts
    
    
    Main:
      IF PulseFlag = 1 THEN
    '     PULSOUT tachdrv, 50      ' 
         HSEROUT ["OF= ",DEC Overflows,"  ,Ticks= ",DEC Remainder, 13,10]
         PulseFlag = 0
         Overflows = 0
         PIR1.0 = 0               ' clear TMR1IF
      ELSE 
        HSEROUT ["NoFlag", 13,10]  
      ENDIF 
    GOTO Main
    '---[CCP1 - interrupt handler]------------------------------------------
    Capture:  ' Enter here with input Pulse  (CCP1) 
        Remainder= TMR1  - lastcount
        lastcount = TMR1
        PulseFlag = 1           ' set flag to pulse out @ each +capture
    @ INT_RETURN
    ''**** TMR *********
    Timer1:
        Overflows = Overflows + 1
    @ INT_RETURN    
    END
    Last edited by richard; - 1st October 2020 at 11:47.
    This is more entertaining than Free to Air TV

  4. #4
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    227

    Default Re: CCP and timers to capture frequency

    Richard,

    I had to change CCP1CON = %00000101 to CCP1CON = %10000101 to turn on the CCP, but it looks like it works a lot better than what I was trying.
    I'll play with it a bit and see.

    Sorry to keep asking questions, I feel like a dolt sometimes... :-)

    Thanks
    bo

Similar Threads

  1. Question regarding CCP
    By spcw1234 in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 8th April 2013, 09:55
  2. Replies: 1
    Last Post: - 9th March 2013, 07:10
  3. Capture without CCP
    By boroko in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 28th March 2009, 23:09
  4. use of ccp mode
    By boboco in forum General
    Replies: 10
    Last Post: - 6th April 2006, 13:58
  5. CCP question
    By jamie_s in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 5th December 2005, 17:08

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts