PIC18F24k22 does not capture input...

Discussion in 'Embedded Systems and Microcontrollers' started by dtvonly, Apr 8, 2013.

  1. dtvonly

    Thread Starter Member

    Dec 14, 2012
    43
    0
    Hi. I am trying to use the PIC18F24K22 to capture an input square wave by capturing its every rising edge. CCP2 (RB3) is configured to work with TImer1. The input is a 1MHz square wave. The Timer1 is set to work as Fosc/4 where Fosc is 16MHz. Even with Fosc/4=4MHz this should have been fast enough to capture the input period. I had even tried lowering the input square wave frequency to 100KHz. The same problem: The microcontroller is not capturing anything. What's wrong? Please see attached C file. thank you.
     
  2. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    I don't see where you cleared CCP2MX, so that CCP2 will be on RB3. By default in CONFIG3, CCP2 is on RC1.


    Try clearing the bit in the configuration word 3..
     
  3. dtvonly

    Thread Starter Member

    Dec 14, 2012
    43
    0
    Hi Tshuck. Thanks for the advise. I did forget to config RB3 for CCP2. Ok. With that the MCU now sees the input. However, the captured period is sstill) all wrong. Below is a small portion of the code:

    Code ( (Unknown Language)):
    1.  
    2. T1CONbits.TMR1ON = 1;
    3.  TMR1H = 0;
    4.  TMR1L = 0;
    5.   if(PIR2bits.CCP2IF)             // make sure CP2IF flag is reset first.
    6.    PIR2bits.CCP2IF = 0;
    7.   while(!PIR2bits.CCP2IF);       //  Wait for first rising edge detect.
    8.   First_edge = (TMR1H * 0x100) | TMR1L;
    9.   PIR2bits.CCP2IF = 0;
    10.   while(!PIR2bits.CCP2IF);       //  Wait for second edge detect.
    11.   Second_edge = (TMR1H * 0x100) | TMR1L;
    12.   PIR2bits.CCP2IF = 0;
    13.   Nop();
    14.   TMR1L = 0;
    15.   TMR1H = 0;
    16.   Period = Second_edge-First_edge;
    17.  
    Per datasheet, with each capture, CC2IF = 1 which will transfer TMR1H:TMR1L to CCPR2H:CCPR2L, respectively. Upon receiving a capture, I would transfer CCP2RH:CCP2FL to an int var for temp holding. This value has always been wrong. As such, I have tried to replace CCP2RH:CCP2RL with TMR1H:TMR1L, respectively. That is what in the code above. Still getting the wrong value. Please note I have reset TMR1H:TMR1L registers to ensure proper updating. Please advise. Thank you.
     
  4. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    I think you might benefit from the use of interrupts, but that's another topic for another day...

    Hopefully, your compiler knows to make your x * 0x100 into << 4, but that's a speed issue...

    Now, your period isn't the difference between the two values, this is the number of click pulses the timer sees in the given period. in order to get the period of the waveform, you'd have to divide by the click, in this case, it is Period= measured_difference/(Fosc/4), since your timer is running off of Fosc/4...
     
  5. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    Sorry, I'm on my phone and it likes the word click as opposed to clock, we fight about it constantly, but it wins sometimes... so, click = clock for my previous post. Editing the post on my phone causes all the HTML tags to show up and it's a pain to deal with...
     
  6. dtvonly

    Thread Starter Member

    Dec 14, 2012
    43
    0
    Hi tsuck. I recompiled then ran the program again. This time I replaced the TMR1H:TMR1L with CCPR2H:CCPR2L and everthing worked. One slight problem, however. My current settings are:
    - TIMER1 on Fosc=16MHz (NOT Fosc/4)

    My main objective is to be able to measure up to 1MHz input square wave. So far my maximum capture is only about 220KHz.

    According to PIC18F24k22 spec, I am allowed to measure up to:
    CCP2 period = [(3*Tcy) + 40]/N where N = 1 is the CCP2 prescaler.
    (PIC18f24k22 datasheet page 455).

    With these settings and technical spec, I should (ideally) be able to measure up to 24MHz.

    What am I missing?
     
  7. dtvonly

    Thread Starter Member

    Dec 14, 2012
    43
    0
    Hi tshuck. The code "snipplet" is just that. You are right about the period calculation. the final period would be the difference/Fosc or Fosc/4. This is not the issue. The issue is still the difference between the "edge counts". Once I increase my input frequency above 220kHz, the edge difference would be incorrect. By the way, I am now using Fosc=16MHz instead of Fosc/4.

    testing 220kHz: edge difference = 72, period = 1/[72*(1/16MHz)] = 222kHz (correct)
    testing 172Khz: edge difference = 88, period = 1/[88*(1/16MHz)] = 173kHz (correct)
    testing 1MHz: edge difference = 136, period = 1/[136*(1/16MHz)] = 117kHz (wrong). edge difference should be about 16 for 1MHz.

    Please advise. Thank you.
     
  8. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    As far as the formula on page 455, Tcy is given in units of ns, so your calculation should be:
    Tccp = (3(4/16)e3 + 40)/N = 790/N =~1.2MHz with N = 1

    Now, you can't measure a frequency above the frequency at which your counter counts, right? That should have tipped you off that you had the wrong values.


    Read the note on the bottom of page 180, it says you can't run the capture off of Fosc, you must use a scale factor.
     
    Last edited: Apr 8, 2013
  9. dtvonly

    Thread Starter Member

    Dec 14, 2012
    43
    0
    Hi tshuck. You are correct.

    Given: Fosc = 16MHz, Fcy=16MHz/4 => Tcy=1/4MHz = 250mS; N=1

    The maximum is about 1.2MHz. Should I still be able to get to 1MHz with .2MHz to spare?
     
  10. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    Not while you are using a 16MHz Fosc, since you cannot run the capture module at Fosc, see my previous post.

    You can, however, run the on-board PLL to get up to 64MHz Fosc, greatly increasing your ability to measure a higher frequency signal.
     
  11. dtvonly

    Thread Starter Member

    Dec 14, 2012
    43
    0
    I think I got it now. The name "Fosc" is a bit confusing. So according to the datasheet page 180, don't use INTOSC directly, but the implication is to use INTOSC + PLL? I will try this. Thank you.
     
  12. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    Fosc is the frequency of the system oscillator. with a PIC, the instruction frequency is Fosc/4.

    Do, when you are running your uC at 16MHz, Fosc =16MHz, and your instructions(atomic) occur every (Fosc/4)^-1 seconds.

    What page 180 means is that you need a prescale when using the capture mode.
     
Loading...