CCP Module How to ?


Closed Thread
Results 1 to 6 of 6

Hybrid View

  1. #1
    capitano's Avatar
    capitano Guest

    Post CCP Module How to ?

    I have a problem with CCP module, i must to measure a period from 1ms to 5 ms.
    This is my program using CCP interrupt but it don't work fine. Can you help me please
    Thank you in advance.



    DEFINE OSC 20



    T1CON=%00000000
    CCP1CON=%00000000

    Speed var word

    state var bit


    TMR1L=0 ' Reset Timer
    TMR1H=0 ' Remember Timer is OFF
    pir1.2=0 ' Reset Capture Flag
    pir1.0=0
    CCP1CON = %00000101





    ' Interrupt


    INTCON = %11000000 'Global interrup enable -
    PIE1=%00101111
    ON INTERRUPT GoTo interr



    mainloop:

    GoTo mainloop




    'Gestione di Interrupt

    Disable

    interr:





    '************************************
    'Interrupt Speed

    If pir1.2=1 then

    If state=0 then

    T1CON.0=1 ' Enable Timer
    pir1.2=0 ' Reset Capture Flag
    state =1


    else

    Speed.lowbyte = CCPR1L
    Speed.highbyte = CCPR1H
    ' Store the captured value in period variable
    T1CON.0=0 ' Timer is OFF
    CCP1CON=0 ' Capture is OFF
    TMR1L=0 ' Reset Timer
    TMR1H=0 ' Remember Timer is OFF
    pir1.2=0 ' Reset Capture Flag
    CCP1CON = %00000100
    state=0

    endif





    endif


    Resume
    Enable

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    I've never give a try with CCP module but...

    Are you going to measure external pulses ??!?!?

    Have a look to T1CON.1=1 for external clock
    Case T1CON.1=0 internal clock (fosc/4)=5MHZ

    In this case timer will overflow (1/5MHZ)*65536=13.1 msec
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

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


    Did you find this post helpful? Yes | No

    Default

    Hi capitano,

    Could be a simple problem.

    You're starting off with the Capture triggering on the rising edge, and State = 0
    CCP1CON = %00000101

    On the first interrupt, it starts the timer and changes the State to 1. But I think at this point you also need to change the capture mode to trigger on the Falling edge.
    CCP1CON = %00000100

    On the next time through the interrupt, take the reading, clear the timer and State, then set it to trigger on the Rising edge again.

    This would measure a HIGH pulse. To measure the LOW pulse just reverse the Rising/Falling edges.

    Something like this:
    Code:
    interr:
    '************************************
    'Interrupt Speed
    
        If pir1.2=1 then
            If state=0 then
                T1CON.0=1 ' Enable Timer 
                CCP1CON = %00000100   ' Next trigger is Falling edge
                pir1.2=0  ' Reset Capture Flag 
                state =1
            else
                Speed.lowbyte = CCPR1L 
                Speed.highbyte = CCPR1H 
                ' Store the captured value in period variable 
                T1CON.0=0 ' Timer is OFF 
                CCP1CON=0 ' Capture is OFF 
                TMR1L=0   ' Reset Timer 
                TMR1H=0   ' Remember Timer is OFF 
                pir1.2=0  ' Reset Capture Flag 
                CCP1CON = %00000101   ' Next trigger is Rising edge
                state=0
            endif
        endif
    Resume
    HTH,
       Darrel

  4. #4
    atomski's Avatar
    atomski Guest


    Did you find this post helpful? Yes | No

    Default

    Darrel, guys,

    Could you take a look at this thread:

    http://www.picbasic.co.uk/forum/show...hlight=CAPTURE

    and tell me if using the CCP module as you have described
    above could cure some of my headaches Thanks!

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


    Did you find this post helpful? Yes | No

    Default

    atomski,

    The example given above uses PBP's ON INTERRUPT GOTO type of interrupts. Since the exact time that the interrupt is serviced is not known, it's not a good choice for timing both high and low pulses consecutively.

    However, it can be done relatively easily with ASM using 1 of 2 possible methods.

    1. CCP module in CAPTURE mode using Timer1 and CCPIF interrupt.

    2. INT external interrupt using Timer1.

    The first thing to point out here is that both methods use Timer1. So, the question is, Which one do you want to use. Do you use the INT pin and save the CCP module for something else? Or, use the CCP module and save the RB0 (INT) pin?

    The second thing to mention is that these interrupts will interfere with any "Software Timed commands" like SEROUT, PULSOUT/IN, and most importantly FREQOUT. I say that because you had mentioned in the other thread that the chip would also be using FREQOUT. The degree to which it affects those commands is dependant on the time it takes to process the interrupt. Trying to capture and decode your pulse stream in real time might take enough time to make the problem noticable. But that's just a guess at this point.

    The idea is pretty much the same for both techniques.

    On each interrupt, immediately save the values in TMR1H:TMR1L, and then reset TMR1. Now at this point, simply change the "Edge" that causes an interrupt. For INT it's OPTION.6 (16F628). The first time through will give a Bad value. Then on the next interrupt is does the same thing, but this time the value will correspond to the last pulse width. Since you are just looking for the widths of either high or low pulses, theres no need to keep track of which one it actually was.

    Actually decoding the stream will only take a few subtractions to determine if it's a START, 0 or 1. Shift the results through a register and you should have it. Also, if Timer1 overflows. it's either in-between bytes, or an error. It should scrap any bits that have already come in and wait for the next Start bit.

    The only diference when using the CCP module is that you'll get the value from CCPR1H:CCPR1L instead of TMR1H:TMR1L. And, the "Edge" selection for the CCP module is CCP1CON = %101 (rising) and CCP1CON = %100 for falling edge.

    -------------

    It may or may not be apparent from that, but when measuring both high and low pulses consecutively, the CCP module doesn't really do anything for you. With only one exeption, it frees up RB0. Well, OK it does do one other thing. It introduces a small error, equal to the time it takes to enter the interrupt and reset the timer.

    If you don't need RB0, I would suggest using option 2.

    HTH,
       Darrel
    Last edited by Darrel Taylor; - 8th February 2005 at 07:59.
    DT

  6. #6
    atomski's Avatar
    atomski Guest


    Did you find this post helpful? Yes | No

    Default

    Ok Darrel,

    Thanks for the clarification. I thought pretty much along the
    same tracks, however to be honest I wasn't sure 100%. I'll
    post my code later on today, so you'll be able to see what's
    bothering me for the past several weeks. Bare in mind that
    I'm not an expert in PBP, but I manage.

    TTYL

Similar Threads

  1. Version Control
    By btaylor in forum mel PIC BASIC Pro
    Replies: 33
    Last Post: - 16th October 2011, 17:12
  2. Replies: 1
    Last Post: - 27th July 2008, 06:14
  3. Vinculum VNC1L Vdrive2 module problems
    By the_virus in forum Serial
    Replies: 9
    Last Post: - 21st July 2008, 07:01
  4. CCp module question.
    By robert0 in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 3rd January 2007, 00:28
  5. Rf module
    By tangray in forum Adverts
    Replies: 0
    Last Post: - 7th August 2006, 07:14

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

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